From ab41f48889b773d2ef3c5590ea36d00461d56443 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 01:19:28 +0300 Subject: [PATCH 01/13] Task 1 2 --- homework-g595-ferenets/pom.xml | 28 ++++ .../g595/ferenets/task1/MyCalculator.java | 139 ++++++++++++++++++ .../task2/DoubleSerializationStrategy.java | 17 +++ .../task2/IntegerSerializationStrategy.java | 18 +++ .../ferenets/task2/MyKeyValueStorage.java | 104 +++++++++++++ .../ferenets/task2/SerializationStrategy.java | 11 ++ .../task2/StringSerializationStrategy.java | 17 +++ .../StudentKeySerializationStrategy.java | 20 +++ .../task2/StudentSerializationStrategy.java | 26 ++++ .../g595/ferenets/task1/MyCalculatorTest.java | 12 ++ .../ferenets/task2/MyKeyValueStorageTest.java | 41 ++++++ pom.xml | 1 + 12 files changed, 434 insertions(+) create mode 100644 homework-g595-ferenets/pom.xml create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculator.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/DoubleSerializationStrategy.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/IntegerSerializationStrategy.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/SerializationStrategy.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StringSerializationStrategy.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentKeySerializationStrategy.java create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentSerializationStrategy.java create mode 100644 homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculatorTest.java create mode 100644 homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorageTest.java diff --git a/homework-g595-ferenets/pom.xml b/homework-g595-ferenets/pom.xml new file mode 100644 index 000000000..d85798e58 --- /dev/null +++ b/homework-g595-ferenets/pom.xml @@ -0,0 +1,28 @@ + + + + mipt-java-2016 + ru.mipt.java2016 + 1.0.0 + + 4.0.0 + + homework-g595-ferenets + 1.0.0 + + + ru.mipt.java2016 + homework-base + 1.0.0 + + + ru.mipt.java2016 + homework-tests + 1.0.0 + + + + + \ No newline at end of file diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculator.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculator.java new file mode 100644 index 000000000..e5728f30e --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculator.java @@ -0,0 +1,139 @@ +package ru.mipt.java2016.homework.g595.ferenets.task1; + +import ru.mipt.java2016.homework.base.task1.Calculator; +import ru.mipt.java2016.homework.base.task1.ParsingException; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.HashSet; + + +public class MyCalculator implements Calculator { + + private static final HashSet ACCEPTABLE_SYMBOLS = new HashSet<>( + Arrays.asList('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '-', '*', '/', + '(', ')')); + private static final HashSet DIGITS = + new HashSet<>(Arrays.asList('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')); + private static final HashSet OPERATORS = + new HashSet<>(Arrays.asList('+', '-', '*', '/')); + private static final HashSet SPACES = new HashSet<>(Arrays.asList(' ', '\n', '\t')); + + + @Override + public double calculate(String expression) throws ParsingException { + if (expression == null) { + throw new ParsingException("Null Expression"); + } + int bracketsBalance = 0; + String expressionInBrackets = ""; + String expressionOutOfBrackets = ""; + for (char currentCharacter : expression.toCharArray()) { + if (!ACCEPTABLE_SYMBOLS.contains(currentCharacter) && !SPACES + .contains(currentCharacter)) { + throw new ParsingException("Bad expression"); + } else if (currentCharacter == '(') { + bracketsBalance += 1; + } else { + if (currentCharacter == ')') { + bracketsBalance -= 1; + if (bracketsBalance < 0) { + throw new ParsingException("Bad Brackets Balance"); + } + if (bracketsBalance == 0) { + expressionOutOfBrackets += calculate(expressionInBrackets); + expressionInBrackets = ""; + } + } else { + if (bracketsBalance == 0) { + expressionOutOfBrackets += currentCharacter; + } else { + expressionInBrackets += currentCharacter; + } + } + } + } + if (bracketsBalance != 0) { + throw new ParsingException("Bad Brackets Balance"); + } + ArrayDeque numberArrayDeque = new ArrayDeque<>(); + ArrayDeque operatorArrayDeque = new ArrayDeque<>(); + boolean isReadingNumber = false; + boolean isDotInNumber = false; + boolean wasOperator = true; + String number = ""; + expression = expressionOutOfBrackets; + for (char currentCharacter : expression.toCharArray()) { + if (DIGITS.contains(currentCharacter) || currentCharacter == '.') { + wasOperator = false; + if (!isReadingNumber) { + if (currentCharacter == '.') { + throw new ParsingException("Dot is in the beginning of number"); + } else { + number = "" + currentCharacter; + isDotInNumber = false; + isReadingNumber = true; + } + } else { + if (currentCharacter == '.') { + if (isDotInNumber) { + throw new ParsingException("Two Dots In Number"); + } else { + isDotInNumber = true; + } + } + number += currentCharacter; + } + } else if (OPERATORS.contains(currentCharacter)) { + if (wasOperator) { + if (currentCharacter == '-') { + if (number.equals("-")) { + number = ""; + } else { + number = "-"; + } + isReadingNumber = true; + isDotInNumber = false; + } else { + throw new ParsingException("Two Operators Together"); + } + continue; + } + wasOperator = true; + numberArrayDeque.add(Double.valueOf(number)); + isReadingNumber = false; + operatorArrayDeque.add(currentCharacter); + } + } + if (isReadingNumber) { + numberArrayDeque.add(Double.valueOf(number)); + } + if (numberArrayDeque.isEmpty()) { + throw new ParsingException("Too Few Numbers"); + } + ArrayDeque newNumberArrayDeque = new ArrayDeque<>(); + ArrayDeque newOperatorArrayDeque = new ArrayDeque<>(); + while (numberArrayDeque.size() > 1) { + char currentOperator = operatorArrayDeque.pop(); + if (currentOperator == '+' || currentOperator == '-') { + newNumberArrayDeque.add(numberArrayDeque.pop()); + newOperatorArrayDeque.add(currentOperator); + } else if (currentOperator == '*') { + numberArrayDeque.push(numberArrayDeque.pop() * numberArrayDeque.pop()); + } else if (currentOperator == '/') { + numberArrayDeque.push(numberArrayDeque.pop() / numberArrayDeque.pop()); + } + } + newNumberArrayDeque.add(numberArrayDeque.pop()); + Double result = newNumberArrayDeque.pop(); + while (!newNumberArrayDeque.isEmpty()) { + char currentOperator = newOperatorArrayDeque.pop(); + if (currentOperator == '+') { + result += newNumberArrayDeque.pop(); + } else if (currentOperator == '-') { + result -= newNumberArrayDeque.pop(); + } + } + return result; + } +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/DoubleSerializationStrategy.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/DoubleSerializationStrategy.java new file mode 100644 index 000000000..6fbc143f7 --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/DoubleSerializationStrategy.java @@ -0,0 +1,17 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + +import java.io.IOException; +import java.io.RandomAccessFile; + + +public class DoubleSerializationStrategy implements SerializationStrategy { + @Override + public Double read(RandomAccessFile file) throws IOException { + return file.readDouble(); + } + + @Override + public void write(RandomAccessFile file, Double value) throws IOException { + file.writeDouble(value); + } +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/IntegerSerializationStrategy.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/IntegerSerializationStrategy.java new file mode 100644 index 000000000..52e198acd --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/IntegerSerializationStrategy.java @@ -0,0 +1,18 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + +import java.io.IOException; +import java.io.RandomAccessFile; + + +public class IntegerSerializationStrategy implements SerializationStrategy { + + @Override + public Integer read(RandomAccessFile file) throws IOException { + return file.readInt(); + } + + @Override + public void write(RandomAccessFile file, Integer value) throws IOException { + file.writeInt(value); + } +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java new file mode 100644 index 000000000..bbc204346 --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java @@ -0,0 +1,104 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + +import ru.mipt.java2016.homework.base.task2.KeyValueStorage; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.HashMap; +import java.util.Iterator; + +public class MyKeyValueStorage implements KeyValueStorage { + + private HashMap map; + private SerializationStrategy keySerializator; + private SerializationStrategy valueSerializator; + private RandomAccessFile RAFile; + private boolean opened; + + + MyKeyValueStorage(String path, SerializationStrategy _keySerializator, + SerializationStrategy _valueSerializator) throws IOException { + map = new HashMap<>(); + keySerializator = _keySerializator; + valueSerializator = _valueSerializator; + opened = true; + String pathToStorage = path + File.separator + "storage.txt"; + try { + File file = new File(pathToStorage); + if (file.createNewFile()) { + RAFile = new RandomAccessFile(file.getPath(), "rw"); + } else { + RAFile = new RandomAccessFile(file, "rw"); + int elementsCount = RAFile.readInt(); + for (int i = 0; i < elementsCount; ++i) { + K currentKey = this.keySerializator.read(RAFile); + V currentValue = this.valueSerializator.read(RAFile); + map.put(currentKey, currentValue); + } + } + } catch (FileNotFoundException e) { + throw new FileNotFoundException("File is not found"); + } + } + + private void checkFileAccess() { + if (!opened) { + throw new IllegalStateException("The storage is closed"); + } + } + + @Override + public V read(K key) { + checkFileAccess(); + return map.get(key); + } + + @Override + public boolean exists(K key) { + checkFileAccess(); + return map.containsKey(key); + } + + @Override + public void write(K key, V value) { + checkFileAccess(); + map.put(key, value); + } + + @Override + public void delete(K key) { + checkFileAccess(); + map.remove(key); + } + + @Override + public Iterator readKeys() { + checkFileAccess(); + return map.keySet().iterator(); + } + + @Override + public int size() { + checkFileAccess(); + return map.size(); + } + + @Override + public void close() throws IOException { + try { + RAFile.setLength(0); + RAFile.seek(0); + RAFile.writeInt(map.size()); + for (HashMap.Entry entry : map.entrySet()) { + keySerializator.write(RAFile, entry.getKey()); + valueSerializator.write(RAFile, entry.getValue()); + } + opened = false; + RAFile.close(); + } catch (IOException e) { + throw new IOException("Closed."); + } + } +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/SerializationStrategy.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/SerializationStrategy.java new file mode 100644 index 000000000..3d04403e1 --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/SerializationStrategy.java @@ -0,0 +1,11 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + + +import java.io.IOException; +import java.io.RandomAccessFile; + +public interface SerializationStrategy { + T read(RandomAccessFile file) throws IOException; + + void write(RandomAccessFile file, T value) throws IOException; +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StringSerializationStrategy.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StringSerializationStrategy.java new file mode 100644 index 000000000..edb203134 --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StringSerializationStrategy.java @@ -0,0 +1,17 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + +import java.io.IOException; +import java.io.RandomAccessFile; + + +public class StringSerializationStrategy implements SerializationStrategy { + @Override + public String read(RandomAccessFile file) throws IOException { + return file.readUTF(); + } + + @Override + public void write(RandomAccessFile file, String value) throws IOException { + file.writeUTF(value); + } +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentKeySerializationStrategy.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentKeySerializationStrategy.java new file mode 100644 index 000000000..599f78dbf --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentKeySerializationStrategy.java @@ -0,0 +1,20 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + + +import ru.mipt.java2016.homework.tests.task2.StudentKey; + +import java.io.IOException; +import java.io.RandomAccessFile; + +public class StudentKeySerializationStrategy implements SerializationStrategy { + @Override + public StudentKey read(RandomAccessFile file) throws IOException { + return new StudentKey(file.readInt(), file.readUTF()); + } + + @Override + public void write(RandomAccessFile file, StudentKey value) throws IOException { + file.writeInt(value.getGroupId()); + file.writeUTF(value.getName()); + } +} diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentSerializationStrategy.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentSerializationStrategy.java new file mode 100644 index 000000000..fc2d619ca --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/StudentSerializationStrategy.java @@ -0,0 +1,26 @@ +package ru.mipt.java2016.homework.g595.ferenets.task2; + + +import ru.mipt.java2016.homework.tests.task2.Student; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Date; + +public class StudentSerializationStrategy implements SerializationStrategy { + @Override + public Student read(RandomAccessFile file) throws IOException { + return new Student(file.readInt(), file.readUTF(), file.readUTF(), + new Date(file.readLong()), file.readBoolean(), file.readDouble()); + } + + @Override + public void write(RandomAccessFile file, Student value) throws IOException { + file.writeInt(value.getGroupId()); + file.writeUTF(value.getName()); + file.writeUTF(value.getHometown()); + file.writeLong(value.getBirthDate().getTime()); + file.writeBoolean(value.isHasDormitory()); + file.writeDouble(value.getAverageScore()); + } +} diff --git a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculatorTest.java b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculatorTest.java new file mode 100644 index 000000000..fbc3ee4c1 --- /dev/null +++ b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task1/MyCalculatorTest.java @@ -0,0 +1,12 @@ +package ru.mipt.java2016.homework.g595.ferenets.task1; + +import ru.mipt.java2016.homework.base.task1.Calculator; +import ru.mipt.java2016.homework.tests.task1.AbstractCalculatorTest; + + +public class MyCalculatorTest extends AbstractCalculatorTest { + @Override + protected Calculator calc() { + return new MyCalculator(); + } +} diff --git a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorageTest.java b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorageTest.java new file mode 100644 index 000000000..d9dfeb742 --- /dev/null +++ b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorageTest.java @@ -0,0 +1,41 @@ +package ru.mipt.java2016.homework.g595.ferenets.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 MyKeyValueStorageTest extends AbstractSingleFileStorageTest { + + @Override + protected KeyValueStorage buildStringsStorage(String path) { + try { + return new MyKeyValueStorage(path, new StringSerializationStrategy(), new StringSerializationStrategy()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + @Override + protected KeyValueStorage buildNumbersStorage(String path) { + try { + return new MyKeyValueStorage(path, new IntegerSerializationStrategy(), new DoubleSerializationStrategy()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + @Override + protected KeyValueStorage buildPojoStorage(String path) { + try { + return new MyKeyValueStorage(path, new StudentKeySerializationStrategy(), new StudentSerializationStrategy()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/pom.xml b/pom.xml index 5bca65ec3..a8e972bb7 100644 --- a/pom.xml +++ b/pom.xml @@ -88,6 +88,7 @@ homework-g596-grebenshchikova homework-g597-kochukov homework-g597-sigareva + homework-g595-ferenets workshop-materials From 3887855a99ef63d1766973335c879f435462b4fb Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 03:12:17 +0300 Subject: [PATCH 02/13] Update MyKeyValueStorage.java --- .../ferenets/task2/MyKeyValueStorage.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java index bbc204346..7c327d38a 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java @@ -14,24 +14,24 @@ public class MyKeyValueStorage implements KeyValueStorage { private HashMap map; private SerializationStrategy keySerializator; private SerializationStrategy valueSerializator; - private RandomAccessFile RAFile; + private RandomAccessFile fileRA; private boolean opened; - MyKeyValueStorage(String path, SerializationStrategy _keySerializator, - SerializationStrategy _valueSerializator) throws IOException { + MyKeyValueStorage(String path, SerializationStrategy argKeySerializator, + SerializationStrategy argValueSerializator) throws IOException { map = new HashMap<>(); - keySerializator = _keySerializator; - valueSerializator = _valueSerializator; + keySerializator = argKeySerializator; + valueSerializator = argValueSerializator; opened = true; String pathToStorage = path + File.separator + "storage.txt"; try { File file = new File(pathToStorage); if (file.createNewFile()) { - RAFile = new RandomAccessFile(file.getPath(), "rw"); + fileRA = new RandomAccessFile(file.getPath(), "rw"); } else { - RAFile = new RandomAccessFile(file, "rw"); - int elementsCount = RAFile.readInt(); + fileRA = new RandomAccessFile(file, "rw"); + int elementsCount = fileRA.readInt(); for (int i = 0; i < elementsCount; ++i) { K currentKey = this.keySerializator.read(RAFile); V currentValue = this.valueSerializator.read(RAFile); @@ -88,15 +88,15 @@ public int size() { @Override public void close() throws IOException { try { - RAFile.setLength(0); - RAFile.seek(0); - RAFile.writeInt(map.size()); + fileRA.setLength(0); + fileRA.seek(0); + fileRA.writeInt(map.size()); for (HashMap.Entry entry : map.entrySet()) { - keySerializator.write(RAFile, entry.getKey()); - valueSerializator.write(RAFile, entry.getValue()); + keySerializator.write(fileRA, entry.getKey()); + valueSerializator.write(fileRA, entry.getValue()); } opened = false; - RAFile.close(); + fileRA.close(); } catch (IOException e) { throw new IOException("Closed."); } From 322c039c54a60b0540d46b7b654ebe4b708dd384 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 03:23:49 +0300 Subject: [PATCH 03/13] small fixes --- .../ferenets/task2/MyKeyValueStorage.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java index bbc204346..ebb7b2257 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java @@ -14,27 +14,27 @@ public class MyKeyValueStorage implements KeyValueStorage { private HashMap map; private SerializationStrategy keySerializator; private SerializationStrategy valueSerializator; - private RandomAccessFile RAFile; + private RandomAccessFile fileRA; private boolean opened; - MyKeyValueStorage(String path, SerializationStrategy _keySerializator, - SerializationStrategy _valueSerializator) throws IOException { + MyKeyValueStorage(String path, SerializationStrategy argKeySerializator, + SerializationStrategy argValueSerializator) throws IOException { map = new HashMap<>(); - keySerializator = _keySerializator; - valueSerializator = _valueSerializator; + keySerializator = argKeySerializator; + valueSerializator = argValueSerializator; opened = true; String pathToStorage = path + File.separator + "storage.txt"; try { File file = new File(pathToStorage); if (file.createNewFile()) { - RAFile = new RandomAccessFile(file.getPath(), "rw"); + fileRA = new RandomAccessFile(file.getPath(), "rw"); } else { - RAFile = new RandomAccessFile(file, "rw"); - int elementsCount = RAFile.readInt(); + fileRA = new RandomAccessFile(file, "rw"); + int elementsCount = fileRA.readInt(); for (int i = 0; i < elementsCount; ++i) { - K currentKey = this.keySerializator.read(RAFile); - V currentValue = this.valueSerializator.read(RAFile); + K currentKey = this.keySerializator.read(fileRA); + V currentValue = this.valueSerializator.read(fileRA); map.put(currentKey, currentValue); } } @@ -88,15 +88,15 @@ public int size() { @Override public void close() throws IOException { try { - RAFile.setLength(0); - RAFile.seek(0); - RAFile.writeInt(map.size()); + fileRA.setLength(0); + fileRA.seek(0); + fileRA.writeInt(map.size()); for (HashMap.Entry entry : map.entrySet()) { - keySerializator.write(RAFile, entry.getKey()); - valueSerializator.write(RAFile, entry.getValue()); + keySerializator.write(fileRA, entry.getKey()); + valueSerializator.write(fileRA, entry.getValue()); } opened = false; - RAFile.close(); + fileRA.close(); } catch (IOException e) { throw new IOException("Closed."); } From dccbb56f824a965bb50f0fb0294a188967d94cee Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 15:32:13 +0300 Subject: [PATCH 04/13] Task 1 2 --- .../ferenets/task2/MyKeyValueStorage.java | 2 +- .../ferenets/task3/MyOptimizedStorage.java | 139 ++++++++++++++++++ .../OptimizedStoragePerformanceTest.java | 43 ++++++ 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java create mode 100644 homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java index ebb7b2257..42d2c4b59 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java @@ -18,7 +18,7 @@ public class MyKeyValueStorage implements KeyValueStorage { private boolean opened; - MyKeyValueStorage(String path, SerializationStrategy argKeySerializator, + public MyKeyValueStorage(String path, SerializationStrategy argKeySerializator, SerializationStrategy argValueSerializator) throws IOException { map = new HashMap<>(); keySerializator = argKeySerializator; diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java new file mode 100644 index 000000000..7fe382277 --- /dev/null +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -0,0 +1,139 @@ +package ru.mipt.java2016.homework.g595.ferenets.task3; + + +import ru.mipt.java2016.homework.base.task2.KeyValueStorage; +import ru.mipt.java2016.homework.g595.ferenets.task2.SerializationStrategy; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class MyOptimizedStorage implements KeyValueStorage{ + private final int MAX_MEM_SIZE = 100; + private SerializationStrategy keySerialization; + private SerializationStrategy valueSerialization; + private HashMap map; + private HashMap keyValueOffset; + private boolean opened; + private RandomAccessFile storage; + private RandomAccessFile offsets; + + + + MyOptimizedStorage(String path, SerializationStrategy argKeySerialization, + SerializationStrategy argValueSerialization) throws IOException{ + keySerialization = argKeySerialization; + valueSerialization = argValueSerialization; + File storageFile = new File(path + File.separator + "storage.txt"); + File offsetsFile = new File(path + File.separator + "offsets.txt"); + try { + offsets = new RandomAccessFile(offsetsFile, "rw"); + storage = new RandomAccessFile(storageFile, "rw"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + int offsetsSize = offsets.readInt(); + for (int i = 0; i < offsetsSize; i++) { + try { + K key = keySerialization.read(offsets); + long offset = offsets.readLong(); + keyValueOffset.put(key, offset); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + private void checkFileAccess() { + if (!opened) { + throw new IllegalStateException("The storage is closed"); + } + } + + private void pushMapIntoFile() throws IOException{ + if(map.size() < MAX_MEM_SIZE) return; + storage.seek(storage.length()); + for (Map.Entry entry: map.entrySet()){ + if(!keyValueOffset.containsKey(entry.getKey())){ + keyValueOffset.put(entry.getKey(), storage.getFilePointer()); + valueSerialization.write(storage, entry.getValue()); + } + } + map.clear(); + } + + @Override + public V read(K key) { + checkFileAccess(); + try { + if (map.containsKey(key)) { + return map.get(key); + } + if (keyValueOffset.containsKey(key)) { + long offset = keyValueOffset.get(key); + storage.seek(offset); + V value = valueSerialization.read(storage); + return value; + } + }catch (IOException e){ + e.printStackTrace(); + } + return null; + } + + @Override + public boolean exists(K key) { + checkFileAccess(); + return keyValueOffset.containsKey(key); + } + + @Override + public void write(K key, V value) { + checkFileAccess(); + map.put(key, value); + try { + pushMapIntoFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void delete(K key) { + checkFileAccess(); + if(exists(key)){ + map.remove(key); + keyValueOffset.remove(key); + } + } + + @Override + public Iterator readKeys() { + checkFileAccess(); + return map.keySet().iterator(); + } + + @Override + public int size() { + checkFileAccess(); + return map.keySet().size() + keyValueOffset.size(); + } + + @Override + public void close() throws IOException { + opened = false; + pushMapIntoFile(); + offsets.writeInt(keyValueOffset.size()); + for (Map.Entry entry : keyValueOffset.entrySet()) { + keySerialization.write(offsets, entry.getKey()); + offsets.writeLong(entry.getValue()); + } + storage.close(); + offsets.close(); + } +} diff --git a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java new file mode 100644 index 000000000..5b48f2b27 --- /dev/null +++ b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java @@ -0,0 +1,43 @@ +package ru.mipt.java2016.homework.g595.ferenets.task3; + +import ru.mipt.java2016.homework.base.task2.*; +import ru.mipt.java2016.homework.g595.ferenets.task2.*; +import ru.mipt.java2016.homework.tests.task2.*; +import ru.mipt.java2016.homework.tests.task3.KeyValueStoragePerformanceTest; + +import java.io.IOException; + +public class OptimizedStoragePerformanceTest extends KeyValueStoragePerformanceTest { + @Override + protected KeyValueStorage buildStringsStorage(String path) throws MalformedDataException { + try { + return new MyKeyValueStorage(path, + new StringSerializationStrategy(), new StringSerializationStrategy()); + } catch (IOException e) { + e.getCause(); + } + return null; + } + + @Override + protected KeyValueStorage buildNumbersStorage(String path) throws MalformedDataException { + try { + return new MyKeyValueStorage<>(path, + new IntegerSerializationStrategy(), new StringSerializationStrategy()); + } catch (IOException e) { + e.getCause(); + } + return null; + } + + @Override + protected KeyValueStorage buildPojoStorage(String path) throws MalformedDataException { + try { + return new MyKeyValueStorage<>(path, + new StudentKeySerializationStrategy(), new StudentSerializationStrategy()); + } catch (IOException e) { + e.getCause(); + } + return null; + } +} From c466325297571e56325b1551efc0d6aa28df4323 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 15:54:22 +0300 Subject: [PATCH 05/13] Task 1 2 3 --- .../ferenets/task3/MyOptimizedStorage.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index 7fe382277..7da321972 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -12,8 +12,8 @@ import java.util.Iterator; import java.util.Map; -public class MyOptimizedStorage implements KeyValueStorage{ - private final int MAX_MEM_SIZE = 100; +public class MyOptimizedStorage implements KeyValueStorage { + private static final int MAX_MEM_SIZE = 100; private SerializationStrategy keySerialization; private SerializationStrategy valueSerialization; private HashMap map; @@ -25,7 +25,7 @@ public class MyOptimizedStorage implements KeyValueStorage{ MyOptimizedStorage(String path, SerializationStrategy argKeySerialization, - SerializationStrategy argValueSerialization) throws IOException{ + SerializationStrategy argValueSerialization) throws IOException { keySerialization = argKeySerialization; valueSerialization = argValueSerialization; File storageFile = new File(path + File.separator + "storage.txt"); @@ -55,10 +55,12 @@ private void checkFileAccess() { } } - private void pushMapIntoFile() throws IOException{ - if(map.size() < MAX_MEM_SIZE) return; + private void pushMapIntoFile() throws IOException { + if (map.size() < MAX_MEM_SIZE) { + return; + } storage.seek(storage.length()); - for (Map.Entry entry: map.entrySet()){ + for (Map.Entry entry: map.entrySet()) { if(!keyValueOffset.containsKey(entry.getKey())){ keyValueOffset.put(entry.getKey(), storage.getFilePointer()); valueSerialization.write(storage, entry.getValue()); @@ -80,7 +82,7 @@ public V read(K key) { V value = valueSerialization.read(storage); return value; } - }catch (IOException e){ + } catch (IOException e) { e.printStackTrace(); } return null; @@ -106,7 +108,7 @@ public void write(K key, V value) { @Override public void delete(K key) { checkFileAccess(); - if(exists(key)){ + if(exists(key)) { map.remove(key); keyValueOffset.remove(key); } From fb73801712739439190be6ff34f915189928ec13 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 16:02:07 +0300 Subject: [PATCH 06/13] Task 1 2 3 --- .../homework/g595/ferenets/task3/MyOptimizedStorage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index 7da321972..ccd6adbd3 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -61,7 +61,7 @@ private void pushMapIntoFile() throws IOException { } storage.seek(storage.length()); for (Map.Entry entry: map.entrySet()) { - if(!keyValueOffset.containsKey(entry.getKey())){ + if (!keyValueOffset.containsKey(entry.getKey())) { keyValueOffset.put(entry.getKey(), storage.getFilePointer()); valueSerialization.write(storage, entry.getValue()); } @@ -108,7 +108,7 @@ public void write(K key, V value) { @Override public void delete(K key) { checkFileAccess(); - if(exists(key)) { + if (exists(key)) { map.remove(key); keyValueOffset.remove(key); } From 2b5f43abef3abb3cb8bcb4c150a5a1f61d9d397d Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 23:28:49 +0300 Subject: [PATCH 07/13] Task 1 2 3 --- .../ferenets/task2/MyKeyValueStorage.java | 2 +- .../ferenets/task3/MyOptimizedStorage.java | 107 ++++++++++++------ .../OptimizedStoragePerformanceTest.java | 6 +- 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java index 42d2c4b59..6f64d73bf 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task2/MyKeyValueStorage.java @@ -95,8 +95,8 @@ public void close() throws IOException { keySerializator.write(fileRA, entry.getKey()); valueSerializator.write(fileRA, entry.getValue()); } - opened = false; fileRA.close(); + opened = false; } catch (IOException e) { throw new IOException("Closed."); } diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index ccd6adbd3..d19cc0788 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -8,43 +8,58 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.channels.FileLock; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class MyOptimizedStorage implements KeyValueStorage { private static final int MAX_MEM_SIZE = 100; private SerializationStrategy keySerialization; private SerializationStrategy valueSerialization; - private HashMap map; - private HashMap keyValueOffset; + private HashMap map = new HashMap(); + private HashMap keyValueOffset = new HashMap(); private boolean opened; private RandomAccessFile storage; private RandomAccessFile offsets; - + private String storagePath; + private String offsetsPath; + private FileLock lockFile; + private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); MyOptimizedStorage(String path, SerializationStrategy argKeySerialization, SerializationStrategy argValueSerialization) throws IOException { - keySerialization = argKeySerialization; - valueSerialization = argValueSerialization; - File storageFile = new File(path + File.separator + "storage.txt"); - File offsetsFile = new File(path + File.separator + "offsets.txt"); try { - offsets = new RandomAccessFile(offsetsFile, "rw"); - storage = new RandomAccessFile(storageFile, "rw"); + keySerialization = argKeySerialization; + valueSerialization = argValueSerialization; + storagePath = path + File.separator + "storage.txt"; + offsetsPath = path + File.separator + "offsets.txt"; + File offsetsFile = new File(offsetsPath); + File storageFile = new File(storagePath); + if(!offsetsFile.createNewFile()) { + offsets = new RandomAccessFile(offsetsPath, "rw"); + storage = new RandomAccessFile(storagePath, "rw"); + lockFile = offsets.getChannel().lock(); + int offsetsSize = offsets.readInt(); + for (int i = 0; i < offsetsSize; i++) { + K key = keySerialization.read(offsets); + long offset = offsets.readLong(); + keyValueOffset.put(key, offset); + } + lockFile.release(); + offsets.close(); + } else { + offsets = new RandomAccessFile(offsetsPath, "rw"); + storage = new RandomAccessFile(storagePath, "rw"); + lockFile = offsets.getChannel().lock(); + } } catch (FileNotFoundException e) { e.printStackTrace(); - } - int offsetsSize = offsets.readInt(); - for (int i = 0; i < offsetsSize; i++) { - try { - K key = keySerialization.read(offsets); - long offset = offsets.readLong(); - keyValueOffset.put(key, offset); - } catch (IOException e) { - e.printStackTrace(); - } + } catch (IOException e) { + e.printStackTrace(); } } @@ -56,21 +71,24 @@ private void checkFileAccess() { } private void pushMapIntoFile() throws IOException { + readWriteLock.writeLock().lock(); if (map.size() < MAX_MEM_SIZE) { return; } storage.seek(storage.length()); - for (Map.Entry entry: map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { if (!keyValueOffset.containsKey(entry.getKey())) { keyValueOffset.put(entry.getKey(), storage.getFilePointer()); valueSerialization.write(storage, entry.getValue()); } } map.clear(); + readWriteLock.writeLock().unlock(); } @Override public V read(K key) { + readWriteLock.writeLock().lock(); checkFileAccess(); try { if (map.containsKey(key)) { @@ -84,6 +102,8 @@ public V read(K key) { } } catch (IOException e) { e.printStackTrace(); + } finally { + readWriteLock.writeLock().unlock(); } return null; } @@ -96,46 +116,69 @@ public boolean exists(K key) { @Override public void write(K key, V value) { + readWriteLock.writeLock().lock(); checkFileAccess(); map.put(key, value); try { pushMapIntoFile(); } catch (IOException e) { e.printStackTrace(); + } finally { + readWriteLock.writeLock().unlock(); } } @Override public void delete(K key) { + readWriteLock.readLock().lock(); checkFileAccess(); if (exists(key)) { map.remove(key); keyValueOffset.remove(key); } + readWriteLock.readLock().unlock(); } @Override - public Iterator readKeys() { - checkFileAccess(); - return map.keySet().iterator(); + public Iterator readKeys() { + readWriteLock.readLock().lock(); + try{ + checkFileAccess(); + return map.keySet().iterator(); + } finally { + readWriteLock.readLock().unlock(); + } } @Override public int size() { - checkFileAccess(); - return map.keySet().size() + keyValueOffset.size(); + readWriteLock.readLock().lock(); + try{ + checkFileAccess(); + return map.keySet().size() + keyValueOffset.size(); + } finally { + readWriteLock.readLock().unlock(); + } } @Override public void close() throws IOException { + readWriteLock.writeLock().lock(); opened = false; - pushMapIntoFile(); - offsets.writeInt(keyValueOffset.size()); - for (Map.Entry entry : keyValueOffset.entrySet()) { - keySerialization.write(offsets, entry.getKey()); - offsets.writeLong(entry.getValue()); + try { + pushMapIntoFile(); + offsets = new RandomAccessFile(offsetsPath, "rw"); + lockFile = offsets.getChannel().lock(); + offsets.writeInt(keyValueOffset.size()); + for (Map.Entry entry : keyValueOffset.entrySet()) { + keySerialization.write(offsets, entry.getKey()); + offsets.writeLong(entry.getValue()); + } + lockFile.release(); + storage.close(); + offsets.close(); + } finally { + readWriteLock.writeLock().unlock(); } - storage.close(); - offsets.close(); } } diff --git a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java index 5b48f2b27..0b2f0b467 100644 --- a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java +++ b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java @@ -11,7 +11,7 @@ public class OptimizedStoragePerformanceTest extends KeyValueStoragePerformanceT @Override protected KeyValueStorage buildStringsStorage(String path) throws MalformedDataException { try { - return new MyKeyValueStorage(path, + return new MyOptimizedStorage(path, new StringSerializationStrategy(), new StringSerializationStrategy()); } catch (IOException e) { e.getCause(); @@ -22,7 +22,7 @@ protected KeyValueStorage buildStringsStorage(String path) throw @Override protected KeyValueStorage buildNumbersStorage(String path) throws MalformedDataException { try { - return new MyKeyValueStorage<>(path, + return new MyOptimizedStorage(path, new IntegerSerializationStrategy(), new StringSerializationStrategy()); } catch (IOException e) { e.getCause(); @@ -33,7 +33,7 @@ protected KeyValueStorage buildNumbersStorage(String path) thro @Override protected KeyValueStorage buildPojoStorage(String path) throws MalformedDataException { try { - return new MyKeyValueStorage<>(path, + return new MyOptimizedStorage(path, new StudentKeySerializationStrategy(), new StudentSerializationStrategy()); } catch (IOException e) { e.getCause(); From aa9da5a1cf8821328d7b10b5aa1e73736964d7c0 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Mon, 19 Dec 2016 23:31:33 +0300 Subject: [PATCH 08/13] Task 1 2 3 --- .../g595/ferenets/task3/MyOptimizedStorage.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index d19cc0788..18a7c22a3 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -39,7 +39,7 @@ public class MyOptimizedStorage implements KeyValueStorage { offsetsPath = path + File.separator + "offsets.txt"; File offsetsFile = new File(offsetsPath); File storageFile = new File(storagePath); - if(!offsetsFile.createNewFile()) { + if (!offsetsFile.createNewFile()) { offsets = new RandomAccessFile(offsetsPath, "rw"); storage = new RandomAccessFile(storagePath, "rw"); lockFile = offsets.getChannel().lock(); @@ -142,7 +142,7 @@ public void delete(K key) { @Override public Iterator readKeys() { readWriteLock.readLock().lock(); - try{ + try { checkFileAccess(); return map.keySet().iterator(); } finally { @@ -153,9 +153,9 @@ public Iterator readKeys() { @Override public int size() { readWriteLock.readLock().lock(); - try{ - checkFileAccess(); - return map.keySet().size() + keyValueOffset.size(); + try { + checkFileAccess(); + return map.keySet().size() + keyValueOffset.size(); } finally { readWriteLock.readLock().unlock(); } From ad98e5df3b9f2eb8888425f7d9ade82217f4d3c5 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Tue, 20 Dec 2016 01:16:57 +0300 Subject: [PATCH 09/13] Task 1 2 3 --- .../ferenets/task3/MyOptimizedStorage.java | 93 +++++++++++-------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index 18a7c22a3..3ca3c929c 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -9,23 +9,24 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileLock; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import java.nio.channels.OverlappingFileLockException; +import java.util.*; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; + public class MyOptimizedStorage implements KeyValueStorage { private static final int MAX_MEM_SIZE = 100; private SerializationStrategy keySerialization; private SerializationStrategy valueSerialization; private HashMap map = new HashMap(); - private HashMap keyValueOffset = new HashMap(); + private TreeMap keyValueOffset = new TreeMap(); + private HashSet keySet = new HashSet(); private boolean opened; private RandomAccessFile storage; private RandomAccessFile offsets; - private String storagePath; - private String offsetsPath; + private File storageFile; + private File offsetsFile; private FileLock lockFile; private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); @@ -35,32 +36,36 @@ public class MyOptimizedStorage implements KeyValueStorage { try { keySerialization = argKeySerialization; valueSerialization = argValueSerialization; - storagePath = path + File.separator + "storage.txt"; - offsetsPath = path + File.separator + "offsets.txt"; - File offsetsFile = new File(offsetsPath); - File storageFile = new File(storagePath); + String storagePath = path + File.separator + "storage.txt"; + String offsetsPath = path + File.separator + "offsets.txt"; + opened = true; + offsetsFile = new File(offsetsPath); + storageFile = new File(storagePath); if (!offsetsFile.createNewFile()) { - offsets = new RandomAccessFile(offsetsPath, "rw"); - storage = new RandomAccessFile(storagePath, "rw"); - lockFile = offsets.getChannel().lock(); + offsets = new RandomAccessFile(offsetsFile, "rw"); + storage = new RandomAccessFile(storageFile, "rw"); + try { + lockFile = offsets.getChannel().lock(); + } catch (OverlappingFileLockException e) { + e.printStackTrace(); + } int offsetsSize = offsets.readInt(); for (int i = 0; i < offsetsSize; i++) { K key = keySerialization.read(offsets); long offset = offsets.readLong(); keyValueOffset.put(key, offset); + keySet.add(key); } - lockFile.release(); - offsets.close(); } else { - offsets = new RandomAccessFile(offsetsPath, "rw"); - storage = new RandomAccessFile(storagePath, "rw"); + offsets = new RandomAccessFile(offsetsFile, "rw"); + storage = new RandomAccessFile(storageFile, "rw"); lockFile = offsets.getChannel().lock(); } - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } + lockFile.release(); + offsets.close(); } @@ -72,18 +77,19 @@ private void checkFileAccess() { private void pushMapIntoFile() throws IOException { readWriteLock.writeLock().lock(); - if (map.size() < MAX_MEM_SIZE) { - return; - } - storage.seek(storage.length()); - for (Map.Entry entry : map.entrySet()) { - if (!keyValueOffset.containsKey(entry.getKey())) { + try { + storage.seek(storage.length()); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == null){ + continue; + } keyValueOffset.put(entry.getKey(), storage.getFilePointer()); valueSerialization.write(storage, entry.getValue()); } + map.clear(); + } finally { + readWriteLock.writeLock().unlock(); } - map.clear(); - readWriteLock.writeLock().unlock(); } @Override @@ -100,18 +106,23 @@ public V read(K key) { V value = valueSerialization.read(storage); return value; } + return null; } catch (IOException e) { - e.printStackTrace(); + throw new IllegalStateException("Key is wrong"); } finally { readWriteLock.writeLock().unlock(); } - return null; } @Override public boolean exists(K key) { - checkFileAccess(); - return keyValueOffset.containsKey(key); + readWriteLock.readLock().lock(); + try { + checkFileAccess(); + return keySet.contains(key); + } finally { + readWriteLock.readLock().unlock(); + } } @Override @@ -119,8 +130,11 @@ public void write(K key, V value) { readWriteLock.writeLock().lock(); checkFileAccess(); map.put(key, value); + keySet.add(key); try { - pushMapIntoFile(); + if (map.size() > MAX_MEM_SIZE) { + pushMapIntoFile(); + } } catch (IOException e) { e.printStackTrace(); } finally { @@ -133,8 +147,9 @@ public void delete(K key) { readWriteLock.readLock().lock(); checkFileAccess(); if (exists(key)) { - map.remove(key); + map.put(key, null); keyValueOffset.remove(key); + keySet.remove(key); } readWriteLock.readLock().unlock(); } @@ -144,7 +159,7 @@ public Iterator readKeys() { readWriteLock.readLock().lock(); try { checkFileAccess(); - return map.keySet().iterator(); + return keySet.iterator(); } finally { readWriteLock.readLock().unlock(); } @@ -155,7 +170,7 @@ public int size() { readWriteLock.readLock().lock(); try { checkFileAccess(); - return map.keySet().size() + keyValueOffset.size(); + return keySet.size(); } finally { readWriteLock.readLock().unlock(); } @@ -167,8 +182,12 @@ public void close() throws IOException { opened = false; try { pushMapIntoFile(); - offsets = new RandomAccessFile(offsetsPath, "rw"); - lockFile = offsets.getChannel().lock(); + offsets = new RandomAccessFile(offsetsFile, "rw"); + try { + lockFile = offsets.getChannel().lock(); + } catch (OverlappingFileLockException e) { + e.printStackTrace(); + } offsets.writeInt(keyValueOffset.size()); for (Map.Entry entry : keyValueOffset.entrySet()) { keySerialization.write(offsets, entry.getKey()); From 917fdca8bfed0184dbae4ccd7ce7f91ddec9b037 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Tue, 20 Dec 2016 01:18:59 +0300 Subject: [PATCH 10/13] Task 1 2 3 --- .../homework/g595/ferenets/task3/MyOptimizedStorage.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index 3ca3c929c..63de4d6b9 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -5,7 +5,6 @@ import ru.mipt.java2016.homework.g595.ferenets.task2.SerializationStrategy; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileLock; @@ -80,7 +79,7 @@ private void pushMapIntoFile() throws IOException { try { storage.seek(storage.length()); for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == null){ + if (entry.getValue() == null) { continue; } keyValueOffset.put(entry.getKey(), storage.getFilePointer()); From f590a0e24dbb042f41ffcffbf6e1356857e5f628 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Tue, 20 Dec 2016 01:46:27 +0300 Subject: [PATCH 11/13] Task 1 2 3 --- .../g595/ferenets/task3/OptimizedStoragePerformanceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java index 0b2f0b467..d194708b1 100644 --- a/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java +++ b/homework-g595-ferenets/src/test/java/ru/mipt/java2016/homework/g595/ferenets/task3/OptimizedStoragePerformanceTest.java @@ -23,7 +23,7 @@ protected KeyValueStorage buildStringsStorage(String path) throw protected KeyValueStorage buildNumbersStorage(String path) throws MalformedDataException { try { return new MyOptimizedStorage(path, - new IntegerSerializationStrategy(), new StringSerializationStrategy()); + new IntegerSerializationStrategy(), new DoubleSerializationStrategy()); } catch (IOException e) { e.getCause(); } From 5d862bb38767b1bb9162683291385db8c2d7d23d Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Tue, 20 Dec 2016 01:54:34 +0300 Subject: [PATCH 12/13] Task 1 2 3 --- .../g595/ferenets/task3/MyOptimizedStorage.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index 63de4d6b9..20ba0e96a 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -26,7 +26,6 @@ public class MyOptimizedStorage implements KeyValueStorage { private RandomAccessFile offsets; private File storageFile; private File offsetsFile; - private FileLock lockFile; private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); @@ -43,11 +42,6 @@ public class MyOptimizedStorage implements KeyValueStorage { if (!offsetsFile.createNewFile()) { offsets = new RandomAccessFile(offsetsFile, "rw"); storage = new RandomAccessFile(storageFile, "rw"); - try { - lockFile = offsets.getChannel().lock(); - } catch (OverlappingFileLockException e) { - e.printStackTrace(); - } int offsetsSize = offsets.readInt(); for (int i = 0; i < offsetsSize; i++) { K key = keySerialization.read(offsets); @@ -58,12 +52,10 @@ public class MyOptimizedStorage implements KeyValueStorage { } else { offsets = new RandomAccessFile(offsetsFile, "rw"); storage = new RandomAccessFile(storageFile, "rw"); - lockFile = offsets.getChannel().lock(); } } catch (IOException e) { e.printStackTrace(); } - lockFile.release(); offsets.close(); } @@ -182,17 +174,11 @@ public void close() throws IOException { try { pushMapIntoFile(); offsets = new RandomAccessFile(offsetsFile, "rw"); - try { - lockFile = offsets.getChannel().lock(); - } catch (OverlappingFileLockException e) { - e.printStackTrace(); - } offsets.writeInt(keyValueOffset.size()); for (Map.Entry entry : keyValueOffset.entrySet()) { keySerialization.write(offsets, entry.getKey()); offsets.writeLong(entry.getValue()); } - lockFile.release(); storage.close(); offsets.close(); } finally { From 91fbc00476f3d48120ceae52360d4c6f0de4e7f1 Mon Sep 17 00:00:00 2001 From: MiptAlex179 Date: Tue, 20 Dec 2016 01:56:45 +0300 Subject: [PATCH 13/13] Update MyOptimizedStorage.java --- .../homework/g595/ferenets/task3/MyOptimizedStorage.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java index 20ba0e96a..b9e5ccfbc 100644 --- a/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java +++ b/homework-g595-ferenets/src/main/java/ru/mipt/java2016/homework/g595/ferenets/task3/MyOptimizedStorage.java @@ -7,8 +7,6 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; -import java.nio.channels.FileLock; -import java.nio.channels.OverlappingFileLockException; import java.util.*; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;