diffTTCRDT function
TTGraphData?
diffTTCRDT(
- TTGraphData updatedGraph,
- TTGraphData existingGraph, {
- CrdtOption? opts,
Implementation
TTGraphData? diffTTCRDT(TTGraphData updatedGraph, TTGraphData existingGraph,
{CrdtOption? opts}) {
opts ??= CrdtOption(lexical: jsonEncode, futureGrace: 10 * 60 * 1000);
var machineState = DateTime.now().millisecondsSinceEpoch,
futureGrace = opts.futureGrace,
lexical = opts.lexical!;
final maxState = machineState + futureGrace!;
final TTGraphData allUpdates = TTGraphData();
for (final soul in updatedGraph.entries) {
final TTNode? existing = existingGraph[soul.key];
final TTNode? updated = soul.value;
final TTNodeState existingState =
existing?.nodeMetaData?.forward ?? TTNodeState();
final TTNodeState updatedState =
updated?.nodeMetaData?.forward ?? TTNodeState();
if (updated == null) {
if (existing == null) {
allUpdates[soul.key] = updated;
}
continue;
}
var hasUpdates = false;
final TTNode updates =
TTNode(nodeMetaData: TTNodeMeta(key: soul.key, forward: TTNodeState()));
for (final key in updatedState.keys) {
final existingKeyState = existingState[key];
final updatedKeyState = updatedState[key];
if (updatedKeyState == null || updatedKeyState > maxState) {
continue;
}
if (existingKeyState != null && existingKeyState >= updatedKeyState) {
continue;
}
if (existingKeyState == updatedKeyState) {
final existingVal = existing?[key];
final updatedVal = updated[key];
// This follows the original GUN conflict resolution logic
if (lexical(updatedVal) <= lexical(existingVal)) {
continue;
}
}
updates[key] = updated[key];
updates.nodeMetaData?.forward![key] = updatedKeyState;
hasUpdates = true;
}
if (hasUpdates) {
allUpdates[soul.key] = updates;
}
}
return allUpdates.isNotEmpty ? allUpdates : null;
}