Grove.Register.LWWRegister (Grove v0.1.1)
View SourceA Last-Write-Wins Register (LWW-Register) CRDT.
Each update is tagged with a Lamport timestamp. On merge, the value with the highest timestamp wins. Ties are broken by comparing actor IDs.
Important
Uses Lamport timestamps (logical clocks), NOT wall-clock time. This ensures correctness even with clock skew between nodes.
Delta-State Support
This CRDT supports delta-state replication. Note that for LWWRegister, the delta is the full register state since merge needs all metadata. The delta buffer tracks whether any local changes have been made.
delta/1- Returns the register state if modified, or empty state if notreset_delta/1- Clears the dirty flag after synchronization
Example
iex> reg = Grove.Register.LWWRegister.new(:node_a)
iex> reg = Grove.Register.LWWRegister.set(reg, "hello")
iex> Grove.Register.LWWRegister.value(reg)
"hello"
Summary
Functions
Returns the accumulated delta since the last reset.
Merges two LWW-Registers.
Creates a new LWW-Register for the given actor.
Resets the delta buffer after synchronization.
Sets the value of the register.
Sets the value with an explicit timestamp.
Returns the current timestamp.
Returns the current value of the register.
Types
@type actor() :: term()
@type t() :: %Grove.Register.LWWRegister{ actor: actor(), delta_dirty: boolean(), timestamp: non_neg_integer(), value: term() }
Functions
Returns the accumulated delta since the last reset.
For LWWRegister, the delta is the full register state if any changes were made locally, or an empty register (timestamp 0) if not.
Merges two LWW-Registers.
The value with the higher timestamp wins. Ties are broken by comparing actor IDs, then values (higher wins).
Note: The actor field represents the origin of the current value, not the replica doing the merge. This is essential for associativity.
Creates a new LWW-Register for the given actor.
Resets the delta buffer after synchronization.
Call this after sending the delta to other replicas.
Sets the value of the register.
Automatically increments the timestamp.
@spec set(t(), term(), non_neg_integer()) :: t()
Sets the value with an explicit timestamp.
Use this when applying remote operations.
@spec timestamp(t()) :: non_neg_integer()
Returns the current timestamp.
Returns the current value of the register.