14
14
*
15
15
* @param <T> The type of the elements in the LWWElementSet.
16
16
* @author <a href="https://github.com/itakurah">itakurah (GitHub)</a>, <a
17
- * href="https://www.linkedin.com/in/niklashoefflin/">Niklas Hoefflin (LinkedIn)</a>
17
+ * href="https://www.linkedin.com/in/niklashoefflin/">Niklas Hoefflin (LinkedIn)</a>
18
18
* @see <a href="https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type">Conflict free
19
- * replicated data type (Wikipedia)</a>
19
+ * replicated data type (Wikipedia)</a>
20
20
* @see <a href="https://inria.hal.science/inria-00555588v1/document">A comprehensive study of
21
- * Convergent and Commutative Replicated Data Types</a>
21
+ * Convergent and Commutative Replicated Data Types</a>
22
22
*/
23
23
class LWWElementSet <T > {
24
- final Map <T , Element <T >> addSet ;
25
- final Map <T , Element <T >> removeSet ;
24
+ final Map <T , Element <T >> addSet ;
25
+ final Map <T , Element <T >> removeSet ;
26
26
27
- /**
28
- * Constructs an empty LWWElementSet. This constructor initializes the addSet and removeSet as
29
- * empty HashMaps. The addSet stores elements that are added, and the removeSet stores elements
30
- * that are removed.
31
- */
32
- LWWElementSet () {
33
- this .addSet = new HashMap <>();
34
- this .removeSet = new HashMap <>();
35
- }
36
-
37
- /**
38
- * Adds an element to the addSet with the current timestamp. This method stores the element in the
39
- * addSet, ensuring that the element is added to the set with an associated timestamp that
40
- * represents the time of the addition.
41
- *
42
- * @param key The key of the element to be added.
43
- */
44
- public void add (T key ) {
45
- addSet .put (key , new Element <>(key , Instant .now ()));
46
- }
27
+ /**
28
+ * Constructs an empty LWWElementSet. This constructor initializes the addSet and removeSet as
29
+ * empty HashMaps. The addSet stores elements that are added, and the removeSet stores elements
30
+ * that are removed.
31
+ */
32
+ LWWElementSet () {
33
+ this .addSet = new HashMap <>();
34
+ this .removeSet = new HashMap <>();
35
+ }
47
36
48
- /**
49
- * Removes an element by adding it to the removeSet with the current timestamp. This method adds
50
- * the element to the removeSet, marking it as removed with the current timestamp.
51
- *
52
- * @param key The key of the element to be removed.
53
- */
54
- public void remove (T key ) {
55
- removeSet .put (key , new Element <>(key , Instant .now ()));
56
- }
37
+ /**
38
+ * Adds an element to the addSet with the current timestamp. This method stores the element in the
39
+ * addSet, ensuring that the element is added to the set with an associated timestamp that
40
+ * represents the time of the addition.
41
+ *
42
+ * @param key The key of the element to be added.
43
+ */
44
+ public void add (T key ) {
45
+ addSet .put (key , new Element <>(key , Instant .now ()));
46
+ }
57
47
58
- /**
59
- * Checks if an element is in the LWWElementSet. An element is considered present if it exists in
60
- * the addSet and either does not exist in the removeSet, or its add timestamp is later than any
61
- * corresponding remove timestamp.
62
- *
63
- * @param key The key of the element to be checked.
64
- * @return {@code true} if the element is present in the set (i.e., its add timestamp is later
65
- * than its remove timestamp, or it is not in the remove set), {@code false} otherwise (i.e.,
66
- * the element has been removed or its remove timestamp is later than its add timestamp).
67
- */
68
- public boolean lookup (T key ) {
69
- Element <T > inAddSet = addSet .get (key );
70
- Element <T > inRemoveSet = removeSet .get (key );
48
+ /**
49
+ * Removes an element by adding it to the removeSet with the current timestamp. This method adds
50
+ * the element to the removeSet, marking it as removed with the current timestamp.
51
+ *
52
+ * @param key The key of the element to be removed.
53
+ */
54
+ public void remove (T key ) {
55
+ removeSet .put (key , new Element <>(key , Instant .now ()));
56
+ }
71
57
72
- return inAddSet != null
73
- && (inRemoveSet == null || inAddSet .timestamp .isAfter (inRemoveSet .timestamp ));
74
- }
58
+ /**
59
+ * Checks if an element is in the LWWElementSet. An element is considered present if it exists in
60
+ * the addSet and either does not exist in the removeSet, or its add timestamp is later than any
61
+ * corresponding remove timestamp.
62
+ *
63
+ * @param key The key of the element to be checked.
64
+ * @return {@code true} if the element is present in the set (i.e., its add timestamp is later
65
+ * than its remove timestamp, or it is not in the remove set), {@code false} otherwise (i.e.,
66
+ * the element has been removed or its remove timestamp is later than its add timestamp).
67
+ */
68
+ public boolean lookup (T key ) {
69
+ Element <T > inAddSet = addSet .get (key );
70
+ Element <T > inRemoveSet = removeSet .get (key );
75
71
76
- /**
77
- * Merges another LWWElementSet into this set. This method takes the union of both the add-sets
78
- * and remove-sets from the two sets, resolving conflicts by keeping the element with the latest
79
- * timestamp. If an element appears in both the add-set and remove-set of both sets, the one with
80
- * the later timestamp will be retained.
81
- *
82
- * @param other The LWWElementSet to merge with the current set.
83
- */
84
- public void merge (LWWElementSet <T > other ) {
85
- for (Map .Entry <T , Element <T >> entry : other .addSet .entrySet ()) {
86
- addSet .merge (entry .getKey (), entry .getValue (), this ::resolveConflict );
72
+ return inAddSet != null
73
+ && (inRemoveSet == null || inAddSet .timestamp .isAfter (inRemoveSet .timestamp ));
87
74
}
88
- for (Map .Entry <T , Element <T >> entry : other .removeSet .entrySet ()) {
89
- removeSet .merge (entry .getKey (), entry .getValue (), this ::resolveConflict );
75
+
76
+ /**
77
+ * Merges another LWWElementSet into this set. This method takes the union of both the add-sets
78
+ * and remove-sets from the two sets, resolving conflicts by keeping the element with the latest
79
+ * timestamp. If an element appears in both the add-set and remove-set of both sets, the one with
80
+ * the later timestamp will be retained.
81
+ *
82
+ * @param other The LWWElementSet to merge with the current set.
83
+ */
84
+ public void merge (LWWElementSet <T > other ) {
85
+ for (Map .Entry <T , Element <T >> entry : other .addSet .entrySet ()) {
86
+ addSet .merge (entry .getKey (), entry .getValue (), this ::resolveConflict );
87
+ }
88
+ for (Map .Entry <T , Element <T >> entry : other .removeSet .entrySet ()) {
89
+ removeSet .merge (entry .getKey (), entry .getValue (), this ::resolveConflict );
90
+ }
90
91
}
91
- }
92
92
93
- /**
94
- * Resolves conflicts between two elements by selecting the one with the later timestamp. This
95
- * method is used when merging two LWWElementSets to ensure that the most recent operation (based
96
- * on timestamps) is kept.
97
- *
98
- * @param e1 The first element.
99
- * @param e2 The second element.
100
- * @return The element with the later timestamp.
101
- */
102
- private Element <T > resolveConflict (Element <T > e1 , Element <T > e2 ) {
103
- return e1 .timestamp .isAfter (e2 .timestamp ) ? e1 : e2 ;
104
- }
93
+ /**
94
+ * Resolves conflicts between two elements by selecting the one with the later timestamp. This
95
+ * method is used when merging two LWWElementSets to ensure that the most recent operation (based
96
+ * on timestamps) is kept.
97
+ *
98
+ * @param e1 The first element.
99
+ * @param e2 The second element.
100
+ * @return The element with the later timestamp.
101
+ */
102
+ private Element <T > resolveConflict (Element <T > e1 , Element <T > e2 ) {
103
+ return e1 .timestamp .isAfter (e2 .timestamp ) ? e1 : e2 ;
104
+ }
105
105
}
106
106
107
107
/**
@@ -111,17 +111,17 @@ private Element<T> resolveConflict(Element<T> e1, Element<T> e2) {
111
111
* @param <T> The type of the key associated with the element.
112
112
*/
113
113
class Element <T > {
114
- T key ;
115
- Instant timestamp ;
114
+ T key ;
115
+ Instant timestamp ;
116
116
117
- /**
118
- * Constructs a new Element with the specified key and timestamp.
119
- *
120
- * @param key The key of the element.
121
- * @param timestamp The timestamp associated with the element.
122
- */
123
- Element (T key , Instant timestamp ) {
124
- this .key = key ;
125
- this .timestamp = timestamp ;
126
- }
117
+ /**
118
+ * Constructs a new Element with the specified key and timestamp.
119
+ *
120
+ * @param key The key of the element.
121
+ * @param timestamp The timestamp associated with the element.
122
+ */
123
+ Element (T key , Instant timestamp ) {
124
+ this .key = key ;
125
+ this .timestamp = timestamp ;
126
+ }
127
127
}
0 commit comments