Skip to content

Commit

Permalink
fix: compare & merge bug GCounter & PNCounter (#73)
Browse files Browse the repository at this point in the history
Co-authored-by: Oak <[email protected]>
  • Loading branch information
joaopereira12 and d-roak authored Jul 30, 2024
1 parent e04bb30 commit 7ebcbd1
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 8 deletions.
14 changes: 6 additions & 8 deletions packages/crdt/src/builtins/GCounter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@ export class GCounter {
}

compare(peerCounter: GCounter): boolean {
for (let key in Object.keys(this.counts)) {
if (this.counts[key] > peerCounter.counts[key]) {
return false;
}
}
return true;
return (this.counts.length === peerCounter.counts.length && Object.keys(this.counts).every(key => this.counts[key] <= peerCounter.counts[key]));
}

merge(peerCounter: GCounter): void {
Expand All @@ -34,8 +29,11 @@ export class GCounter {
this.counts,
peerCounter.counts,
);

Object.keys(temp).forEach((key) => {
this.counts[key] = Math.max(this.counts[key], peerCounter.counts[key]);
this.counts[key] = Math.max(this.counts[key] || 0, peerCounter.counts[key] || 0);
});

this.globalCounter = Object.values(this.counts).reduce((a, b) => a + b, 0);
}
}
}
42 changes: 42 additions & 0 deletions packages/crdt/tests/GCounter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, test, expect, beforeEach } from "vitest";
import { GCounter } from "../src/builtins/GCounter";

describe("G-Counter Tests", () => {
let set1: GCounter;

beforeEach(() => {
set1 = new GCounter({ "node1": 5, "node2": 10});
});

test("Test Initial Values", () => {
expect(set1.value()).toBe(15);
});

test("Test Increment", () => {
set1.increment("node1", 10);
set1.increment("node2", 5);

expect(set1.value()).toBe(30);
});

test("Test Compare", () => {
let set2 = new GCounter({ "node1": 5, "node2": 10});
let set3 = new GCounter({ "node1": 5, "node2": 10, "node3": 15 });

expect(set1.compare(set2)).toBe(true);
set1.increment("node1", 5);
expect(set1.compare(set2)).toBe(false);
expect(set1.compare(set3)).toBe(false);
});

test("Test Merge", () => {
let set2 = new GCounter({ "node1": 3, "node2": 10});
let set3 = new GCounter({ "node1": 5, "node3": 15});

expect(set1.counts).toEqual({"node1": 5, "node2": 10});
set2.merge(set1);
expect(set2.counts).toEqual({"node1": 5, "node2": 10});
set1.merge(set3);
expect(set1.counts).toEqual({"node1": 5, "node2": 10, "node3": 15});
});
});
51 changes: 51 additions & 0 deletions packages/crdt/tests/PNCounter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { describe, test, expect, beforeEach, afterEach } from "vitest";
import { PNCounter } from "../src/builtins/PNCounter";
import { GCounter } from "../src/builtins/GCounter";

describe("PN-Counter Tests", () => {
let set1: PNCounter;
let set2: PNCounter;

beforeEach(() => {
set1 = new PNCounter(new GCounter({ "node1": 5, "node2": 10, "node3": 15 }), new GCounter({ "node1": 3, "node2": 4, "node3": 3 }));
set2 = new PNCounter(new GCounter({ "node1": 5, "node2": 10, "node3": 15 }), new GCounter({ "node1": 3, "node2": 4, "node3": 3 }));
});

test("Test Initial Value", () => {
expect(set1.value()).toBe(20);
expect(set2.value()).toBe(20);
});

test("Test Increment", () => {
set1.increment("node1",10);
set2.increment("node1",20);
expect(set1.value()).toBe(30);
expect(set2.value()).toBe(40);
});

test("Test Decrement", () => {
set1.decrement("node1",10);
set2.decrement("node1",20);
expect(set1.value()).toBe(10);
expect(set2.value()).toBe(0);
});

test("Test Compare", () => {
expect(set1.compare(set2)).toBe(true);
set1.decrement("node1",10);
expect(set1.compare(set2)).toBe(false);
set2.decrement("node1",10);
expect(set1.compare(set2)).toBe(true);
});

test("Test Merge", () => {
set1.increment("node1",10);
set2.decrement("node2",5);
expect(set1.compare(set2)).toBe(false);
expect(set2.compare(set1)).toBe(false);
set1.merge(set2);
set2.merge(set1);
expect(set1.compare(set2)).toBe(true);
expect(set2.compare(set1)).toBe(true);
});
});

0 comments on commit 7ebcbd1

Please sign in to comment.