Skip to content

Added PN-Counter (Positive-Negative Counter) for tracking counts in distributed systems #4974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 110 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
d1d2da9
added Boruvka's algorithm to find Minimum Spanning Tree
itakurah Nov 19, 2023
0236655
clang format
itakurah Nov 19, 2023
0cb6011
clang format
itakurah Nov 19, 2023
1d0717d
clang format
itakurah Nov 19, 2023
e8b51c9
clang format
itakurah Nov 19, 2023
55078e4
clang format
itakurah Nov 22, 2023
0da8bad
clang format
itakurah Nov 22, 2023
f0d8192
added JUnit tests
itakurah Nov 22, 2023
262648d
clang format
itakurah Nov 22, 2023
4a8864b
clang format
itakurah Nov 22, 2023
37be803
clang format
itakurah Nov 22, 2023
78f0a96
clang format
itakurah Nov 22, 2023
0162767
clang format
itakurah Nov 22, 2023
54196ba
clang format
itakurah Nov 22, 2023
9ce77b0
clang format
itakurah Nov 22, 2023
9399d24
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
3b4e6d6
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
3f1b5ab
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
54745a4
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
7ca5cba
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
8af1152
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
3dce6ee
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
76ee92b
removed compareTo
itakurah Nov 22, 2023
bb6dbca
renamed member fields
itakurah Nov 22, 2023
e7ea4e1
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 22, 2023
b41c3a1
changed constructor
itakurah Nov 23, 2023
40b5b25
updated test cases
itakurah Nov 23, 2023
5c34f3b
clang format
itakurah Nov 23, 2023
a62ef7e
added GCounter for tracking counts in a distributed and concurrent en…
itakurah Nov 23, 2023
c748099
added GCounter for tracking counts in a distributed and concurrent en…
itakurah Nov 23, 2023
623be46
clang format
itakurah Nov 23, 2023
9a3587d
clang format
itakurah Nov 23, 2023
92ce6b1
clang format
itakurah Nov 23, 2023
f59213e
clang format
itakurah Nov 23, 2023
1c1f78c
clang format
itakurah Nov 23, 2023
fa96251
clang format
itakurah Nov 23, 2023
f275ed1
clang format
itakurah Nov 23, 2023
f2d9a93
clang format
itakurah Nov 23, 2023
1c14657
clang format
itakurah Nov 23, 2023
bcf8dbe
clang format
itakurah Nov 23, 2023
d0cae1f
clang format
itakurah Nov 23, 2023
5496ffc
clang format
itakurah Nov 23, 2023
8543d83
clang format
itakurah Nov 23, 2023
0e6e7de
clang format
itakurah Nov 24, 2023
bd04ed7
added test cases for vertices and edges
itakurah Nov 24, 2023
2a16c18
clang format
itakurah Nov 24, 2023
277b823
clang format
itakurah Nov 24, 2023
f6c71dd
Merge branch 'master' into master
vil02 Nov 26, 2023
b67ef33
Merge remote-tracking branch 'origin/crdt'
itakurah Nov 27, 2023
ac8d8df
added separate methods for logic
itakurah Nov 27, 2023
d191a27
added new test cases
itakurah Nov 27, 2023
fc11ba7
Merge remote-tracking branch 'origin/master'
itakurah Nov 27, 2023
45803d0
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
0aa71e8
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
1e3b255
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
f905321
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
8f41341
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
5aaec56
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
7fef71d
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
7b230f6
refactor
itakurah Nov 27, 2023
c47a7e9
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
7b9fd37
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
ed3ad77
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
cd07ca6
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
0989353
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 27, 2023
268eb89
refactor
itakurah Nov 27, 2023
9471b29
refactor
itakurah Nov 27, 2023
8b81224
Merge branch 'TheAlgorithms:master' into pncounter
itakurah Nov 28, 2023
2cf09c6
added computeTotalWeight() and some refactoring
itakurah Nov 28, 2023
e0637b6
refactor
itakurah Nov 28, 2023
81ca459
clang format
itakurah Nov 28, 2023
8f59ab8
Merge branch 'master' into master
vil02 Nov 28, 2023
9897ddc
refactor
itakurah Nov 29, 2023
5c37c5c
refactor
itakurah Nov 29, 2023
d380a0c
Update directory
Nov 29, 2023
3a23e3d
clang format
itakurah Nov 29, 2023
708b8f0
Merge remote-tracking branch 'origin/master'
itakurah Nov 29, 2023
be3eb66
clang format
itakurah Nov 29, 2023
05241ca
clang format
itakurah Nov 29, 2023
df7314a
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 29, 2023
c47c59a
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 29, 2023
b2757b5
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 29, 2023
48001bf
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah Nov 29, 2023
bdab7cb
refactor
itakurah Nov 29, 2023
63a53d7
refactor
itakurah Nov 29, 2023
61f80ad
refactor
itakurah Nov 29, 2023
0821de0
refactor
itakurah Nov 29, 2023
d9dcead
refactor
itakurah Nov 29, 2023
73b22d1
refactor
itakurah Nov 29, 2023
1cd65fe
refactor
itakurah Nov 29, 2023
1b90810
refactor
itakurah Nov 30, 2023
eec8d1b
Merge branch 'TheAlgorithms:master' into crdt
itakurah Dec 2, 2023
30aa66e
Merge branch 'pncounter'
itakurah Dec 2, 2023
dfc9f3a
Merge remote-tracking branch 'origin/master'
itakurah Dec 2, 2023
aba0e75
Merge remote-tracking branch 'origin/crdt'
itakurah Dec 2, 2023
03d5dce
Merge remote-tracking branch 'origin/pncounter' into pncounter
itakurah Dec 2, 2023
f706fe8
added PN-Counter
itakurah Dec 2, 2023
3afb28e
added PN-Counter tests
itakurah Dec 2, 2023
edd511a
Update directory
Dec 2, 2023
f8b3c55
clang format
itakurah Dec 2, 2023
88ac39b
Update directory
Dec 2, 2023
c418184
clang format
itakurah Dec 2, 2023
03377e2
clang format
itakurah Dec 2, 2023
af7d944
clang format
itakurah Dec 2, 2023
0a72e19
Merge branch 'master' into pn
itakurah Dec 3, 2023
b3976bc
Merge remote-tracking branch 'origin/pncounter' into pn
itakurah Dec 3, 2023
dba8296
Update src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.…
itakurah Dec 3, 2023
4db306e
added checks for different node size of counters when comparing and m…
itakurah Dec 3, 2023
58ad1b9
Merge remote-tracking branch 'origin/pn' into pn
itakurah Dec 3, 2023
b0076f3
spelling
itakurah Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
* [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
* crdt
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
* [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
* disjointsetunion
* [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
* [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
Expand Down Expand Up @@ -617,6 +618,7 @@
* [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
* crdt
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
* [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
* disjointsetunion
* [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
* graphs
Expand Down
100 changes: 100 additions & 0 deletions src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.thealgorithms.datastructures.crdt;

import java.util.HashMap;
import java.util.Map;

/**
* PN-Counter (Positive-Negative Counter) is a state-based CRDT (Conflict-free Replicated Data Type)
* designed for tracking counts with both increments and decrements in a distributed and concurrent environment.
* It combines two G-Counters, one for increments (P) and one for decrements (N).
* The total count is obtained by subtracting the value of the decrement counter from the increment counter.
* This implementation supports incrementing, decrementing, querying the total count,
* comparing with other PN-Counters, and merging with another PN-Counter
* to compute the element-wise maximum for both increment and decrement counters.
* (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
*
* @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
*/

class PNCounter {
private final Map<Integer, Integer> P;
private final Map<Integer, Integer> N;
private final int myId;
private final int n;

/**
* Constructs a PN-Counter for a cluster of n nodes.
*
* @param myId The identifier of the current node.
* @param n The number of nodes in the cluster.
*/
public PNCounter(int myId, int n) {
this.myId = myId;
this.n = n;
this.P = new HashMap<>();
this.N = new HashMap<>();

for (int i = 0; i < n; i++) {
P.put(i, 0);
N.put(i, 0);
}
}

/**
* Increments the increment counter for the current node.
*/
public void increment() {
P.put(myId, P.get(myId) + 1);
}

/**
* Increments the decrement counter for the current node.
*/
public void decrement() {
N.put(myId, N.get(myId) + 1);
}

/**
* Gets the total value of the counter by subtracting the decrement counter from the increment counter.
*
* @return The total value of the counter.
*/
public int value() {
int sumP = P.values().stream().mapToInt(Integer::intValue).sum();
int sumN = N.values().stream().mapToInt(Integer::intValue).sum();
return sumP - sumN;
}

/**
* Compares the state of this PN-Counter with another PN-Counter.
*
* @param other The other PN-Counter to compare with.
* @return True if the state of this PN-Counter is less than or equal to the state of the other PN-Counter.
*/
public boolean compare(PNCounter other) {
if (this.n != other.n) {
throw new IllegalArgumentException("Cannot compare PN-Counters with different number of nodes");
}
for (int i = 0; i < n; i++) {
if (this.P.get(i) > other.P.get(i) && this.N.get(i) > other.N.get(i)) {
return false;
}
}
return true;
}

/**
* Merges the state of this PN-Counter with another PN-Counter.
*
* @param other The other PN-Counter to merge with.
*/
public void merge(PNCounter other) {
if (this.n != other.n) {
throw new IllegalArgumentException("Cannot merge PN-Counters with different number of nodes");
}
for (int i = 0; i < n; i++) {
this.P.put(i, Math.max(this.P.get(i), other.P.get(i)));
this.N.put(i, Math.max(this.N.get(i), other.N.get(i)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.thealgorithms.datastructures.crdt;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

public class PNCounterTest {

@Test
public void testIncrement() {
PNCounter counter = new PNCounter(0, 3);
counter.increment();
assertEquals(1, counter.value());
}

@Test
public void testDecrement() {
PNCounter counter = new PNCounter(0, 3);
counter.decrement();
assertEquals(-1, counter.value());
}

@Test
public void testIncrementAndDecrement() {
PNCounter counter = new PNCounter(0, 3);
counter.increment();
counter.increment();
counter.decrement();
assertEquals(1, counter.value());
}

@Test
public void testCompare() {
PNCounter counter1 = new PNCounter(0, 3);
counter1.increment();
PNCounter counter2 = new PNCounter(1, 3);
assertTrue(counter1.compare(counter2));
counter2.increment();
assertTrue(counter2.compare(counter1));
counter1.decrement();
assertFalse(counter1.compare(counter2));
}

@Test
public void testMerge() {
PNCounter counter1 = new PNCounter(0, 3);
counter1.increment();
counter1.increment();
PNCounter counter2 = new PNCounter(1, 3);
counter2.increment();
counter1.merge(counter2);
assertEquals(3, counter1.value());
}
}