Skip to content
This repository was archived by the owner on Sep 27, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/ru/fizteh/fivt/students/elina_denisova/j_unit/Commands.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ru.fizteh.fivt.students.elina_denisova.j_unit;

public enum Commands {

CREATECOMMAND("create"),
COMMITCOMMAND("commit"),
ROLLBACKCOMMAND("rollback"),
DROPCOMMAND("drop"),
USECOMMAND("use"),
SHOWCOMMAND("show"),
PUTCOMMAND("put"),
GETCOMMAND("get"),
REMOVECOMMAND("remove"),
LISTCOMMAND("list"),
EXITCOMMAND("exit");


private String value;
private Commands(String word) {
value = word;
}

public static Commands getCommand(String word) throws IllegalArgumentException {
for (Commands command : Commands.values()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Положите все команды в Map и доставайте команды из него, а не так

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется, я залила старый вариант -_-

if (command.getValue().equals(word)) {
return command;
}
}
throw new IllegalArgumentException(word + " - unknown command");
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.fizteh.fivt.students.elina_denisova.j_unit;

public class HandlerException {
public static void handler(String message, Throwable cause) {
System.err.println(message + cause.getMessage());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

нужно поставить "." между сообщениями

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Исправлено.

System.exit(1);
}
public static void handler(Throwable cause) {
System.err.println(cause.getMessage());
System.exit(1);
}

}


Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.fizteh.fivt.students.elina_denisova.j_unit;

import java.util.Scanner;

public class InteractiveParse {
public static void parse(MyTableProvider directory) {
Scanner in = new Scanner(System.in);
try {
while (true) {
System.out.print("$ ");
String s;
s = in.nextLine();
s = s.trim();
String[] current = s.split("\\s+");
for (int i = 0; i < current.length; ++i) {
current[i].trim();
}
ParserCommands.commandsExecution(current, directory);
}
} catch (IllegalMonitorStateException e) {
in.close();
System.out.println("Goodbye");
System.exit(0);
} catch (Exception e) {
in.close();
HandlerException.handler("InteractiveParse: Unknown error", e);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так как ты печатаешь свое сообщение, а за ним сообщение exeption, то не стоит добавлять "Unknown error"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Исправлено.

}
in.close();
}
}
310 changes: 310 additions & 0 deletions src/ru/fizteh/fivt/students/elina_denisova/j_unit/MyTable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
package ru.fizteh.fivt.students.elina_denisova.j_unit;

import ru.fizteh.fivt.storage.strings.Table;

import java.io.*;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyTable implements Table {

private Path mainDir;
private Map<String, Map<String, String>> databases;
private static Map<Integer, ArrayList<String>> changes = new HashMap<>();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это не ООП. Если вы хотите хранить список изменений, то заведите базовый класс Change, заведите наследников PutChange/RemoveChange, и храните в этой мапе ArrayList<Change>. Тогда будет ООП.

private int numberChanges = 0;

public MyTable(File tableDir) {
try {
databases = new HashMap<>();
mainDir = tableDir.toPath();

for (int i = 0; i < 16; i++) {
File subDir = new File(tableDir, i + ".dir");
for (int j = 0; j < 16; j++) {
File dbFile = new File(subDir, j + ".dat");
if (dbFile.exists()) {
String adds = Integer.toString(i * 100 + j);
databases.put(adds, new HashMap<String, String>());
readFromFile(dbFile, databases.get(adds));
}
}
}
} catch (Exception e) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Уточнить исключение. Какое именно исключение вы здесь ловите? Почему оно может кинуться?

HandlerException.handler("TableProvider: Unknown error", e);
}
}

public boolean containsKey(String adds) {
return databases.containsKey(adds);
}

@Override
public String getName() {
return mainDir.toString();
};

@Override
public String get(String key) throws IllegalArgumentException {
if (key != null) {
int hashCode = Math.abs(key.hashCode());
int dir = hashCode % 16;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

16 нужно вынести в константы

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Исправлено

int file = hashCode / 16 % 16;
String adds = Integer.toString(dir * 100 + file);
return databases.get(adds).get(key);
} else {
throw new IllegalArgumentException("Table.get: Haven't key. ");
}
}

@Override
public String put(String key, String value) {
if ((key != null) || (value != null)) {
try {
int hashCode = Math.abs(key.hashCode());
int dir = hashCode % 16;
int file = hashCode / 16 % 16;
String adds = Integer.toString(dir * 100 + file);
if (!databases.containsKey(adds)) {
File subDir = new File(mainDir.toString(), dir + ".dir");
if (!subDir.exists()) {
if (!subDir.mkdir()) {
throw new UnsupportedOperationException("ParserCommands.commandsExecution.put:"
+ " Unable to create directories in working catalog");
}
}
File dbFile = new File(subDir, file + ".dat");
if (!dbFile.exists()) {
if (!dbFile.createNewFile()) {
throw new UnsupportedOperationException("ParserCommands.commandsExecution.put:"
+ " Unable to create database files in working catalog");
}
}
databases.put(adds, new HashMap<String, String>());
}

String oldValue = databases.get(adds).get(key);
databases.get(adds).put(key, value);
numberChanges++;
changes.put(numberChanges, new ArrayList<String>());
changes.get(numberChanges).add("put");
changes.get(numberChanges).add(key);
changes.get(numberChanges).add(value);
if (oldValue == null) {
changes.get(numberChanges).add("new");
} else {
changes.get(numberChanges).add(oldValue);
}
return oldValue;


} catch (IOException e) {
throw new NullPointerException("MyTable.put: Cannot create new file. ");
}
} else {
throw new IllegalArgumentException("MyTable.put: Haven't key or value. ");
}
}

@Override
public String remove(String key) {
if (key != null) {
int hashCode = Math.abs(key.hashCode());
int dir = hashCode % 16;
int file = hashCode / 16 % 16;
String adds = Integer.toString(dir * 100 + file);
if (!databases.containsKey(adds)) {
return null;
} else {
String oldValue = databases.get(adds).get(key);
databases.get(adds).remove(key);
numberChanges++;
changes.put(numberChanges, new ArrayList<String>());
changes.get(numberChanges).add("remove");
changes.get(numberChanges).add(key);
changes.get(numberChanges).add(oldValue);
return oldValue;
}
} else {
throw new IllegalArgumentException("Table.get: Haven't key. ");
}
}

@Override
public int size() {
int answer = 0;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
String adds = Integer.toString(i * 100 + j);
if (databases.containsKey(adds)) {
answer += databases.get(adds).size();
}
}
}
return answer;
}

