Class StripedBuffer<E>

java.lang.Object
com.github.benmanes.caffeine.cache.StripedBuffer<E>
All Implemented Interfaces:
Buffer<E>
Direct Known Subclasses:
BoundedBuffer

abstract class StripedBuffer<E> extends Object implements Buffer<E>
A base class providing the mechanics for supporting dynamic striping of bounded buffers. This implementation is an adaption of the numeric 64-bit Striped64 class, which is used by atomic counters. The approach was modified to lazily grow an array of buffers in order to minimize memory usage for caches that are not heavily contended on.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) static final int
    The maximum number of attempts when trying to expand the table.
    (package private) static final int
    The bound on the table size.
    (package private) static final int
    Number of CPUS.
    (package private) static final long
     
    (package private) Buffer<E> @Nullable []
    Table of buffers.
    (package private) static final long
     
    (package private) int
    Spinlock (locked via CAS) used when resizing and/or creating Buffers.

    Fields inherited from interface com.github.benmanes.caffeine.cache.Buffer

    FAILED, FULL, SUCCESS
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) static final int
    advanceProbe(int probe)
    Pseudo-randomly advances and records the given probe value for the given thread.
    (package private) final boolean
    CASes the tableBusy field from 0 to 1 to acquire lock.
    protected abstract Buffer<E>
    create(E e)
    Creates a new buffer instance after resizing to accommodate a producer.
    void
    drainTo(Consumer<E> consumer)
    Drains the buffer, sending each element to the consumer for processing.
    (package private) final void
    expandOrRetry(E e, boolean wasUncontended)
    Handles cases of updates involving initialization, resizing, creating new Buffers, and/or contention.
    (package private) static final int
    Returns the probe value for the current thread.
    int
    offer(E e)
    Inserts the specified element into this buffer if it is possible to do so immediately without violating capacity restrictions.
    int
    Returns the number of elements that have been read from the buffer.
    int
    Returns the number of elements that have been written to the buffer.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface com.github.benmanes.caffeine.cache.Buffer

    size
  • Field Details

    • TABLE_BUSY

      static final long TABLE_BUSY
    • PROBE

      static final long PROBE
    • NCPU

      static final int NCPU
      Number of CPUS.
    • MAXIMUM_TABLE_SIZE

      static final int MAXIMUM_TABLE_SIZE
      The bound on the table size.
    • ATTEMPTS

      static final int ATTEMPTS
      The maximum number of attempts when trying to expand the table.
      See Also:
    • table

      transient volatile Buffer<E> @Nullable [] table
      Table of buffers. When non-null, size is a power of 2.
    • tableBusy

      transient volatile int tableBusy
      Spinlock (locked via CAS) used when resizing and/or creating Buffers.
  • Constructor Details

    • StripedBuffer

      StripedBuffer()
  • Method Details

    • casTableBusy

      final boolean casTableBusy()
      CASes the tableBusy field from 0 to 1 to acquire lock.
    • getProbe

      static final int getProbe()
      Returns the probe value for the current thread. Duplicated from ThreadLocalRandom because of packaging restrictions.
    • advanceProbe

      static final int advanceProbe(int probe)
      Pseudo-randomly advances and records the given probe value for the given thread. Duplicated from ThreadLocalRandom because of packaging restrictions.
    • create

      protected abstract Buffer<E> create(E e)
      Creates a new buffer instance after resizing to accommodate a producer.
      Parameters:
      e - the producer's element
      Returns:
      a newly created buffer populated with a single element
    • offer

      public int offer(E e)
      Description copied from interface: Buffer
      Inserts the specified element into this buffer if it is possible to do so immediately without violating capacity restrictions. The addition is allowed to fail spuriously if multiple threads insert concurrently.
      Specified by:
      offer in interface Buffer<E>
      Parameters:
      e - the element to add
      Returns:
      1 if the buffer is full, -1 if the CAS failed, or 0 if added
    • drainTo

      public void drainTo(Consumer<E> consumer)
      Description copied from interface: Buffer
      Drains the buffer, sending each element to the consumer for processing. The caller must ensure that a consumer has exclusive read access to the buffer.
      Specified by:
      drainTo in interface Buffer<E>
      Parameters:
      consumer - the action to perform on each element
    • reads

      public int reads()
      Description copied from interface: Buffer
      Returns the number of elements that have been read from the buffer.
      Specified by:
      reads in interface Buffer<E>
      Returns:
      the number of elements read from this buffer
    • writes

      public int writes()
      Description copied from interface: Buffer
      Returns the number of elements that have been written to the buffer.
      Specified by:
      writes in interface Buffer<E>
      Returns:
      the number of elements written to this buffer
    • expandOrRetry

      final void expandOrRetry(E e, boolean wasUncontended)
      Handles cases of updates involving initialization, resizing, creating new Buffers, and/or contention. See above for explanation. This method suffers the usual non-modularity problems of optimistic retry code, relying on rechecked sets of reads.
      Parameters:
      e - the element to add
      wasUncontended - false if CAS failed before call