diff --git a/homework-g599-derut/.project b/homework-g599-derut/.project
new file mode 100644
index 000000000..83f571a37
--- /dev/null
+++ b/homework-g599-derut/.project
@@ -0,0 +1,23 @@
+
+
+ homework-g599-derut
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/homework-g599-derut/pom.xml b/homework-g599-derut/pom.xml
new file mode 100644
index 000000000..9a26fe82e
--- /dev/null
+++ b/homework-g599-derut/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+ mipt-java-2016
+ ru.mipt.java2016
+ 1.0.0
+
+ 4.0.0
+
+ homework-g599-derut
+
+
+ ru.mipt.java2016
+ homework-base
+ 1.0.0
+
+
+ ru.mipt.java2016
+ homework-tests
+ 1.0.0
+ test
+
+
+
+
\ No newline at end of file
diff --git a/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/DoubleRead.java b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/DoubleRead.java
new file mode 100644
index 000000000..99a1e9ba2
--- /dev/null
+++ b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/DoubleRead.java
@@ -0,0 +1,18 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class DoubleRead implements Serializer {
+
+ @Override
+ public void write(RandomAccessFile f, Double val) throws IOException {
+ f.writeDouble(val);
+ }
+
+ @Override
+ public Double read(RandomAccessFile f) throws IOException {
+ return f.readDouble();
+ }
+
+}
diff --git a/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/IntegerRead.java b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/IntegerRead.java
new file mode 100644
index 000000000..ed89a155d
--- /dev/null
+++ b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/IntegerRead.java
@@ -0,0 +1,18 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class IntegerRead implements Serializer {
+
+ @Override
+ public void write(RandomAccessFile f, Integer val) throws IOException {
+ f.writeInt(val);
+ }
+
+ @Override
+ public Integer read(RandomAccessFile f) throws IOException {
+ return f.readInt();
+ }
+
+}
diff --git a/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/MyKVStorage.java b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/MyKVStorage.java
new file mode 100644
index 000000000..fe7176cbd
--- /dev/null
+++ b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/MyKVStorage.java
@@ -0,0 +1,110 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import ru.mipt.java2016.homework.base.task2.KeyValueStorage;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+class MyKVStorage implements KeyValueStorage {
+ private final RandomAccessFile dataBase;
+ private final Map data = new HashMap<>();
+ private final Serializer keyS;
+ private final Serializer valS;
+ private boolean isClosed = true;
+ private int length = 0;
+
+ MyKVStorage(String path, Serializer keyS, Serializer valS) throws IOException {
+ this.keyS = keyS;
+ this.valS = valS;
+ Path directPath = Paths.get(path, "dataBase.db");
+ dataBase = new RandomAccessFile(directPath.toFile(), "rw");
+ isClosed = false;
+ if (dataBase.length() != 0) {
+ initialRead();
+ }
+ }
+
+ private void initialRead() throws IOException {
+ length = dataBase.readInt();
+ for (int i = 0; i < length; ++i) {
+ K key = keyS.read(dataBase);
+ V val = valS.read(dataBase);
+ data.put(key, val);
+ }
+ }
+
+ @Override
+ public synchronized V read(K key) {
+ checker();
+ return data.get(key);
+ }
+
+ @Override
+ public synchronized boolean exists(K key) {
+ checker();
+ return data.containsKey(key);
+
+ }
+
+ @Override
+ public synchronized void write(K key, V value) {
+ checker();
+ if (!exists(key)) {
+ ++length;
+ }
+ data.put(key, value);
+
+ }
+
+ @Override
+ public synchronized void delete(K key) {
+ checker();
+ if (exists(key)) {
+ data.remove(key);
+ --length;
+ }
+ }
+
+ @Override
+ public Iterator readKeys() {
+ checker();
+ return data.keySet().iterator();
+ }
+
+ @Override
+ public synchronized int size() {
+ checker();
+ return length;
+ }
+
+ @Override
+ public synchronized void close() throws IOException {
+ if (!isClosed) {
+ render();
+ }
+
+ }
+
+ public void render() throws IOException {
+ dataBase.seek(0);
+ dataBase.setLength(0);
+ IntegerRead intR = new IntegerRead();
+ intR.write(dataBase, length);
+ for (Map.Entry entry : data.entrySet()) {
+ keyS.write(dataBase, entry.getKey());
+ valS.write(dataBase, entry.getValue());
+ }
+ dataBase.close();
+ isClosed = true;
+ }
+
+ private void checker() {
+ if (isClosed) {
+ throw new RuntimeException("Closed!!!");
+ }
+ }
+}
diff --git a/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/Serializer.java b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/Serializer.java
new file mode 100644
index 000000000..f5b5c70fa
--- /dev/null
+++ b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/Serializer.java
@@ -0,0 +1,12 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public interface Serializer {
+
+ void write(RandomAccessFile f, T val) throws IOException;
+
+ T read(RandomAccessFile f) throws IOException;
+
+}
diff --git a/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/StringReader.java b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/StringReader.java
new file mode 100644
index 000000000..be9ab845b
--- /dev/null
+++ b/homework-g599-derut/src/main/java/ru/mipt/java2016/homework/g599/derut/task2/StringReader.java
@@ -0,0 +1,29 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class StringReader implements Serializer {
+
+ @Override
+ public void write(RandomAccessFile f, String val) throws IOException {
+ int length = val.length();
+ char[] c = val.toCharArray();
+ f.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ f.writeChar(c[i]);
+ }
+
+ }
+
+ @Override
+ public String read(RandomAccessFile f) throws IOException {
+ int length = f.readInt();
+ char[] c = new char[length];
+ for (int i = 0; i < length; i++) {
+ c[i] = f.readChar();
+ }
+ return new String(c);
+ }
+
+}
diff --git a/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/DataBaseTest.java b/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/DataBaseTest.java
new file mode 100644
index 000000000..67ae33812
--- /dev/null
+++ b/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/DataBaseTest.java
@@ -0,0 +1,38 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import ru.mipt.java2016.homework.base.task2.KeyValueStorage;
+import ru.mipt.java2016.homework.tests.task2.AbstractSingleFileStorageTest;
+import ru.mipt.java2016.homework.tests.task2.Student;
+import ru.mipt.java2016.homework.tests.task2.StudentKey;
+
+import java.io.IOException;
+
+public class DataBaseTest extends AbstractSingleFileStorageTest {
+ @Override
+ protected KeyValueStorage buildStringsStorage(String path) {
+ try {
+ return new MyKVStorage(path, new StringReader(), new StringReader());
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected KeyValueStorage buildNumbersStorage(String path) {
+ try {
+
+ return new MyKVStorage(path, new IntegerRead(), new DoubleRead());
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected KeyValueStorage buildPojoStorage(String path) {
+ try {
+ return new MyKVStorage(path, new StudentKReader(), new StudentReader());
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/StudentKReader.java b/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/StudentKReader.java
new file mode 100644
index 000000000..5c79e16cd
--- /dev/null
+++ b/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/StudentKReader.java
@@ -0,0 +1,25 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import ru.mipt.java2016.homework.tests.task2.StudentKey;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class StudentKReader implements Serializer {
+ @Override
+ public void write(RandomAccessFile f, StudentKey val) throws IOException {
+ IntegerRead intS = new IntegerRead();
+ StringReader stringS = new StringReader();
+ intS.write(f, val.getGroupId());
+ stringS.write(f, val.getName());
+
+ }
+
+ @Override
+ public StudentKey read(RandomAccessFile f) throws IOException {
+ IntegerRead intS = new IntegerRead();
+ StringReader stringS = new StringReader();
+ return new StudentKey(intS.read(f), stringS.read(f));
+ }
+
+}
diff --git a/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/StudentReader.java b/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/StudentReader.java
new file mode 100644
index 000000000..7b903e13c
--- /dev/null
+++ b/homework-g599-derut/src/test/java/ru/mipt/java2016/homework/g599/derut/task2/StudentReader.java
@@ -0,0 +1,49 @@
+package ru.mipt.java2016.homework.g599.derut.task2;
+
+import ru.mipt.java2016.homework.tests.task2.Student;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Date;
+
+public class StudentReader implements Serializer {
+ @Override
+ public void write(RandomAccessFile f, Student val) throws IOException {
+ IntegerRead intS = new IntegerRead();
+ StringReader stringS = new StringReader();
+ DoubleRead dS = new DoubleRead();
+
+ intS.write(f, val.getGroupId());
+ stringS.write(f, val.getName());
+ stringS.write(f, val.getHometown());
+ f.writeLong(val.getBirthDate().getTime());
+ boolean f1 = val.isHasDormitory();
+ if (f1)
+ intS.write(f, 1);
+ else
+ intS.write(f, 0);
+ dS.write(f, val.getAverageScore());
+
+ }
+
+ @Override
+ public Student read(RandomAccessFile f) throws IOException {
+ IntegerRead intS = new IntegerRead();
+ StringReader stringS = new StringReader();
+ DoubleRead dS = new DoubleRead();
+ int gID = intS.read(f);
+ String name = stringS.read(f);
+ String hmt = stringS.read(f);
+ long time = f.readLong();
+ Date d = new Date(time);
+ int f1 = intS.read(f);
+ boolean f2;
+ if (f1 == 0)
+ f2 = false;
+ else
+ f2 = true;
+ double as = dS.read(f);
+ return new Student(gID, name, hmt, d, f2, as);
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index b507bc7ef..9ccb96bbd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,6 +88,7 @@
homework-g596-grebenshchikova
homework-g597-kochukov
homework-g597-sigareva
+ homework-g599-derut
workshop-materials