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 6 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
36 changes: 36 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,36 @@
package ru.fizteh.fivt.students.elina_denisova.j_unit;

public enum Commands {

CREATECOMMAND("create"),
SIZECOMMAND("size"),
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());
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: ", e);
}
in.close();
}
}
313 changes: 313 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,313 @@
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 static final int COUNT_OBJECT = 16;
public static final int COMMON_CONSTANT_INDEX = 100;


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

for (int i = 0; i < COUNT_OBJECT; i++) {
File subDir = new File(tableDir, i + ".dir");
for (int j = 0; j < COUNT_OBJECT; j++) {
File dbFile = new File(subDir, j + ".dat");
if (dbFile.exists()) {
String adds = Integer.toString(i * COMMON_CONSTANT_INDEX + 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: ", 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 % COUNT_OBJECT;
int file = hashCode / COUNT_OBJECT % COUNT_OBJECT;
String adds = Integer.toString(dir * COMMON_CONSTANT_INDEX + 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)) {
int hashCode = Math.abs(key.hashCode());
int dir = hashCode % COUNT_OBJECT;
int file = hashCode / COUNT_OBJECT % COUNT_OBJECT;
String adds = Integer.toString(dir * COMMON_CONSTANT_INDEX + file);
if (!databases.containsKey(adds)) {
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;
} 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 % COUNT_OBJECT;
int file = hashCode / COUNT_OBJECT % COUNT_OBJECT;
String adds = Integer.toString(dir * COMMON_CONSTANT_INDEX + file);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Дублирование кода из строк 71-74

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 < COUNT_OBJECT; i++) {
for (int j = 0; j < COUNT_OBJECT; j++) {
String adds = Integer.toString(i * COMMON_CONSTANT_INDEX + j);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Это вычисление дублируется из функции в функцию. Вынести в отдельную функцию.

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 < COUNT_OBJECT; i++) {
for (int j = 0; j < COUNT_OBJECT; j++) {
String adds = Integer.toString(i * COMMON_CONSTANT_INDEX + j);
if (databases.containsKey(adds)) {
File directory = new File(mainDir.toString(), i + ".dir");
if (!directory.exists()) {
if (!directory.mkdir()) {
throw new UnsupportedOperationException("ParserCommands.commandsExecution.put:"
+ " Unable to create directories in working catalog");
}
}
File dataBaseOld = new File(directory, j + ".dat");
if (dataBaseOld.exists()) {
try {
Files.delete(dataBaseOld.toPath());
} catch (IOException e) {
throw new RuntimeException("MyTable.writeInFile: Can't overwrite file");
}
}

if (!dataBaseOld.exists()) {
try {
if (!dataBaseOld.createNewFile()) {
throw new UnsupportedOperationException("ParserCommands.commandsExecution.put:"
+ " Unable to create database files in working catalog");
}
} catch (IOException e) {
throw new UnsupportedOperationException("ParserCommands.commandsExecution.put:"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Дублирование строковой константы из строки 165. Избавиться от него.

+ " Unable to create database files in working catalog");
}
}
try (RandomAccessFile dbFile = new RandomAccessFile(dataBaseOld, "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 < COUNT_OBJECT; file++) {
String variableAdds = Integer.toString(i * COMMON_CONSTANT_INDEX + file);
if (databases.containsKey(variableAdds)) {
k++;
}
}
if (k == COUNT_OBJECT) {
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: ", 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 < COUNT_OBJECT; i++) {
for (int j = 0; j < COUNT_OBJECT; j++) {
String adds = Integer.toString(i * COMMON_CONSTANT_INDEX + j);
if (databases.containsKey(adds)) {
for (String key : databases.get(adds).keySet()) {
listKey.add(key);
}
}
}
} return listKey;
}
}
Loading