/**
  * Устанавливает значение по указанному ключу.
  *
  * @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;
 }
 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);
 }