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 java.lang.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-bitStriped64
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 int
ATTEMPTS
The maximum number of attempts when trying to expand the table.(package private) static int
MAXIMUM_TABLE_SIZE
The bound on the table size.(package private) static int
NCPU
Number of CPUS.(package private) static long
PROBE
(package private) Buffer<E>[]
table
Table of buffers.(package private) static long
TABLE_BUSY
(package private) int
tableBusy
Spinlock (locked via CAS) used when resizing and/or creating Buffers.
-
Constructor Summary
Constructors Constructor Description StripedBuffer()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description (package private) static int
advanceProbe(int probe)
Pseudo-randomly advances and records the given probe value for the given thread.(package private) boolean
casTableBusy()
CASes the tableBusy field from 0 to 1 to acquire lock.(package private) static int
ceilingNextPowerOfTwo(int x)
Returns the closest power-of-two at or higher than the given value.protected abstract Buffer<E>
create(E e)
Creates a new buffer instance after resizing to accommodate a producer.void
drainTo(java.util.function.Consumer<E> consumer)
Drains the buffer, sending each element to the consumer for processing.(package private) void
expandOrRetry(E e, boolean wasUncontended)
Handles cases of updates involving initialization, resizing, creating new Buffers, and/or contention.(package private) static int
getProbe()
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
reads()
Returns the number of elements that have been read from the buffer.int
writes()
Returns the number of elements that have been written to the buffer.
-
-
-
Field Detail
-
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:
- Constant Field Values
-
tableBusy
transient volatile int tableBusy
Spinlock (locked via CAS) used when resizing and/or creating Buffers.
-
-
Method Detail
-
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.
-
ceilingNextPowerOfTwo
static int ceilingNextPowerOfTwo(int x)
Returns the closest power-of-two at or higher than the given value.
-
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.
-
drainTo
public void drainTo(java.util.function.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.
-
reads
public int reads()
Description copied from interface:Buffer
Returns the number of elements that have been read from the buffer.
-
writes
public int writes()
Description copied from interface:Buffer
Returns the number of elements that have been written to the 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 addwasUncontended
- false if CAS failed before call
-
-