public void commitChanges() throws IOException, RuntimeException {
    Throwable t = null;
    RandomAccessFile dataFile = null;
    try {
      try {
        dataFile = new RandomAccessFile(filePath, "rw");
      } catch (FileNotFoundException e) {
        throw new RuntimeException(filePath + " can't get access to file", e);
      }
      if (data == null || data.isEmpty()) {
        closeDataFile(dataFile);
        Shell sh = new Shell(tablePath, false);
        if (sh.rm(filePath) != Shell.ExitCode.OK) {
          throw new RuntimeException(filePath + " can't delete file");
        }
        exists = false;
        return;
      }

      int offset = 0;
      Set<Map.Entry<String, Storeable>> mySet = data.entrySet();
      for (Map.Entry<String, Storeable> myEntry : mySet) {
        offset += getLength(myEntry.getKey()) + 1 + 4;
      }
      int currOffset = offset;
      dataFile.setLength(0);
      dataFile.seek(0);
      for (Map.Entry<String, Storeable> myEntry : mySet) {
        dataFile.write(myEntry.getKey().getBytes());
        dataFile.writeByte(0);
        dataFile.writeInt(currOffset);
        currOffset += getLength(table.getProvider().serialize(table, myEntry.getValue()));
      }
      for (Map.Entry<String, Storeable> myEntry : mySet) {
        dataFile.write(table.getProvider().serialize(table, myEntry.getValue()).getBytes());
      }
    } catch (RuntimeException e5) {
      t = e5;
      throw e5;
    } finally {
      try {
        closeDataFile(dataFile);
      } catch (Throwable e6) {
        if (t != null) {
          t.addSuppressed(e6);
        }
      }
    }
  }
  public void load(RandomAccessFile dataFile) throws RuntimeException, IOException, ParseException {
    try {
      if (dataFile.length() == 0) {
        return;
      }

      long currPtr = 0;
      long firstOffset = 0;
      long newOffset = 0;
      long nextOffset = 0;
      String keyFirst = "";
      String keySecond = "";
      String value;

      dataFile.seek(currPtr);
      keyFirst = getKeyFromFile(dataFile);

      newOffset = dataFile.readInt();
      currPtr = dataFile.getFilePointer();
      checkOffset(newOffset, currPtr, dataFile);
      firstOffset = newOffset;
      do {
        dataFile.seek(currPtr);
        if (currPtr < firstOffset) {
          keySecond = getKeyFromFile(dataFile);
          nextOffset = dataFile.readInt();
          currPtr = dataFile.getFilePointer();
          checkOffset(nextOffset, currPtr, dataFile);
        } else if (currPtr == firstOffset) {
          nextOffset = dataFile.length();
          currPtr++;
        }
        if (nextOffset < newOffset) {
          IOException e1 = new IOException();
          throw e1;
        }

        dataFile.seek(newOffset);
        value = getValueFromFile(nextOffset, dataFile);

        MyStoreable val;
        try {
          val = (MyStoreable) table.getProvider().deserialize(table, value);
        } catch (ParseException e) {
          throw new ParseException(
              filePath + " can't deserialize values from file " + e.getMessage(),
              e.getErrorOffset());
        }
        data.put(keyFirst, val);
        //                table.getHashMap().put(keyFirst, val);*/

        keyFirst = keySecond;
        newOffset = nextOffset;
      } while (currPtr <= firstOffset);
      hasChanged = true;
    } catch (IOException e1) {
      throw new IOException(filePath + " can't read values from file", e1);
    } catch (OutOfMemoryError e2) {
      throw new RuntimeException(filePath + " can't read values from file: out of memory", e2);
    }
  }