void (@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."); }); }