compactSync method

bool compactSync()

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;
}