diff --git a/packages/object/src/hashgraph/index.ts b/packages/object/src/hashgraph/index.ts index bae345b4..15c82431 100644 --- a/packages/object/src/hashgraph/index.ts +++ b/packages/object/src/hashgraph/index.ts @@ -1,4 +1,3 @@ -import { doesNotMatch } from "node:assert"; import * as crypto from "node:crypto"; import { BitSet } from "./bitset.js"; @@ -179,7 +178,10 @@ export class HashGraph { return result; } - linearizeOperations(): Operation[] { + linearizeOperations( + areCausallyRelatedFn: (v1: Hash, v2: Hash) => boolean = this + .areCausallyRelated, + ): Operation[] { const order = this.topologicalSort(); const result: Operation[] = []; let i = 0; @@ -192,7 +194,7 @@ export class HashGraph { while (j < order.length) { const moving = order[j]; - if (!this.areCausallyRelated(anchor, moving)) { + if (!areCausallyRelatedFn(anchor, moving)) { const v1 = this.vertices.get(anchor); const v2 = this.vertices.get(moving); let action: ActionType; @@ -251,6 +253,46 @@ export class HashGraph { return test1 || test2; } + areCausallyRelatedOld(hash1: Hash, hash2: Hash): boolean { + const visited = new Set(); + const stack = [hash1]; + + while (stack.length > 0) { + const current = stack.pop(); + if (current === hash2) return true; + if (current === undefined) continue; + visited.add(current); + + const vertex = this.vertices.get(current); + if (!vertex) continue; + for (const dep of vertex.dependencies) { + if (!visited.has(dep)) { + stack.push(dep); + } + } + } + + visited.clear(); + stack.push(hash2); + + while (stack.length > 0) { + const current = stack.pop(); + if (current === hash1) return true; + if (current === undefined) continue; + visited.add(current); + + const vertex = this.vertices.get(current); + if (!vertex) continue; + for (const dep of vertex.dependencies) { + if (!visited.has(dep)) { + stack.push(dep); + } + } + } + + return false; + } + // Time complexity: O(1), Space complexity: O(1) getFrontier(): Hash[] { return Array.from(this.frontier);