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;
 }
 /**
  * Устанавливает значение по указанному ключу.
  *
  * @param key Ключ для нового значения. Не может быть null.
  * @param value Новое значение. Не может быть null.
  * @return Значение, которое было записано по этому ключу ранее. Если ранее значения не было
  *     записано, возвращает null.
  * @throws IllegalArgumentException Если значение параметров key или value является null.
  * @throws ru.fizteh.fivt.storage.structured.ColumnFormatException - при попытке передать
  *     Storeable с колонками другого типа.
  */
 @Override
 public Storeable put(String key, Storeable value) throws ColumnFormatException {
   checkKey(key);
   checkValue(value);
   Storeable oldValue = tableIndexedData.get(key);
   if (oldValue == null || !oldValue.equals(value)) {
     HashcodeDestination dest = new HashcodeDestination(key);
     tableFileModified[dest.getDir()][dest.getFile()] = true;
     tableIndexedData.put(key, value);
   }
   return oldValue;
 }