encode method

Uint8List encode(
  1. Fugue<String> f
)

Encode f to a compact byte buffer.

Implementation

Uint8List encode(Fugue<String> f) {
  final blocks = f.rawBlocks.toList(growable: false);

  // Intern replica ids in first-seen order.
  final index = <String, int>{};
  int rid(String r) => index.putIfAbsent(r, () => index.length);
  for (final b in blocks) {
    rid(b.$1.replica); // start
    if (!b.$2.isOrigin) rid(b.$2.replica); // parent
  }
  final dict = List<String>.filled(index.length, '');
  index.forEach((r, i) => dict[i] = r);

  final out = BytesBuilder(copy: false);
  out.addByte(1);
  _varint(out, dict.length);
  for (final r in dict) {
    final b = utf8.encode(r);
    _varint(out, b.length);
    out.add(b);
  }
  _varint(out, blocks.length);
  for (final (start, parent, side, values, del) in blocks) {
    _varint(out, rid(start.replica));
    _varint(out, start.counter);
    final origin = parent.isOrigin;
    out.addByte((side == Side.right ? 1 : 0) | (origin ? 0x80 : 0));
    if (!origin) {
      _varint(out, rid(parent.replica));
      _varint(out, parent.counter);
    }
    final runBytes = utf8.encode(values.join());
    _varint(out, runBytes.length);
    out.add(runBytes);
    _varint(out, values.length);
    _varint(out, del.length ~/ 2);
    for (var i = 0; i + 1 < del.length; i += 2) {
      _varint(out, del[i]);
      _varint(out, del[i + 1]);
    }
  }
  return out.toBytes();
}