compactSync method
Merges every segment into one, keeping the newest version of each key.
This is a full compaction: because it rewrites every segment, tombstones
can be dropped entirely — after the merge no older copy of a deleted key
remains. Returns false when there was nothing to do.
Implementation
bool compactSync() {
_checkWritable();
_checkOpen();
if (_segments.length < 2) return false;
final builder = SegmentBuilder(blockTargetSize: blockTargetSize);
final seen = MemTable();
for (var i = _segments.length - 1; i >= 0; i--) {
_segments[i].forEachEntry((key, document) {
if (seen.contains(key)) return;
seen.put(key, 0, 0, 0);
if (document == null) return; // tombstone: drop with the old data
builder.add(key, document.toBytes());
});
}
final oldNames = <String>[for (final info in _segmentInfos) info.name];
final bytes = builder.finish();
final name = _segmentName(_nextSegmentId++);
_writeFile(name, bytes.asUint8List());
final info = SegmentInfo(
name: name,
entryCount: builder.docCount,
byteLength: bytes.length,
);
_manifest = ManifestStore(_directory).saveSync(<SegmentInfo>[info]);
_segments
..clear()
..add(SegmentReader(bytes.asUint8List()));
_segmentInfos
..clear()
..add(info);
for (final old in oldNames) {
_directory.deleteSync(old);
}
return true;
}