E
- implementation storing the data for sharing during exchange or parallel coordination of an event.public abstract class RingBuffer<E> extends java.lang.Object implements java.util.function.LongSupplier, Backpressurable
Modifier and Type | Field and Description |
---|---|
static java.util.function.Supplier |
EMITTED |
static long |
INITIAL_CURSOR_VALUE
Set to -1 as sequence starting point
|
Constructor and Description |
---|
RingBuffer() |
Modifier and Type | Method and Description |
---|---|
abstract void |
addGatingSequence(Sequence gatingSequence)
Add the specified gating sequence to this instance of the Disruptor.
|
static <T> java.util.Queue<T> |
blockingBoundedQueue(RingBuffer<Slot<T>> buffer,
long startSequence)
|
static <E> RingBuffer<Slot<E>> |
createMultiProducer(int bufferSize)
Create a new multiple producer RingBuffer using the default wait strategy
WaitStrategy.busySpin() . |
static <E> RingBuffer<E> |
createMultiProducer(java.util.function.Supplier<E> factory,
int bufferSize,
WaitStrategy waitStrategy)
Create a new multiple producer RingBuffer with the specified wait strategy.
|
static <E> RingBuffer<E> |
createMultiProducer(java.util.function.Supplier<E> factory,
int bufferSize,
WaitStrategy waitStrategy,
java.lang.Runnable spinObserver)
Create a new multiple producer RingBuffer with the specified wait strategy.
|
static java.lang.Runnable |
createRequestTask(org.reactivestreams.Subscription upstream,
java.lang.Runnable stopCondition,
java.util.function.Consumer<java.lang.Long> postWaitCallback,
java.util.function.LongSupplier readCount,
WaitStrategy waitStrategy,
org.reactivestreams.Subscriber<?> errorSubscriber,
int prefetch)
Create a
Runnable event loop that will keep monitoring a LongSupplier and compare it to a RingBuffer |
static <E> RingBuffer<Slot<E>> |
createSingleProducer(int bufferSize)
Create a new single producer RingBuffer using the default wait strategy
WaitStrategy.busySpin() . |
static <E> RingBuffer<E> |
createSingleProducer(java.util.function.Supplier<E> factory,
int bufferSize)
Create a new single producer RingBuffer using the default wait strategy
WaitStrategy.busySpin() . |
static <E> RingBuffer<E> |
createSingleProducer(java.util.function.Supplier<E> factory,
int bufferSize,
WaitStrategy waitStrategy)
Create a new single producer RingBuffer with the specified wait strategy.
|
static <E> RingBuffer<E> |
createSingleProducer(java.util.function.Supplier<E> factory,
int bufferSize,
WaitStrategy waitStrategy,
java.lang.Runnable spinObserver)
Create a new single producer RingBuffer with the specified wait strategy.
|
abstract E |
get(long sequence)
Get the event for a given sequence in the RingBuffer.
|
long |
getAsLong() |
abstract long |
getCursor()
Get the current cursor value for the ring buffer.
|
abstract long |
getMinimumGatingSequence()
Get the minimum sequence value from all of the gating sequences added to this ringBuffer.
|
abstract long |
getMinimumGatingSequence(Sequence sequence)
Get the minimum sequence value from all of the gating sequences added to this ringBuffer.
|
static long |
getMinimumSequence(Sequence[] sequences,
long minimum)
Get the minimum sequence from an array of
Sequence s. |
static long |
getMinimumSequence(Sequence excludeSequence,
Sequence[] sequences,
long minimum)
Get the minimum sequence from an array of
Sequence s. |
abstract Sequence |
getSequence()
Get the current cursor value for the ring buffer.
|
Sequence[] |
getSequenceReceivers() |
static int |
log2(int i)
Calculate the log base 2 of the supplied integer, essentially reports the location of the highest bit.
|
abstract RingBufferReceiver |
newBarrier()
Create a new
RingBufferReceiver to be used by an EventProcessor to track which messages are available to be read
from the ring buffer given a list of sequences to track. |
static Sequence |
newSequence(long init) |
abstract long |
next()
Increment and return the next sequence for the ring buffer.
|
abstract long |
next(int n)
The same functionality as
next() , but allows the caller to claim the next n sequences. |
static <T> java.util.Queue<T> |
nonBlockingBoundedQueue(RingBuffer<Slot<T>> buffer,
long startSequence)
|
static <E> void |
onNext(E value,
RingBuffer<Slot<E>> ringBuffer)
Signal a new
Slot value to a RingBuffer typed with them. |
abstract void |
publish(long sequence)
Publish the specified sequence.
|
abstract void |
publish(long lo,
long hi)
Publish the specified sequences.
|
abstract long |
remainingCapacity()
Get the remaining capacity for this ringBuffer.
|
abstract boolean |
removeGatingSequence(Sequence sequence)
Remove the specified sequence from this ringBuffer.
|
abstract void |
resetTo(long sequence)
Resets the cursor to a specific value.
|
java.lang.String |
toString() |
abstract long |
tryNext()
Increment and return the next sequence for the ring buffer.
|
abstract long |
tryNext(int n)
The same functionality as
tryNext() , but allows the caller to attempt to claim the next n
sequences. |
static boolean |
waitRequestOrTerminalEvent(java.util.function.LongSupplier pendingRequest,
RingBufferReceiver barrier,
java.util.concurrent.atomic.AtomicBoolean isRunning,
java.util.function.LongSupplier nextSequence,
java.lang.Runnable waiter)
Spin CPU until the request
LongSupplier is populated at least once by a strict positive value. |
static Sequence |
wrap(long init,
java.lang.Object delegate)
Wrap a new sequence into a traceable
Producer thus keeping reference and adding an extra stack level
when
peeking. |
static Sequence |
wrap(Sequence init,
java.lang.Object delegate)
Wrap a sequence into a traceable
Producer thus keeping reference and adding an extra stack level when
peeking. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getCapacity, getPending
public static final java.util.function.Supplier EMITTED
public static final long INITIAL_CURSOR_VALUE
public static java.lang.Runnable createRequestTask(org.reactivestreams.Subscription upstream, java.lang.Runnable stopCondition, java.util.function.Consumer<java.lang.Long> postWaitCallback, java.util.function.LongSupplier readCount, WaitStrategy waitStrategy, org.reactivestreams.Subscriber<?> errorSubscriber, int prefetch)
Runnable
event loop that will keep monitoring a LongSupplier
and compare it to a RingBuffer
upstream
- the Subscription
to request/cancel onstopCondition
- Runnable
evaluated in the spin loop that may throwpostWaitCallback
- a Consumer
notified with the latest sequence readreadCount
- a LongSupplier
a sequence cursor to wait onwaitStrategy
- a WaitStrategy
to trade off cpu cycle for latencyerrorSubscriber
- an error subscriber if request/cancel failsprefetch
- the target prefetch sizeRunnable
loop to execute to start the requesting looppublic static <E> RingBuffer<Slot<E>> createMultiProducer(int bufferSize)
WaitStrategy.busySpin()
.
See MultiProducer
.
E
- the element typebufferSize
- number of elements to create within the ring buffer.java.lang.IllegalArgumentException
- if bufferSize is less than 1 or not a power of 2public static <E> RingBuffer<E> createMultiProducer(java.util.function.Supplier<E> factory, int bufferSize, WaitStrategy waitStrategy)
See MultiProducer
.
E
- the element typefactory
- used to create the events within the ring buffer.bufferSize
- number of elements to create within the ring buffer.waitStrategy
- used to determine how to wait for new elements to become available.public static <E> RingBuffer<E> createMultiProducer(java.util.function.Supplier<E> factory, int bufferSize, WaitStrategy waitStrategy, java.lang.Runnable spinObserver)
See MultiProducer
.
E
- the element typefactory
- used to create the events within the ring buffer.bufferSize
- number of elements to create within the ring buffer.waitStrategy
- used to determine how to wait for new elements to become available.spinObserver
- the Runnable to call on a spin loop waitpublic static <T> java.util.Queue<T> nonBlockingBoundedQueue(RingBuffer<Slot<T>> buffer, long startSequence)
Queue
view over the given RingBuffer
of Slot
.
The read cursor will be added to the gating sequences and will be incremented on polling.
Offer will return false if the tryNext()
does not succeed.T
- the Slot
data content typebuffer
- the RingBuffer
repositorystartSequence
- the starting sequence to track in the Queue
Queue
view of the given RingBuffer
public static <T> java.util.Queue<T> blockingBoundedQueue(RingBuffer<Slot<T>> buffer, long startSequence)
Queue
view over the given RingBuffer
of Slot
.
The read cursor will be added to the gating sequences and will be incremented on polling.
Offer will spin on next()
if the ringbuffer is overrun.T
- the Slot
data content typebuffer
- the RingBuffer
repositorystartSequence
- the starting sequence to track in the Queue
Queue
view of the given RingBuffer
public static <E> RingBuffer<Slot<E>> createSingleProducer(int bufferSize)
WaitStrategy.busySpin()
.
See MultiProducer
.
E
- the element typebufferSize
- number of elements to create within the ring buffer.public static <E> RingBuffer<E> createSingleProducer(java.util.function.Supplier<E> factory, int bufferSize)
WaitStrategy.busySpin()
.
See MultiProducer
.
E
- the element typefactory
- used to create the events within the ring buffer.bufferSize
- number of elements to create within the ring buffer.public static <E> RingBuffer<E> createSingleProducer(java.util.function.Supplier<E> factory, int bufferSize, WaitStrategy waitStrategy)
See MultiProducer
.
E
- the element typefactory
- used to create the events within the ring buffer.bufferSize
- number of elements to create within the ring buffer.waitStrategy
- used to determine how to wait for new elements to become available.public static <E> RingBuffer<E> createSingleProducer(java.util.function.Supplier<E> factory, int bufferSize, WaitStrategy waitStrategy, java.lang.Runnable spinObserver)
See MultiProducer
.
E
- the element typefactory
- used to create the events within the ring buffer.bufferSize
- number of elements to create within the ring buffer.waitStrategy
- used to determine how to wait for new elements to become available.spinObserver
- called each time the next claim is spinning and waiting for a slotpublic static long getMinimumSequence(Sequence[] sequences, long minimum)
Sequence
s.sequences
- to compare.minimum
- an initial default minimum. If the array is empty this value will be returned.public static long getMinimumSequence(Sequence excludeSequence, Sequence[] sequences, long minimum)
Sequence
s.excludeSequence
- to exclude from search.sequences
- to compare.minimum
- an initial default minimum. If the array is empty this value will be returned.public static int log2(int i)
i
- Value to calculate log2 for.public static Sequence newSequence(long init)
init
- the initial valuepublic static <E> void onNext(E value, RingBuffer<Slot<E>> ringBuffer)
Slot
value to a RingBuffer
typed with them.E
- the Slot
reified typevalue
- the data to storeringBuffer
- the target RingBuffer
of Slot
public static boolean waitRequestOrTerminalEvent(java.util.function.LongSupplier pendingRequest, RingBufferReceiver barrier, java.util.concurrent.atomic.AtomicBoolean isRunning, java.util.function.LongSupplier nextSequence, java.lang.Runnable waiter)
LongSupplier
is populated at least once by a strict positive value.
To relieve the spin loop, the read sequence itself will be used against so it will wake up only when a signal
is emitted upstream or other stopping condition including terminal signals thrown by the
RingBufferReceiver
waiting barrier.pendingRequest
- the LongSupplier
request to observebarrier
- RingBufferReceiver
to wait onisRunning
- AtomicBoolean
calling loop running statenextSequence
- LongSupplier
ring buffer read cursorwaiter
- an optional extra spin observer for the wait strategy in RingBufferReceiver
public static Sequence wrap(long init, java.lang.Object delegate)
Producer
thus keeping reference and adding an extra stack level
when
peeking. Mostly invisible cost but the option is left open. Keeping reference of the arbitrary consumer allows
expanded operational navigation (graph) by finding all target subscribers of a given ring buffer.init
- the initial sequence indexdelegate
- the target to proxySequence
public static Sequence wrap(Sequence init, java.lang.Object delegate)
Producer
thus keeping reference and adding an extra stack level when
peeking. Mostly invisible cost but the option is left open.init
- the sequence referencedelegate
- the object to wrapSequence
public abstract void addGatingSequence(Sequence gatingSequence)
gatingSequence
- The sequences to add.public abstract E get(long sequence)
Get the event for a given sequence in the RingBuffer.
This call has 2 uses. Firstly use this call when publishing to a ring buffer. After calling next()
use this call to get hold of the preallocated event to fill with data before calling publish(long)
.
Secondly use this call when consuming data from the ring buffer. After calling RingBufferReceiver.waitFor(long)
call this method with any value greater than that your current consumer sequence
and less than or equal to the value returned from the RingBufferReceiver.waitFor(long)
method.
sequence
- for the eventpublic long getAsLong()
getAsLong
in interface java.util.function.LongSupplier
public abstract long getCursor()
RingBufferProducer
that is being used.
See MultiProducer
.
See SingleProducerSequencer
public abstract long getMinimumGatingSequence()
public abstract long getMinimumGatingSequence(Sequence sequence)
sequence
- the target sequencepublic abstract Sequence getSequence()
RingBufferProducer
that is being used.
See MultiProducer
.
See SingleProducerSequencer
.
public Sequence[] getSequenceReceivers()
public abstract RingBufferReceiver newBarrier()
RingBufferReceiver
to be used by an EventProcessor to track which messages are available to be read
from the ring buffer given a list of sequences to track.RingBufferReceiver
public abstract long next()
long sequence = ringBuffer.next(); try { Event e = ringBuffer.get(sequence); // Do some work with the event. } finally { ringBuffer.publish(sequence); }
publish(long)
,
get(long)
public abstract long next(int n)
next()
, but allows the caller to claim the next n sequences.
See RingBufferProducer.next(int)
n
- number of slots to claimpublic abstract void publish(long sequence)
sequence
- the sequence to publish.public abstract void publish(long lo, long hi)
See RingBufferProducer.next(int)
lo
- the lowest sequence number to be publishedhi
- the highest sequence number to be publishedpublic abstract long remainingCapacity()
public abstract boolean removeGatingSequence(Sequence sequence)
sequence
- to be removed.public abstract void resetTo(long sequence)
sequence
- The sequence to reset too.java.lang.IllegalStateException
- If any gating sequences have already been specified.public java.lang.String toString()
toString
in class java.lang.Object
public abstract long tryNext() throws Exceptions.InsufficientCapacityException
Increment and return the next sequence for the ring buffer. Calls of this method should ensure that they always publish the sequence afterward. E.g.
long sequence = ringBuffer.next(); try { Event e = ringBuffer.get(sequence); // Do some work with the event. } finally { ringBuffer.publish(sequence); }
This method will not block if there is not space available in the ring buffer, instead it will throw a RuntimeException
.
Exceptions.InsufficientCapacityException
- if the necessary space in the ring buffer is not availablepublish(long)
,
get(long)
public abstract long tryNext(int n) throws Exceptions.InsufficientCapacityException
tryNext()
, but allows the caller to attempt to claim the next n
sequences.n
- number of slots to claimExceptions.InsufficientCapacityException
- if the necessary space in the ring buffer is not available