Class LinearizableAtomicLong

java.lang.Object
com.loomcache.server.cp.LinearizableAtomicLong

public final class LinearizableAtomicLong extends Object
Linearizable distributed atomic long with strong consistency via Raft.

Purpose: Unlike eventual-consistency models, this atomic long ensures all operations go through Raft consensus for linearizability. This means reads and writes are globally ordered and reflected consistently across the cluster.

Operations:

  • get() — read current value
  • set(value) — write new value
  • compareAndSet(expect, update) — atomic CAS operation
  • getAndIncrement() — return current, then increment
  • incrementAndGet() — increment, then return new value
  • addAndGet(delta) — add delta and return new value

Consistency Guarantee: All operations are linearizable. In case of cluster partitions, operations will block until the cluster heals or timeout expires.

Thread Safety: This class is thread-safe. Multiple threads can safely perform concurrent operations without synchronization.

Note: Each operation passes through Raft consensus, so performance is slower than local AtomicLong. Use this when consistency matters more than latency.

Since:
1.0
  • Constructor Details

    • LinearizableAtomicLong

      public LinearizableAtomicLong(String atomicName, long initialValue)
      Creates a new LinearizableAtomicLong with the given name and initial value.
      Parameters:
      atomicName - the name of this atomic long (must not be null or empty)
      initialValue - the initial value
      Throws:
      NullPointerException - if atomicName is null
      IllegalArgumentException - if atomicName is empty
  • Method Details

    • setRaftNode

      public void setRaftNode(@Nullable RaftNodeApi raftNode)
      Sets the Raft node for cluster-mode consensus replication.
      Parameters:
      raftNode - the RaftNode to route operations through (may be null to revert to standalone mode)
    • setReadRaftNode

      public void setReadRaftNode(@Nullable RaftNodeApi readRaftNode)
    • snapshotValue

      public long snapshotValue()
      Returns the local value without Raft consensus checks. Used by snapshot/restore operations where the state machine is already linearized.
      Returns:
      the current local value
    • get

      public long get()
      Gets the current value.

      In cluster mode, issues a linearizable read via raftNode.readIndex() to ensure the local state machine is caught up before returning the value. Falls back to a local read when no raftNode is configured.

      Returns:
      the current value
    • set

      public void set(long newValue)
      Sets the value to the given value.

      In cluster mode, the operation is replicated via Raft before applying locally.

      Parameters:
      newValue - the new value
    • set

      public void set(long newValue, String idempotencyClientId, String idempotencyRequestId)
    • set

      public void set(long newValue, @Nullable String senderId)
    • compareAndSet

      public boolean compareAndSet(long expect, long update)
      Atomically sets the value to the given value if the current value equals the expected value.
      Parameters:
      expect - the expected current value
      update - the new value to set if the expectation is met
      Returns:
      true if the update succeeded, false if the current value did not equal expect
    • compareAndSet

      public boolean compareAndSet(long expect, long update, String idempotencyClientId, String idempotencyRequestId)
    • compareAndSet

      public boolean compareAndSet(long expect, long update, @Nullable String senderId)
    • getAndIncrement

      public long getAndIncrement()
      Atomically gets the current value and increments by 1.

      Example: if current value is 5, returns 5 and sets value to 6.

      Returns:
      the previous value
    • getAndIncrement

      public long getAndIncrement(String idempotencyClientId, String idempotencyRequestId)
    • getAndIncrement

      public long getAndIncrement(@Nullable String senderId)
    • incrementAndGet

      public long incrementAndGet()
      Atomically increments by 1 and returns the new value.

      Example: if current value is 5, increments to 6 and returns 6.

      Returns:
      the new value after incrementing
    • incrementAndGet

      public long incrementAndGet(String idempotencyClientId, String idempotencyRequestId)
    • incrementAndGet

      public long incrementAndGet(@Nullable String senderId)
    • decrementAndGet

      public long decrementAndGet()
      Atomically decrements by 1 and returns the new value.
      Returns:
      the new value after decrementing
    • decrementAndGet

      public long decrementAndGet(String idempotencyClientId, String idempotencyRequestId)
    • decrementAndGet

      public long decrementAndGet(@Nullable String senderId)
    • getAndDecrement

      public long getAndDecrement()
      Atomically gets the current value and decrements by 1.
      Returns:
      the previous value before decrement
    • getAndDecrement

      public long getAndDecrement(String idempotencyClientId, String idempotencyRequestId)
    • getAndDecrement

      public long getAndDecrement(@Nullable String senderId)
    • addAndGet

      public long addAndGet(long delta)
      Atomically adds the given value and returns the new total.
      Parameters:
      delta - the value to add (can be negative)
      Returns:
      the new value after adding delta
    • addAndGet

      public long addAndGet(long delta, String idempotencyClientId, String idempotencyRequestId)
    • addAndGet

      public long addAndGet(long delta, @Nullable String senderId)
    • getAndAdd

      public long getAndAdd(long delta)
      Atomically gets the current value and adds the given value.
      Parameters:
      delta - the value to add (can be negative)
      Returns:
      the previous value before adding delta
    • getAndAdd

      public long getAndAdd(long delta, String idempotencyClientId, String idempotencyRequestId)
    • getAndAdd

      public long getAndAdd(long delta, @Nullable String senderId)
    • intValue

      public int intValue()
      Returns the current value as an int.
      Returns:
      the current value cast to int
    • longValue

      public long longValue()
      Returns the current value as a long.
      Returns:
      the current value
    • floatValue

      public float floatValue()
      Returns the current value as a float.
      Returns:
      the current value cast to float
    • doubleValue

      public double doubleValue()
      Returns the current value as a double.
      Returns:
      the current value cast to double
    • applyCommand

      public Object applyCommand(byte[] command)
      Applies a Raft-committed command to the local state machine. Called by the Raft state-machine apply callback when a log entry is committed.
      Parameters:
      command - the serialized command bytes
      Returns:
      the result of the operation (Long for numeric ops, Boolean for CAS)