Skip to content

Commit 249ee1d

Browse files
authored
Add 2P-Set (Two-Phase Set) for both addition and removal operations in distributed systems (TheAlgorithms#4977)
1 parent 36580ba commit 249ee1d

File tree

3 files changed

+155
-1
lines changed

3 files changed

+155
-1
lines changed

DIRECTORY.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
8787
* [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
8888
* [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
89+
* [TwoPSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java)
8990
* disjointsetunion
9091
* [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
9192
* [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
@@ -528,7 +529,7 @@
528529
* [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java)
529530
* [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/LargestRectangle.java)
530531
* [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
531-
* [NextGraterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGraterElement.java)
532+
* [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java)
532533
* [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
533534
* [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
534535
* [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
@@ -621,6 +622,7 @@
621622
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
622623
* [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
623624
* [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
625+
* [TwoPSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java)
624626
* disjointsetunion
625627
* [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
626628
* graphs
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.thealgorithms.datastructures.crdt;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
/**
7+
* TwoPhaseSet (2P-Set) is a state-based CRDT (Conflict-free Replicated Data Type) designed for managing sets
8+
* with support for both addition and removal operations in a distributed and concurrent environment.
9+
* It combines two G-Sets (grow-only sets) - one set for additions and another set (tombstone set) for removals.
10+
* Once an element is removed and placed in the tombstone set, it cannot be re-added, adhering to "remove-wins" semantics.
11+
* This implementation supports querying the presence of elements, adding elements, removing elements,
12+
* comparing with other 2P-Sets, and merging two 2P-Sets while preserving the remove-wins semantics.
13+
* (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
14+
*
15+
* @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
16+
*/
17+
18+
public class TwoPSet {
19+
private Set<String> setA;
20+
private Set<String> setR;
21+
22+
/**
23+
* Constructs an empty Two-Phase Set.
24+
*/
25+
public TwoPSet() {
26+
this.setA = new HashSet<>();
27+
this.setR = new HashSet<>();
28+
}
29+
30+
/**
31+
* Checks if an element is in the set and has not been removed.
32+
*
33+
* @param element The element to be checked.
34+
* @return True if the element is in the set and has not been removed, otherwise false.
35+
*/
36+
public boolean lookup(String element) {
37+
return setA.contains(element) && !setR.contains(element);
38+
}
39+
40+
/**
41+
* Adds an element to the set.
42+
*
43+
* @param element The element to be added.
44+
*/
45+
public void add(String element) {
46+
setA.add(element);
47+
}
48+
49+
/**
50+
* Removes an element from the set. The element will be placed in the tombstone set.
51+
*
52+
* @param element The element to be removed.
53+
*/
54+
public void remove(String element) {
55+
if (lookup(element)) {
56+
setR.add(element);
57+
}
58+
}
59+
60+
/**
61+
* Compares the current 2P-Set with another 2P-Set.
62+
*
63+
* @param otherSet The other 2P-Set to compare with.
64+
* @return True if both SetA and SetR are subset, otherwise false.
65+
*/
66+
public boolean compare(TwoPSet otherSet) {
67+
return otherSet.setA.containsAll(setA) && otherSet.setR.containsAll(setR);
68+
}
69+
70+
/**
71+
* Merges the current 2P-Set with another 2P-Set.
72+
*
73+
* @param otherSet The other 2P-Set to merge with.
74+
* @return A new 2P-Set containing the merged elements.
75+
*/
76+
public TwoPSet merge(TwoPSet otherSet) {
77+
TwoPSet mergedSet = new TwoPSet();
78+
mergedSet.setA.addAll(this.setA);
79+
mergedSet.setA.addAll(otherSet.setA);
80+
mergedSet.setR.addAll(this.setR);
81+
mergedSet.setR.addAll(otherSet.setR);
82+
return mergedSet;
83+
}
84+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.thealgorithms.datastructures.crdt;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.junit.jupiter.api.BeforeEach;
6+
import org.junit.jupiter.api.Test;
7+
8+
class TwoPSetTest {
9+
10+
private TwoPSet set;
11+
12+
@BeforeEach
13+
void setUp() {
14+
set = new TwoPSet();
15+
}
16+
17+
@Test
18+
void testLookup() {
19+
set.add("A");
20+
assertTrue(set.lookup("A"));
21+
assertFalse(set.lookup("B"));
22+
set.remove("A");
23+
assertFalse(set.lookup("A"));
24+
}
25+
26+
@Test
27+
void testAdd() {
28+
set.add("A");
29+
assertTrue(set.lookup("A"));
30+
}
31+
32+
@Test
33+
void testRemove() {
34+
set.add("A");
35+
set.remove("A");
36+
assertFalse(set.lookup("A"));
37+
}
38+
39+
@Test
40+
void testCompare() {
41+
TwoPSet set1 = new TwoPSet();
42+
set1.add("A");
43+
set1.add("B");
44+
TwoPSet set2 = new TwoPSet();
45+
set2.add("A");
46+
assertFalse(set1.compare(set2));
47+
set2.add("B");
48+
assertTrue(set1.compare(set2));
49+
set1.remove("A");
50+
assertFalse(set1.compare(set2));
51+
set2.remove("A");
52+
assertTrue(set1.compare(set2));
53+
}
54+
55+
@Test
56+
void testMerge() {
57+
TwoPSet set1 = new TwoPSet();
58+
set1.add("A");
59+
set1.add("B");
60+
TwoPSet set2 = new TwoPSet();
61+
set2.add("B");
62+
set2.add("C");
63+
TwoPSet mergedSet = set1.merge(set2);
64+
assertTrue(mergedSet.lookup("A"));
65+
assertTrue(mergedSet.lookup("B"));
66+
assertTrue(mergedSet.lookup("C"));
67+
}
68+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy