compact method

Future<bool> compact()

Merges every segment into one, dropping tombstones.

Implementation

Future<bool> compact() async {
  if (_segmentInfos.length < 2) return false;
  final builder = SegmentBuilder(blockTargetSize: blockTargetSize);
  final seen = MemTable();
  for (var i = _segmentInfos.length - 1; i >= 0; i--) {
    final reader = await _readerAt(i);
    reader.forEachEntry((key, document) {
      if (seen.contains(key)) return;
      seen.put(key, 0, 0, 0);
      if (document == null) return;
      builder.add(key, document.toBytes());
    });
  }
  final bytes = builder.finish();
  final name = _segmentName(_nextSegmentId++);
  await store.put(_key(name), bytes.asUint8List());

  final info = SegmentInfo(
    name: name,
    entryCount: builder.docCount,
    byteLength: bytes.length,
  );
  final oldNames = <String>[
    for (final segment in _segmentInfos) segment.name,
  ];
  _generation++;
  await store.put(
    _key(manifestKey),
    Manifest(generation: _generation, segments: <SegmentInfo>[info]).encode(),
  );
  await store.deleteMany(<String>[for (final old in oldNames) _key(old)]);

  _segmentInfos
    ..clear()
    ..add(info);
  _segmentCache.clear();
  _lru.clear();
  return true;
}