Class DistributedList<E>

java.lang.Object
com.loomcache.server.datastructures.DistributedList<E>
Type Parameters:
E - the type of elements in this list

public class DistributedList<E> extends Object
Distributed ordered list with configurable consistency mode.

Supports two consistency modes selected at creation time:

  • CP (default) — Operations go through Raft log, providing linearizable reads and writes. All nodes see the same order of operations.
  • AP — Operations use primary-backup replication, providing faster performance at the cost of eventual consistency.

Both modes provide:

  • Thread-safe concurrent access
  • Standard List API: add, get, set, remove, contains, indexOf, size
  • Efficient subList views
  • Stream support and iteration safety
  • Listener callbacks for change events

Large-list access. The bulk-materializing APIs — toSnapshot(), toArray(), stream(), and forEach(Consumer) — refuse to run past MAX_SNAPSHOT_ITEMS and throw IllegalStateException. Callers that need to read lists larger than that must use the paginated accessors: page(int, int) reads a bounded slice, and forEachPage(int, Consumer) iterates every element page-at-a-time without ever materializing the full list in memory. The Raft/persistence path uses snapshotForPersistence(), which is unbounded by design.

The consistency mode is immutable after creation and determines how the replication layer handles operations on this list instance.

Since:
1.2
  • Field Details

  • Constructor Details

    • DistributedList

      public DistributedList(String name, int instanceNumber)
      Create a DistributedList with the given name and default CP consistency mode.
      Parameters:
      name - the name of the list (must not be null)
      instanceNumber - the node instance number
      Throws:
      NullPointerException - if name is null
    • DistributedList

      public DistributedList(String name, int instanceNumber, DistributedList.ConsistencyMode consistencyMode)
      Create a DistributedList with the given name and consistency mode.
      Parameters:
      name - the name of the list (must not be null)
      instanceNumber - the node instance number
      consistencyMode - the consistency mode (CP or AP, must not be null)
      Throws:
      NullPointerException - if name or consistencyMode is null
  • Method Details

    • isLinearizable

      public boolean isLinearizable()
      Returns whether this list operates in linearizable (CP) mode.
      Returns:
      true if the list uses Raft consensus for linearizable operations, false if it uses primary-backup (AP) replication
    • add

      public boolean add(E element)
      Add an element to the end of the list. In CP mode, requires Raft consensus. In AP mode, uses primary-backup replication.
      Returns:
      true if added successfully
    • add

      public void add(int index, E element)
      Add an element at a specific index. In CP mode, requires Raft consensus. In AP mode, uses primary-backup replication.
    • addAll

      public boolean addAll(Collection<? extends E> elements)
      Add all elements from a collection. In CP mode, requires Raft consensus. In AP mode, uses primary-backup replication.
      Returns:
      true if any elements were added
    • get

      public E get(int index)
      Get element at index. In CP mode, requires Raft consistency check (no local-only reads). In AP mode, reads from local primary copy.
    • set

      public E set(int index, E element)
      Set element at index. In CP mode, requires Raft consensus. In AP mode, uses primary-backup replication.
      Returns:
      the previous element at that index
    • remove

      public E remove(int index)
      Remove element at index. In CP mode, requires Raft consensus. In AP mode, uses primary-backup replication.
      Returns:
      the removed element
    • remove

      public boolean remove(@Nullable E o)
      Remove the first occurrence of an element. In CP mode, requires Raft consensus. In AP mode, uses primary-backup replication.
      Parameters:
      o - the element to remove (may be null)
      Returns:
      true if element was removed
    • contains

      public boolean contains(@Nullable E o)
      Check if list contains an element.
    • indexOf

      public int indexOf(@Nullable E o)
      Get the index of the first occurrence of an element.
      Returns:
      index, or -1 if not found
    • lastIndexOf

      public int lastIndexOf(@Nullable E o)
      Get the index of the last occurrence of an element.
      Returns:
      index, or -1 if not found
    • size

      public int size()
      Get the size of the list.
    • isEmpty

      public boolean isEmpty()
      Check if the list is empty.
    • clear

      public void clear()
      Clear all elements from the list.
    • subList

      public List<E> subList(int fromIndex, int toIndex)
      Get an immutable copy of a sublist range (from inclusive, to exclusive).
    • toSnapshot

      public ArrayList<E> toSnapshot()
      Get an atomic snapshot of the list as an ArrayList, bounded by MAX_SNAPSHOT_ITEMS. Used by the registry for Raft snapshot serialization.
    • toArray

      public Object[] toArray()
      Get an array representation of the list.
    • stream

      public Stream<E> stream()
      Get a stream over the list elements.
    • snapshotForPersistence

      public List<E> snapshotForPersistence()
      Unbounded snapshot intended solely for Raft/state-machine persistence. Bypasses MAX_SNAPSHOT_ITEMS because the snapshot path must faithfully capture the full list state regardless of size; user-facing snapshot/stream/iter APIs remain capped.
    • forEach

      public void forEach(Consumer<E> action)
      Iterate over a bounded snapshot of the current elements and apply an action.
    • page

      public List<E> page(int offset, int pageSize)
      Read a page of elements without materializing the whole list.

      Intended for lists above MAX_SNAPSHOT_ITEMS where toSnapshot() / stream() / forEach(Consumer) refuse to run.

      Parameters:
      offset - starting index (0-based, inclusive); clamped to size
      pageSize - page size (must be positive and ≤ MAX_SNAPSHOT_ITEMS)
      Returns:
      an immutable list containing at most pageSize elements
      Throws:
      IllegalArgumentException - if offset is negative or pageSize is non-positive or greater than MAX_SNAPSHOT_ITEMS
    • forEachPage

      public void forEachPage(int pageSize, Consumer<List<E>> action)
      Iterate over the entire list in bounded pages, applying action to each page.

      Uses page-at-a-time reads so arbitrarily large lists can be consumed without violating MAX_SNAPSHOT_ITEMS. The traversal pins the backing sequence once at the start so concurrent writes do not shift page boundaries.

      Parameters:
      pageSize - page size (must be positive and ≤ MAX_SNAPSHOT_ITEMS)
      action - callback invoked once per page (never invoked with an empty page)
      Throws:
      IllegalArgumentException - if pageSize is non-positive or > MAX_SNAPSHOT_ITEMS
      NullPointerException - if action is null
    • addListener

      public void addListener(DistributedList.ListListener<E> listener)
      Add a listener for change events.
    • removeListener

      public void removeListener(DistributedList.ListListener<E> listener)
      Remove a listener.
    • getTotalAdds

      public long getTotalAdds()
    • getTotalRemoves

      public long getTotalRemoves()
    • getTotalSets

      public long getTotalSets()
    • getPeakSize

      public long getPeakSize()
    • toString

      public String toString()
      Overrides:
      toString in class Object