From 8010bb352f3f4e2515b8578d0cdee71c948e14ce Mon Sep 17 00:00:00 2001 From: hoangquocvietuet Date: Fri, 1 Nov 2024 09:14:43 +0700 Subject: [PATCH] feat: add dropped array, find next function in bitset --- packages/object/src/hashgraph/bitset.ts | 18 +++++ .../object/src/linearize/pairSemantics.ts | 33 +++++--- packages/object/tests/hashgraph.test.ts | 76 +++++++++---------- 3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/packages/object/src/hashgraph/bitset.ts b/packages/object/src/hashgraph/bitset.ts index 0af35c9e..e729512a 100644 --- a/packages/object/src/hashgraph/bitset.ts +++ b/packages/object/src/hashgraph/bitset.ts @@ -81,4 +81,22 @@ export class BitSet { .map((int) => int.toString(2).padStart(32, "0")) .join(""); } + + findNext(index: number, bit: number): number { + let byteIndex = (index / 32) | 0; + let bitIndex = index % 32; + let mask = 1 << bitIndex; + while (byteIndex < this.data.length) { + while (bitIndex < 32) { + if ((this.data[byteIndex] & mask) === bit) + return byteIndex * 32 + bitIndex; + mask <<= 1; + bitIndex++; + } + byteIndex++; + bitIndex = 0; + mask = 1; + } + return -1; + } } diff --git a/packages/object/src/linearize/pairSemantics.ts b/packages/object/src/linearize/pairSemantics.ts index f86c6379..39378fab 100644 --- a/packages/object/src/linearize/pairSemantics.ts +++ b/packages/object/src/linearize/pairSemantics.ts @@ -6,15 +6,24 @@ import { export function linearizePair(hashGraph: HashGraph): Operation[] { const order = hashGraph.topologicalSort(true); + const dropped = new Array(order.length).fill(false); const result: Operation[] = []; let i = 0; while (i < order.length) { + if (dropped[i]) { + i++; + continue; + } const anchor = order[i]; let j = i + 1; - let shouldIncrementI = true; while (j < order.length) { + if (dropped[i]) break; + if (dropped[j]) { + j++; + continue; + } const moving = order[j]; if (!hashGraph.areCausallyRelatedUsingBitsets(anchor, moving)) { @@ -29,16 +38,14 @@ export function linearizePair(hashGraph: HashGraph): Operation[] { switch (action) { case ActionType.DropLeft: - order.splice(i, 1); - j = order.length; // Break out of inner loop - shouldIncrementI = false; - continue; // Continue outer loop without incrementing i + dropped[i] = true; + break; case ActionType.DropRight: - order.splice(j, 1); - continue; // Continue with the same j + dropped[j] = true; + break; case ActionType.Swap: [order[i], order[j]] = [order[j], order[i]]; - j = order.length; // Break out of inner loop + j = i + 1; break; case ActionType.Nop: j++; @@ -48,12 +55,14 @@ export function linearizePair(hashGraph: HashGraph): Operation[] { j++; } } - - if (shouldIncrementI) { - const op = hashGraph.vertices.get(order[i])?.operation; - if (op && op.value !== null) result.push(op); + if (dropped[i]) { i++; + continue; } + + const op = hashGraph.vertices.get(order[i])?.operation; + if (op && op.value !== null) result.push(op); + i++; } return result; diff --git a/packages/object/tests/hashgraph.test.ts b/packages/object/tests/hashgraph.test.ts index b1fde2f6..c3a12eb4 100644 --- a/packages/object/tests/hashgraph.test.ts +++ b/packages/object/tests/hashgraph.test.ts @@ -16,8 +16,8 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Add Two Vertices", () => { /* - V1:NOP <- V2:ADD(1) <- V2:REMOVE(1) - */ + V1:NOP <- V2:ADD(1) <- V2:REMOVE(1) + */ const cro1 = obj1.cro as AddWinsSet; cro1.add(1); @@ -33,10 +33,10 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Add Two Concurrent Vertices With Same Value", () => { /* - _ V2:REMOVE(1) - V1:ADD(1) / - \ _ V3:ADD(1) - */ + _ V2:REMOVE(1) + V1:ADD(1) / + \ _ V3:ADD(1) + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet; @@ -61,10 +61,10 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Add Two Concurrent Vertices With Different Values", () => { /* - _ V2:REMOVE(1) - V1:ADD(1) / - \ _ V3:ADD(2) - */ + _ V2:REMOVE(1) + V1:ADD(1) / + \ _ V3:ADD(2) + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet; @@ -91,10 +91,10 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Tricky Case", () => { /* - ___ V2:REMOVE(1) <- V4:ADD(10) - V1:ADD(1) / - \ ___ V3:ADD(1) <- V5:REMOVE(5) - */ + ___ V2:REMOVE(1) <- V4:ADD(10) + V1:ADD(1) / + \ ___ V3:ADD(1) <- V5:REMOVE(5) + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet; @@ -125,10 +125,10 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Yuta Papa's Case", () => { /* - ___ V2:REMOVE(1) <- V4:ADD(2) - V1:ADD(1) / - \ ___ V3:REMOVE(2) <- V5:ADD(1) - */ + ___ V2:REMOVE(1) <- V4:ADD(2) + V1:ADD(1) / + \ ___ V3:REMOVE(2) <- V5:ADD(1) + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet; @@ -157,14 +157,14 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Mega Complex Case", () => { /* - __ V6:ADD(3) - / - ___ V2:ADD(1) <-- V3:RM(2) <-- V7:RM(1) <-- V8:RM(3) - / ______________/ - V1:ADD(1)/ / - \ / - \ ___ V4:RM(2) <-- V5:ADD(2) <-- V9:RM(1) - */ + __ V6:ADD(3) + / + ___ V2:ADD(1) <-- V3:RM(2) <-- V7:RM(1) <-- V8:RM(3) + / ______________/ + V1:ADD(1)/ / + \ / + \ ___ V4:RM(2) <-- V5:ADD(2) <-- V9:RM(1) + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet; @@ -212,14 +212,14 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Mega Complex Case 1", () => { /* - __ V5:ADD(3) - / - ___ V2:ADD(1) <-- V3:RM(2) <-- V6:RM(1) <-- V8:RM(3) - / ^ - V1:ADD(1)/ \ - \ \ - \ ___ V4:RM(2) <-------------------- V7:ADD(2) <-- V9:RM(1) - */ + __ V5:ADD(3) + / + ___ V2:ADD(1) <-- V3:RM(2) <-- V6:RM(1) <-- V8:RM(3) + / ^ + V1:ADD(1)/ \ + \ \ + \ ___ V4:RM(2) <-------------------- V7:ADD(2) <-- V9:RM(1) + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet; @@ -269,10 +269,10 @@ describe("HashGraph for AddWinSet tests", () => { test("Test: Joao's latest brain teaser", () => { /* - __ V2:Add(2) <------------\ - V1:Add(1) / \ - V5:RM(2) - \__ V3:RM(2) <- V4:RM(2) <--/ - */ + __ V2:Add(2) <------------\ + V1:Add(1) / \ - V5:RM(2) + \__ V3:RM(2) <- V4:RM(2) <--/ + */ const cro1 = obj1.cro as AddWinsSet; const cro2 = obj2.cro as AddWinsSet;