diff --git a/packages/object/src/hashgraph/index.ts b/packages/object/src/hashgraph/index.ts index f0c3edc7b..1d0524f9f 100644 --- a/packages/object/src/hashgraph/index.ts +++ b/packages/object/src/hashgraph/index.ts @@ -166,16 +166,20 @@ export class HashGraph { dfsTopologicalSortIterative(origin: Hash, subgraph: ObjectSet): Hash[] { const visited = new ObjectSet(); - const result: Hash[] = []; - const stack: Hash[] = [origin]; + const result: Hash[] = Array(subgraph.size); + const stack: Hash[] = Array(subgraph.size); const processing = new ObjectSet(); + let resultIndex = subgraph.size - 1; + let stackIndex = 0; + stack[stackIndex] = origin; - while (stack.length > 0) { - const node = stack[stack.length - 1]; + while (resultIndex >= 0) { + const node = stack[stackIndex]; if (visited.has(node)) { - stack.pop(); - result.push(node); + result[resultIndex] = node; + stackIndex--; + resultIndex--; processing.delete(node); continue; } @@ -188,13 +192,14 @@ export class HashGraph { for (const neighbor of neighbors.sort()) { if (processing.has(neighbor)) throw new Error("Graph contains a cycle!"); if (subgraph.has(neighbor) && !visited.has(neighbor)) { - stack.push(neighbor); + stackIndex++; + stack[stackIndex] = neighbor; } } } } - return result.reverse(); + return result; } /* Topologically sort the vertices in the whole hashgraph or the past of a given vertex. */ diff --git a/packages/object/src/linearize/pairSemantics.ts b/packages/object/src/linearize/pairSemantics.ts index 9c3d3066c..7e18f747e 100644 --- a/packages/object/src/linearize/pairSemantics.ts +++ b/packages/object/src/linearize/pairSemantics.ts @@ -58,6 +58,5 @@ export function linearizePairSemantics( } } } - return result; } diff --git a/packages/object/src/utils/objectSet.ts b/packages/object/src/utils/objectSet.ts index cd11095b9..ce70bdf9e 100644 --- a/packages/object/src/utils/objectSet.ts +++ b/packages/object/src/utils/objectSet.ts @@ -1,19 +1,28 @@ export class ObjectSet { set: { [key in T]: boolean }; + size: number; constructor(iterable: Iterable = []) { this.set = {} as { [key in T]: boolean }; + this.size = 0; for (const item of iterable) { this.set[item] = true; + this.size++; } } add(item: T): void { + if (this.has(item)) return; + this.set[item] = true; + this.size++; } delete(item: T): void { + if (!this.has(item)) return; + delete this.set[item]; + this.size--; } has(item: T): boolean { diff --git a/packages/object/tests/actiontypes.test.ts b/packages/object/tests/actiontypes.test.ts index bf798d8d7..939023b35 100644 --- a/packages/object/tests/actiontypes.test.ts +++ b/packages/object/tests/actiontypes.test.ts @@ -89,7 +89,6 @@ describe("Test: ActionTypes (Nop and Swap)", () => { addMul.add(5); drp.merge(drp2.vertices); drp2.merge(drp.vertices); - addMul.mul(5); addMul.add(5); addMul2.add(5); @@ -99,8 +98,11 @@ describe("Test: ActionTypes (Nop and Swap)", () => { expect(addMul2.query_value()).toBe(75); addMul2.mul(2); + vi.setSystemTime(new Date(Date.UTC(1998, 11, 24))); addMul2.add(2); + vi.setSystemTime(new Date(Date.UTC(1998, 11, 25))); addMul.add(3); + vi.setSystemTime(new Date(Date.UTC(1998, 11, 26))); addMul.mul(3); drp.merge(drp2.vertices); drp2.merge(drp.vertices);