void () { flushLock.readLock().lock(); try { List<Integer> files = new ArrayList<>(ourFinishedFiles.size()); ourFinishedFiles.drainTo(files); if (!files.isEmpty()) { for (Integer fileId : files) { RuntimeException exception = ourLock.withWriteLock(fileId, () -> { try { final Timestamps timestamp = ourTimestampsCache.remove(fileId); if (timestamp == null) return null; if (timestamp.isDirty() /*&& file.isValid()*/) { //RC: now I don't see the benefits of implementing timestamps write via raw attribute bytebuffer access // doFlush() is mostly outside the critical path, while implementing timestamps.writeToBuffer(buffer) // is complicated with all those variable-sized numbers used. storage.invoke().writeTimestamps(fileId, timestamp.toImmutable()); } return null; } catch (IOException e) { return new RuntimeException(e); } }); if (exception != null) { throw exception; } } } } finally { flushLock.readLock().unlock(); } }