lattice/two_p_set
A two-phase set (2P-Set) CRDT.
Supports both add and remove, but an element can only be removed once. Once
removed (tombstoned), an element can never be re-added. Internally tracks
two sets: added and removed. An element is active if it is in added
but not in removed. Use ORSet if you need re-add after remove.
Example
import lattice/two_p_set
let set = two_p_set.new()
|> two_p_set.add("alice")
|> two_p_set.add("bob")
|> two_p_set.remove("bob")
two_p_set.contains(set, "alice") // -> True
two_p_set.contains(set, "bob") // -> False (tombstoned)
Types
A 2P-Set (two-phase set) CRDT.
Tracks two monotonically-growing sets: added (elements ever added) and
removed (elements ever tombstoned). An element is active only when it
is in added but not in removed. Tombstoning is permanent — once
removed, an element cannot be re-added to the active set.
pub type TwoPSet(a) {
TwoPSet(added: set.Set(a), removed: set.Set(a))
}
Constructors
Values
pub fn add(tpset: TwoPSet(a), element: a) -> TwoPSet(a)
Add an element to the set.
If the element has already been tombstoned (removed), this call records the
element in added but the element will not be considered active because
the tombstone takes precedence.
pub fn contains(tpset: TwoPSet(a), element: a) -> Bool
Check if the set currently contains the given element.
Returns True only if element is in added and NOT in removed.
pub fn from_json(
json_string: String,
) -> Result(TwoPSet(String), json.DecodeError)
Decode a TwoPSet(String) from a JSON string produced by to_json.
Returns Error if the string is not valid JSON or does not match the
expected format.
pub fn merge(a: TwoPSet(el), b: TwoPSet(el)) -> TwoPSet(el)
Merge two 2P-Sets by taking the union of both added sets and both removed sets.
A tombstone on any replica propagates to all replicas after merge. Merge is commutative, associative, and idempotent (a valid CRDT join).
pub fn remove(tpset: TwoPSet(a), element: a) -> TwoPSet(a)
Remove an element from the set by adding it to the tombstone set.
Once tombstoned, the element is permanently inactive. Removing an element that was never added is also valid and creates a preemptive tombstone.