-
Notifications
You must be signed in to change notification settings - Fork 20k
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
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 0236655
clang format
itakurah 0cb6011
clang format
itakurah 1d0717d
clang format
itakurah e8b51c9
clang format
itakurah 55078e4
clang format
itakurah 0da8bad
clang format
itakurah f0d8192
added JUnit tests
itakurah 262648d
clang format
itakurah 4a8864b
clang format
itakurah 37be803
clang format
itakurah 78f0a96
clang format
itakurah 0162767
clang format
itakurah 54196ba
clang format
itakurah 9ce77b0
clang format
itakurah 9399d24
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 3b4e6d6
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 3f1b5ab
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 54745a4
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 7ca5cba
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 8af1152
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 3dce6ee
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 76ee92b
removed compareTo
itakurah bb6dbca
renamed member fields
itakurah e7ea4e1
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah b41c3a1
changed constructor
itakurah 40b5b25
updated test cases
itakurah 5c34f3b
clang format
itakurah a62ef7e
added GCounter for tracking counts in a distributed and concurrent en…
itakurah c748099
added GCounter for tracking counts in a distributed and concurrent en…
itakurah 623be46
clang format
itakurah 9a3587d
clang format
itakurah 92ce6b1
clang format
itakurah f59213e
clang format
itakurah 1c1f78c
clang format
itakurah fa96251
clang format
itakurah f275ed1
clang format
itakurah f2d9a93
clang format
itakurah 1c14657
clang format
itakurah bcf8dbe
clang format
itakurah d0cae1f
clang format
itakurah 5496ffc
clang format
itakurah 8543d83
clang format
itakurah 0e6e7de
clang format
itakurah bd04ed7
added test cases for vertices and edges
itakurah 2a16c18
clang format
itakurah 277b823
clang format
itakurah f6c71dd
Merge branch 'master' into master
vil02 b67ef33
Merge remote-tracking branch 'origin/crdt'
itakurah ac8d8df
added separate methods for logic
itakurah d191a27
added new test cases
itakurah fc11ba7
Merge remote-tracking branch 'origin/master'
itakurah 45803d0
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 0aa71e8
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 1e3b255
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah f905321
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 8f41341
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 5aaec56
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 7fef71d
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 7b230f6
refactor
itakurah c47a7e9
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 7b9fd37
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah ed3ad77
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah cd07ca6
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 0989353
Update src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 268eb89
refactor
itakurah 9471b29
refactor
itakurah 8b81224
Merge branch 'TheAlgorithms:master' into pncounter
itakurah 2cf09c6
added computeTotalWeight() and some refactoring
itakurah e0637b6
refactor
itakurah 81ca459
clang format
itakurah 8f59ab8
Merge branch 'master' into master
vil02 9897ddc
refactor
itakurah 5c37c5c
refactor
itakurah d380a0c
Update directory
3a23e3d
clang format
itakurah 708b8f0
Merge remote-tracking branch 'origin/master'
itakurah be3eb66
clang format
itakurah 05241ca
clang format
itakurah df7314a
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah c47c59a
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah b2757b5
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah 48001bf
Update src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaA…
itakurah bdab7cb
refactor
itakurah 63a53d7
refactor
itakurah 61f80ad
refactor
itakurah 0821de0
refactor
itakurah d9dcead
refactor
itakurah 73b22d1
refactor
itakurah 1cd65fe
refactor
itakurah 1b90810
refactor
itakurah eec8d1b
Merge branch 'TheAlgorithms:master' into crdt
itakurah 30aa66e
Merge branch 'pncounter'
itakurah dfc9f3a
Merge remote-tracking branch 'origin/master'
itakurah aba0e75
Merge remote-tracking branch 'origin/crdt'
itakurah 03d5dce
Merge remote-tracking branch 'origin/pncounter' into pncounter
itakurah f706fe8
added PN-Counter
itakurah 3afb28e
added PN-Counter tests
itakurah edd511a
Update directory
f8b3c55
clang format
itakurah 88ac39b
Update directory
c418184
clang format
itakurah 03377e2
clang format
itakurah af7d944
clang format
itakurah 0a72e19
Merge branch 'master' into pn
itakurah b3976bc
Merge remote-tracking branch 'origin/pncounter' into pn
itakurah dba8296
Update src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.…
itakurah 4db306e
added checks for different node size of counters when comparing and m…
itakurah 58ad1b9
Merge remote-tracking branch 'origin/pn' into pn
itakurah b0076f3
spelling
itakurah File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))); | ||
} | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.