macula_crdt (macula v0.14.3)
View SourceConflict-Free Replicated Data Types (CRDTs) for shared state.
Implements CRDTs for eventually-consistent distributed state management: - LWW-Register (Last-Write-Wins Register) - single value with timestamp - OR-Set (Observed-Remove Set) - set with add/remove semantics - G-Counter (Grow-only Counter) - monotonically increasing counter - PN-Counter (Positive-Negative Counter) - increment/decrement counter
These CRDTs replace Ra/Raft consensus for Macula's masterless architecture. State is synchronized via gossip protocol between nodes.
Summary
Functions
Increment the G-Counter by 1 for current node
Increment the G-Counter by N for current node
Merge two G-Counters (take max of each node's count)
Get the total value of the G-Counter
Get the current value of the LWW-Register
Merge two LWW-Registers Keeps the value with the highest timestamp Ties broken by node name (lexicographic order)
Set a value in the LWW-Register with timestamp
Get the timestamp of the LWW-Register
Get the value of the LWW-Register (alias for lww_get)
Create a new G-Counter
Create a new empty LWW-Register
Create a new LWW-Register with initial value
Create a new empty OR-Set
Create a new PN-Counter
Add an element to the OR-Set (auto-generates unique tag)
Add an element to the OR-Set with a specific tag
Check if element is in the OR-Set
Get all elements in the OR-Set
Merge two OR-Sets Union of elements, union of tombstones
Remove an element from the OR-Set Removes all current tags for that element (add-wins semantics)
Get the number of elements in the OR-Set
Decrement the PN-Counter by 1
Decrement the PN-Counter by N
Increment the PN-Counter by 1
Increment the PN-Counter by N
Merge two PN-Counters
Get the value of the PN-Counter (positive - negative)
Types
-type gcounter() :: #{node() => non_neg_integer()}.
-type or_set() :: #{elements => #{term() => sets:set(unique_tag())}, tombstones => sets:set(unique_tag())}.
-type timestamp() :: non_neg_integer().
-type unique_tag() :: binary().
Functions
Increment the G-Counter by 1 for current node
-spec gcounter_increment(gcounter(), pos_integer()) -> gcounter().
Increment the G-Counter by N for current node
Merge two G-Counters (take max of each node's count)
-spec gcounter_value(gcounter()) -> non_neg_integer().
Get the total value of the G-Counter
-spec lww_get(lww_register()) -> term().
Get the current value of the LWW-Register
-spec lww_merge(lww_register(), lww_register()) -> lww_register().
Merge two LWW-Registers Keeps the value with the highest timestamp Ties broken by node name (lexicographic order)
-spec lww_set(lww_register(), term(), timestamp()) -> lww_register().
Set a value in the LWW-Register with timestamp
-spec lww_timestamp(lww_register()) -> timestamp().
Get the timestamp of the LWW-Register
-spec lww_value(lww_register()) -> term().
Get the value of the LWW-Register (alias for lww_get)
-spec new_gcounter() -> gcounter().
Create a new G-Counter
-spec new_lww_register() -> lww_register().
Create a new empty LWW-Register
-spec new_lww_register(term()) -> lww_register().
Create a new LWW-Register with initial value
-spec new_or_set() -> or_set().
Create a new empty OR-Set
-spec new_pncounter() -> pncounter().
Create a new PN-Counter
Add an element to the OR-Set (auto-generates unique tag)
-spec or_add(or_set(), term(), unique_tag()) -> or_set().
Add an element to the OR-Set with a specific tag
Check if element is in the OR-Set
Get all elements in the OR-Set
Merge two OR-Sets Union of elements, union of tombstones
Remove an element from the OR-Set Removes all current tags for that element (add-wins semantics)
-spec or_size(or_set()) -> non_neg_integer().
Get the number of elements in the OR-Set
Decrement the PN-Counter by 1
-spec pncounter_decrement(pncounter(), pos_integer()) -> pncounter().
Decrement the PN-Counter by N
Increment the PN-Counter by 1
-spec pncounter_increment(pncounter(), pos_integer()) -> pncounter().
Increment the PN-Counter by N
Merge two PN-Counters
Get the value of the PN-Counter (positive - negative)