public int uncommittedChanges() {
   Set<Map.Entry<String, Storeable>> indexedSet = tableIndexedData.entrySet();
   Set<Map.Entry<String, Storeable>> diskSet = tableOnDisk.entrySet();
   int count = 0;
   Iterator<Map.Entry<String, Storeable>> iter1 = indexedSet.iterator();
   Iterator<Map.Entry<String, Storeable>> iter2 = diskSet.iterator();
   while (iter1.hasNext()) {
     Map.Entry<String, Storeable> next = iter1.next();
     Storeable entryOnDisk = tableOnDisk.get(next.getKey());
     if (entryOnDisk == null) {
       // записи на диске нет, то она изменение
       ++count;
     } else if (!entryOnDisk.equals(next.getValue())) {
       // запись на диске есть, но она другая, тоже изменение
       ++count;
     }
   }
   while (iter2.hasNext()) {
     Map.Entry<String, Storeable> next = iter2.next();
     Storeable entryIndexed = tableIndexedData.get(next.getKey());
     if (entryIndexed == null) {
       // на диске есть, индексированной нет, изменение
       ++count;
     }
   }
   return count;
 }
 /**
  * Выполняет фиксацию изменений.
  *
  * @return Число записанных изменений.
  * @throws java.io.IOException если произошла ошибка ввода/вывода. Целостность таблицы не
  *     гарантируется.
  */
 @Override
 public int commit() throws IOException {
   int numberOfCommittedChanges = uncommittedChanges();
   Set<Map.Entry<String, Storeable>> dbSet = tableIndexedData.entrySet();
   for (int nDir = 0; nDir < 16; ++nDir) {
     for (int nFile = 0; nFile < 16; ++nFile) {
       if (tableFileModified[nDir][nFile]) {
         if (tableFiles[nDir][nFile] == null) {
           File subDir = new File(tableRootDir, Integer.toString(nDir) + ".dir");
           File subFile = new File(subDir, Integer.toString(nFile) + ".dat");
           if (!subDir.exists()) {
             if (!subDir.mkdir()) {
               throw new IllegalStateException("Sub dir was not created");
             }
           }
           tableFiles[nDir][nFile] = new TableFile(subFile);
         }
         List<TableFile.Entry> fileData = new ArrayList<>();
         Iterator<Map.Entry<String, Storeable>> iter = dbSet.iterator();
         while (iter.hasNext()) {
           Map.Entry<String, Storeable> tempMapEntry = iter.next();
           HashcodeDestination dest = new HashcodeDestination(tempMapEntry.getKey());
           if (dest.getDir() == nDir && dest.getFile() == nFile) {
             fileData.add(
                 new TableFile.Entry(
                     tempMapEntry.getKey(),
                     tableProvider.serialize(this, tempMapEntry.getValue())));
           }
         }
         tableFiles[nDir][nFile].writeEntries(fileData);
         tableFileModified[nDir][nFile] = false;
       }
     }
   }
   tableOnDisk.clear();
   tableOnDisk.putAll(tableIndexedData);
   return numberOfCommittedChanges;
 }