merge method

  1. @override
RgaList<T> merge(
  1. covariant RgaList<T> other
)
override

Merges this CRDT with another of the same type.

Implementation

@override
RgaList<T> merge(covariant RgaList<T> other) {
  final nodes = Map<String, RgaNode<T>>.from(_nodes);
  for (final node in other._nodes.values) {
    final existing = nodes[node.id];
    if (existing == null) {
      nodes[node.id] = node;
    } else if (existing.value != node.value || existing.origin != node.origin) {
      // Same id, different content: two replicas generated colliding ids —
      // the deserialization trap of editing a document loaded WITHOUT
      // passing this device's own replicaId to fromMap. One edit is
      // already lost; pick the winner DETERMINISTICALLY so every replica
      // at least converges to the same state instead of diverging forever
      // (keeping "ours" made each side keep a different node).
      final keepExisting = _collisionRank(existing).compareTo(_collisionRank(node)) >= 0;
      final winner = keepExisting ? existing : node;
      nodes[node.id] = (existing.deleted || node.deleted) && !winner.deleted ? winner.tombstone() : winner;
    } else if (node.deleted && !existing.deleted) {
      nodes[node.id] = existing.tombstone(); // deletion wins (monotonic)
    }
  }
  final counter = _counter > other._counter ? _counter : other._counter;
  return RgaList._(replicaId, nodes, counter);
}