@Override
public int commit() {
numberChanges = 0;
changes = new HashMap<>();

int count = 0;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
String adds = Integer.toString(i * 100 + j);
if (databases.containsKey(adds)) {
File directory = new File(mainDir.toString(), i + ".dir");
File dataBaseOld = new File(directory, j + ".dat");
try {
Files.delete(dataBaseOld.toPath());
} catch (IOException e) {
throw new RuntimeException("MyTable.writeInFile: Can't overwrite file");
}
File dataBase = new File(directory, j + ".dat");
try (RandomAccessFile dbFile = new RandomAccessFile(dataBase, "rw")) {
for (Map.Entry<String, String> current : databases.get(adds).entrySet()) {
count++;
writeNext(dbFile, current.getKey());
writeNext(dbFile, current.getValue());
}
} catch (FileNotFoundException e) {
throw new RuntimeException("MyTable.writeInFile: File not found");
} catch (IOException e) {
throw new RuntimeException("MyTable.writeInFile: Can't write to file.", e);
}

if (databases.get(adds).size() == 0) {
File subDir = new File(mainDir.toString(), i + ".dir");
File dbFile = new File(subDir, j + ".dat");
try {
if (dbFile.exists()) {
Files.delete(dbFile.toPath());
}
} catch (IOException e) {
throw new IllegalStateException("MyTable.remove: "
+ "Cannot delete database file. ", e);
}
databases.remove(adds);

int k = 0;
for (int file = 0; file < 16; file++) {
String variableAdds = Integer.toString(i * 100 + file);
if (databases.containsKey(variableAdds)) {
k++;
}
}
if (k == 16) {
try {
Files.delete(subDir.toPath());
} catch (DirectoryNotEmptyException e) {
throw new IllegalStateException("MyTable.remove: Cannot remove table subdirectory. "
+ "Redundant files", e);
} catch (IOException e) {
throw new IllegalStateException("MyTable.remove: "
+ "Cannot delete database subdirectory", e);
}
}
}
}
}
}
return count;

}

private void writeNext(RandomAccessFile dbFile, String word) throws IOException {
try {
dbFile.writeInt(word.getBytes("UTF-8").length);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вынести кодировку в константы

dbFile.write(word.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Table.writeNext: Don't supported encoding UTF-8. ");
} catch (IOException e) {
throw new RuntimeException("Table.writeNext: Can't write to database. ", e);
}
}
public void readFromFile(File dbFileName, Map<String, String> data) throws IllegalArgumentException {
try (RandomAccessFile file = new RandomAccessFile(dbFileName.toString(), "r")) {

if (file.length() > 0) {
while (file.getFilePointer() < file.length()) {
String key = readNext(file);
String value = readNext(file);
if (data.containsKey(key)) {
throw new IllegalArgumentException("Table.readFromFile: Two same keys in database file");
}
data.put(key, value);
}
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
throw new RuntimeException("Table.readFromFile: File not found", e);
} catch (IOException e) {
throw new RuntimeException(" Table.readFromFile: Problems with reading from database file " + e.toString());
} catch (Exception e) {
throw new RuntimeException("Table.readFromFile: Unknown error", e);
}
}


private String readNext(RandomAccessFile dbFile) throws IOException {
try {
int wordLength = dbFile.readInt();
byte[] word = new byte[wordLength];
dbFile.read(word, 0, wordLength);
return new String(word, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new UnsupportedEncodingException("Table.readNext: UTF-8 encoding is not supported");
} catch (IOException e) {
throw new IOException(" Table.readNext: Can't read from database " + e.toString());
}
}


@Override
public int rollback() {
int count = 0;
Map<Integer, ArrayList<String>> saveChanges = changes;
for (int i = saveChanges.size(); i > 0; i--) {
String[] com = new String[saveChanges.get(i).size()];
com = saveChanges.get(i).toArray(com);
String message;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

кажется, что эта строка не нужна

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужна, иначе всё полетит при возвращении null

if (com[0].equals("put")) {
if (com[3].equals("new")) {
message = remove(com[1]);
} else {
message = put(com[1], com[3]);
}
}
if (com[0].equals("remove")) {
put(com[1], com[2]);
}
count++;
}
numberChanges = 0;
changes = new HashMap<>();
return count;
}

@Override
public List<String> list() {
List<String> listKey = new ArrayList<>();
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
String adds = Integer.toString(i * 100 + j);
if (databases.containsKey(adds)) {
for (String key : databases.get(adds).keySet()) {
listKey.add(key);
}
}
}
} return listKey;
}
}
Loading