private void compact(@NotNull Path path) {
    withWriteLock(() -> {
      LOG.info("Space waste in " + path + " is " + myDataTable.getWaste() + " bytes. Compacting now.");
      long start = System.currentTimeMillis();

      try {
        Path parentDir = path.getParent();
        Path newDataFile = parentDir.resolve(path.getFileName() + ".storageData.backup");
        Files.createDirectories(parentDir);
        createOrTruncateFile(newDataFile);

        Path oldDataFile = parentDir.resolve(path.getFileName() + DATA_EXTENSION);
        DataTable newDataTable = new DataTable(newDataFile, myContext);

        RecordIdIterator recordIterator = myRecordsTable.createRecordIdIterator();
        while (recordIterator.hasNextId()) {
          final int recordId = recordIterator.nextId();
          final long addr = myRecordsTable.getAddress(recordId);
          final int size = myRecordsTable.getSize(recordId);

          if (size > 0) {
            assert addr > 0;

            final int capacity = myCapacityAllocationPolicy.calculateCapacity(size);
            final long newaddr = newDataTable.allocateSpace(capacity);
            final byte[] bytes = new byte[size];
            myDataTable.readBytes(addr, bytes);
            newDataTable.writeBytes(newaddr, bytes);
            myRecordsTable.setAddress(recordId, newaddr);
            myRecordsTable.setCapacity(recordId, capacity);
          }
        }

        myDataTable.close();
        newDataTable.close();

        Files.move(newDataFile, oldDataFile, StandardCopyOption.REPLACE_EXISTING);
        myDataTable = new DataTable(oldDataFile, myContext);
      }
      catch (IOException e) {
        LOG.info("Compact failed", e);
      }

      long timedelta = System.currentTimeMillis() - start;
      LOG.info("Done compacting in " + timedelta + "msec.");
    });
  }
private void compact(@NotNull Path path)