@Test
 public void rollbackHardTest() throws IOException, ParseException {
   testTableEng.put("key1", tableProvider.deserialize(testTableEng, "[1, 2, 3]"));
   testTableEng.put("key2", tableProvider.deserialize(testTableEng, "[4, 5, 6]"));
   Assert.assertEquals(2, testTableEng.commit());
   testTableEng.remove("key2");
   testTableEng.put("key2", tableProvider.deserialize(testTableEng, "[4, 5, 6]"));
   Assert.assertEquals(0, testTableEng.rollback());
   testTableEng.remove("key1");
   testTableEng.remove("key2");
 }
 @Test
 public void commitHardTest() throws IOException, ParseException {
   testTableEng.put("key1", tableProvider.deserialize(testTableEng, "[1, 2, 3]"));
   testTableEng.put("key2", tableProvider.deserialize(testTableEng, "[4, 5, 6]"));
   Assert.assertEquals(2, testTableEng.commit());
   testTableEng.put("key1", tableProvider.deserialize(testTableEng, "[7, 8, 9]"));
   testTableEng.put("key3", tableProvider.deserialize(testTableEng, "[10, 11, 12]"));
   testTableEng.remove("key2");
   Assert.assertEquals(3, testTableEng.commit());
   testTableEng.remove("key1");
   testTableEng.remove("key3");
 }
  /** TEST BLOCK REMOVE TESTS */
  @Test
  public void removeTest() throws IOException, ParseException {
    testTableEng.put("key", tableProvider.deserialize(testTableEng, "[1, 2, 3]"));
    Assert.assertNull(testTableEng.remove("nonExictingKey"));
    Assert.assertEquals(
        "[1,2,3]", tableProvider.serialize(testTableEng, testTableEng.remove("key")));

    testTableRus.put(
        "ключ", tableProvider.deserialize(testTableRus, "[1, 2.043, true, \"Hello World!\"]"));
    Assert.assertNull(testTableRus.remove("несуществующийКлюч"));
    Assert.assertEquals(
        "[1,2.043,true,\"Hello World!\"]",
        tableProvider.serialize(testTableRus, testTableRus.remove("ключ")));
  }
 /** TEST BLOCK ROLLBACK TESTS */
 @Test
 public void rollbackTest() throws IOException, ParseException {
   Assert.assertEquals(0, testTableEng.rollback());
   for (int i = 1; i <= 5; ++i) {
     testTableEng.put("key" + i, tableProvider.deserialize(testTableEng, "[1, 2, 3" + i + "]"));
   }
   testTableEng.commit();
   testTableEng.put("key2", tableProvider.deserialize(testTableEng, "[1, 2, 0]"));
   testTableEng.put("key4", tableProvider.deserialize(testTableEng, "[1, 2, 1]"));
   Assert.assertEquals(2, testTableEng.rollback());
   Assert.assertEquals(
       "[1,2,32]", tableProvider.serialize(testTableEng, testTableEng.get("key2")));
   Assert.assertEquals(
       "[1,2,34]", tableProvider.serialize(testTableEng, testTableEng.get("key4")));
   for (int i = 1; i <= 5; ++i) {
     testTableEng.remove("key" + i);
   }
 }
  /** TEST BLOCK SIZE TESTS */
  @Test
  public void sizeTest() throws IOException, ParseException {
    Assert.assertEquals(0, testTableEng.size());
    testTableEng.put("key1", tableProvider.deserialize(testTableEng, "[1, 2, 3]"));
    Assert.assertEquals(1, testTableEng.size());
    testTableEng.put("key2", tableProvider.deserialize(testTableEng, "[4, 5, 6]"));
    testTableEng.put("key3", tableProvider.deserialize(testTableEng, "[7, 8, 9]"));
    Assert.assertEquals(3, testTableEng.size());
    testTableEng.put("key4", tableProvider.deserialize(testTableEng, "[10, 11, 12]"));
    testTableEng.put("key5", tableProvider.deserialize(testTableEng, "[13, 14, 15]"));
    Assert.assertEquals(5, testTableEng.size());
    testTableEng.commit();
    Assert.assertEquals(5, testTableEng.size());

    for (int i = 1; i <= 5; ++i) {
      testTableEng.remove("key" + i);
    }
  }
 /** TEST BLOCK COMMIT TESTS */
 @Test
 public void commitTest() throws IOException, ParseException {
   Assert.assertEquals(0, testTableEng.commit());
   for (int i = 1; i <= 5; ++i) {
     testTableEng.put("key" + i, tableProvider.deserialize(testTableEng, "[1, 2, 3" + i + "]"));
   }
   Assert.assertEquals(5, testTableEng.commit());
   for (int i = 1; i <= 5; ++i) {
     testTableEng.remove("key" + i);
   }
 }
  private void update() throws DatabaseCorruptedException, IOException {
    try (RandomAccessFile file = new RandomAccessFile(filePath.toString(), "r")) {
      if (file.length() == 0) {
        throw new DatabaseCorruptedException("Data base corrupted: empty file found");
      }
      List<String> keys = new LinkedList<>();
      List<Integer> offsets = new LinkedList<>();
      ByteArrayOutputStream bytes = new ByteArrayOutputStream();
      byte b;
      int counter = 0;
      do { // Read keys.
        while ((b = file.readByte()) != 0) {
          counter++;
          bytes.write(b);
        }
        ++counter;
        offsets.add(file.readInt());
        counter += 4;
        String key = bytes.toString(TableManager.CODE_FORMAT);
        bytes.reset();
        if (!checkKey(key)) {
          throw new DatabaseCorruptedException("Wrong key found in file " + filePath.toString());
        }
        keys.add(key);
      } while (counter < offsets.get(0));

      offsets.add((int) file.length());
      offsets.remove(0); // It's current position in file, we don't need it in list.
      Iterator<String> keyIterator = keys.iterator();
      for (int nextOffset : offsets) { // Read values.
        while (counter < nextOffset) {
          bytes.write(file.readByte());
          counter++;
        }
        if (bytes.size() > 0) {
          try {
            fileMap.put(
                keyIterator.next(),
                provider.deserialize(table, bytes.toString(TableManager.CODE_FORMAT)));
          } catch (ParseException e) {
            throw new RuntimeException(
                "Data corrupted in file " + filePath.toString() + " : " + e.getMessage());
          }
          bytes.reset();
        } else {
          throw new DatabaseCorruptedException("Data corrupted in file " + filePath.toString());
        }
      }
      bytes.close();
    }
  }
  /** TEST BLOCK PUT TESTS */
  @Test
  public void putTest() throws IOException, ParseException {
    Assert.assertNull(
        testTableEng.put("key", tableProvider.deserialize(testTableEng, "[1, 2, 3]")));
    Assert.assertEquals(
        "[1,2,3]",
        tableProvider.serialize(
            testTableEng,
            testTableEng.put("key", tableProvider.deserialize(testTableEng, "[1, 2, 3]"))));
    Assert.assertEquals(
        "[1,2,3]",
        tableProvider.serialize(
            testTableEng,
            testTableEng.put("key", tableProvider.deserialize(testTableEng, "[-1, -2, -3]"))));
    testTableEng.remove("key");

    Assert.assertNull(
        testTableRus.put(
            "ключ", tableProvider.deserialize(testTableRus, "[1, 2.043, true, \"Hello World!\"]")));
    Assert.assertEquals(
        "[1,2.043,true,\"Hello World!\"]",
        tableProvider.serialize(
            testTableRus,
            testTableRus.put(
                "ключ",
                tableProvider.deserialize(testTableRus, "[1, 2.043, true, \"Hello World!\"]"))));
    Assert.assertEquals(
        "[1,2.043,true,\"Hello World!\"]",
        tableProvider.serialize(
            testTableRus,
            testTableRus.put(
                "ключ",
                tableProvider.deserialize(
                    testTableRus, "[-1, -2.043, false, \"Bye Bye World!\"]"))));
    testTableRus.remove("ключ");
  }
 private void index() {
   File[] subDirsList = tableRootDir.listFiles();
   if (subDirsList != null) {
     for (File subDir : subDirsList) {
       int numberOfSubDir;
       if (subDir.getName().equals(SignatureFile.signatureFileName)) {
         continue;
       }
       if (!subDir.isDirectory()) {
         throw new IllegalStateException("In table root dir found object is not a directory");
       }
       String[] tableSubDirName = subDir.getName().split("[.]");
       try {
         numberOfSubDir = Integer.parseInt(tableSubDirName[0]);
       } catch (NumberFormatException e) {
         throw new IllegalStateException("Table root directory contains not 0.dir ... 15.dir");
       }
       if (numberOfSubDir < 0
           || numberOfSubDir > 15
           || !tableSubDirName[1].equals("dir")
           || tableSubDirName.length != 2) {
         throw new IllegalStateException("Table root directory contains not 0.dir ... 15.dir");
       }
       File[] subFilesList = subDir.listFiles();
       if (subFilesList != null && subFilesList.length == 0) {
         throw new IllegalStateException("data base contains empty dir");
       }
       if (subFilesList != null) {
         for (File subFile : subFilesList) {
           int numberOfSubFile;
           if (!subFile.isFile()) {
             throw new IllegalStateException("In table sub dir found object is not a file");
           }
           String[] dbFileName = subFile.getName().split("[.]");
           try {
             numberOfSubFile = Integer.parseInt(dbFileName[0]);
           } catch (NumberFormatException e) {
             throw new IllegalStateException("Table sub directory contains not 0.dat ... 15.dat");
           }
           if (numberOfSubFile < 0
               || numberOfSubFile > 15
               || !dbFileName[1].equals("dat")
               || dbFileName.length != 2) {
             throw new IllegalStateException("Table sub directory contains not 0.dat ... 15.dat");
           } else if (subFile.length() == 0) {
             throw new IllegalStateException("Empty file in sub dir");
           } else {
             tableFiles[numberOfSubDir][numberOfSubFile] = new TableFile(subFile);
             List<TableFile.Entry> fileData =
                 tableFiles[numberOfSubDir][numberOfSubFile].readEntries();
             for (TableFile.Entry i : fileData) {
               HashcodeDestination dest = new HashcodeDestination(i.getKey());
               if (dest.getFile() != numberOfSubFile || dest.getDir() != numberOfSubDir) {
                 throw new IllegalStateException("Wrong key placement");
               }
               try {
                 tableIndexedData.put(i.getKey(), tableProvider.deserialize(this, i.getValue()));
               } catch (ParseException e) {
                 throw new IllegalStateException("Can't deserialize", e);
               }
             }
           }
         }
       }
     }
   }
   tableOnDisk = new HashMap<>(tableIndexedData);
 }
 @Test(expected = IllegalArgumentException.class)
 public void putNullKeyTest() throws IOException, ParseException {
   testTableEng.put(
       null, testTableEng.put("key", tableProvider.deserialize(testTableEng, "[1, 2, 3]")));
 }