Class LWWRegister<V>

java.lang.Object
com.loomcache.server.datastructures.crdt.LWWRegister<V>

public class LWWRegister<V> extends Object
Last-Writer-Wins Register CRDT (LWW-Register).

An LWW-Register is a state-based CRDT that represents a register (single value) where the last write (by timestamp) is the value returned. In case of timestamp ties, the node ID is used as a tiebreaker (lexicographic ordering).

Key properties:

  • Stores a single value with a timestamp
  • Merge: higher timestamp wins
  • Ties broken by node ID (lexicographic)
  • Always produces a deterministic result
  • Convergent: all nodes reach the same state given the same history
Since:
1.3
  • Constructor Summary

    Constructors
    Constructor
    Description
    LWWRegister(@NonNull String name, @NonNull String nodeId, int instanceNumber)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    @Nullable V
    get()
    Get the current value in the register.
    long
    Get the timestamp of the current value.
    @Nullable String
    Get the node ID that wrote the current value.
    boolean
    Returns true once the register has observed at least one write.
    void
    Merge another LWW-Register into this one (anti-entropy).
    void
    Reset is NOT supported for LWW-Registers.
    void
    restoreFromSnapshot(@Nullable V value, long timestamp, @Nullable String writerId)
    Restore a register from a persisted snapshot.
    void
    set(V value)
    Set the value in the register.
    void
    setReplicated(@Nullable V value, long timestamp, @NonNull String writerId)
    Apply an already-stamped value from the replicated state-machine log.
    Export the current register state for Raft snapshot persistence.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • LWWRegister

      public LWWRegister(@NonNull String name, @NonNull String nodeId, int instanceNumber)
  • Method Details

    • set

      public void set(V value)
      Set the value in the register. The timestamp is set to the current time, and the writer ID is this node.
      Parameters:
      value - the value to set
    • setReplicated

      public void setReplicated(@Nullable V value, long timestamp, @NonNull String writerId)
      Apply an already-stamped value from the replicated state-machine log.

      Raft log order is authoritative for the wire path; the leader stamps a deterministic timestamp/writer pair before submission so every replica applies identical register state. Anti-entropy conflict resolution remains in merge(LWWRegister).

      Parameters:
      value - the serialized value to store, including null clears
      timestamp - the leader-stamped timestamp, must be positive
      writerId - the leader node id that stamped the value
    • get

      public @Nullable V get()
      Get the current value in the register.
      Returns:
      the current value (null if no value has been set)
    • getTimestamp

      public long getTimestamp()
      Get the timestamp of the current value.
      Returns:
      the timestamp in milliseconds since epoch
    • isSet

      public boolean isSet()
      Returns true once the register has observed at least one write.

      This distinguishes a pristine register from an explicit set(null) write, which has a positive timestamp and null value.

    • getWriterId

      public @Nullable String getWriterId()
      Get the node ID that wrote the current value.
      Returns:
      the writer node ID (null if no value has been set)
    • toSnapshot

      public HashMap<String,Object> toSnapshot()
      Export the current register state for Raft snapshot persistence.
    • restoreFromSnapshot

      public void restoreFromSnapshot(@Nullable V value, long timestamp, @Nullable String writerId)
      Restore a register from a persisted snapshot.
    • merge

      public void merge(LWWRegister<V> other)
      Merge another LWW-Register into this one (anti-entropy). The value with the higher timestamp wins. If timestamps are equal, the value from the lexicographically larger node ID wins. Merge is idempotent and commutative.
      Parameters:
      other - the other LWW-Register to merge
      Throws:
      IllegalArgumentException - if names don't match
    • reset

      public void reset()
      Reset is NOT supported for LWW-Registers. Setting timestamp to 0 makes the reset older than any previously replicated value; the next merge will silently restore the pre-reset value.
      Throws:
      UnsupportedOperationException - always — reset violates CRDT merge invariants