Class RingBuffer<T>
- Namespace
- MarymoorStudios.Core.Promises
- Assembly
- MarymoorStudios.Core.Promises.dll
A fixed-sized, shared-memory, Transport<T>.
public sealed class RingBuffer<T> : Transport<T>, IAsyncDisposable
Type Parameters
T
The item type.
- Inheritance
-
Transport<T>RingBuffer<T>
- Implements
- Inherited Members
Constructors
RingBuffer(ushort, ushort)
Constructs a new RingBuffer<T>
public RingBuffer(ushort capacity, ushort threshold = 1)
Parameters
capacity
ushortThe size of the buffer allocated (in number of items).
threshold
ushortThe number of items of empty space available before the producer is signaled.
Remarks
REQUIRES: capacity > 2
REQUIRES: 1 <= threshold < capacity -1
Capacity is equal to the size of the memory allocation (in number of items) but one item is consumed as a sentinel for "full", so the buffer can actually hold one less.
Threshold is used to decrease ping-ponging by delaying waking the producer until there are more items in the buffer. There is a tradeoff between added latency and buffering costs on the writer side versus signalling costs. The default value is 1 causing the producer to be signalled whenever there is at least one slot available.
Properties
ConsumerEvent
Event to efficiently signal the consumer when items are available to read.
public override sealed WaitHandle ConsumerEvent { get; }
Property Value
Remarks
This event only signals on the transition between an empty queue and having at least one item, so the caller should read the queue to completion before waiting on this event.
ProducerEvent
Event to efficiently signal the producer when slots are available to write.
public override sealed WaitHandle ProducerEvent { get; }
Property Value
Remarks
This event only signals on the transition between a full queue and having at least threshold
items, so the caller should write to the queue until full before waiting on this event.
Methods
Close(TransportFlags)
Marks the buffer as closed atomically.
public override sealed bool Close(TransportFlags flags = TransportFlags.Closed)
Parameters
flags
TransportFlagsIndicates which side(s) to close.
Returns
- bool
True if the both sides have closed, false if only one side has closed as of this call.
Remarks
No more items can be inserted after this call returns.
Either side (producer or consumer) can close the buffer.
Typically, the consumer will continue to read items until TryDequeue(out T) indicates the closure has been seen. This ensures that all buffered items have been removed, regardless of which side closed first.
Both sides should close the buffer before the last side to close can then safely dispose.
DisposeAsync(bool)
Standard dispose pattern for subclasses.
protected override sealed ValueTask DisposeAsync(bool disposing)
Parameters
disposing
boolTrue if both native and managed resources are being disposed. False if only native resources (i.e. in finalizer). When native only then MUST be prompt.
Returns
TryDequeue(out T)
Attempt to remove an item from the front of the buffer.
public override sealed bool TryDequeue(out T item)
Parameters
item
TIf successful, the item removed from the buffer,
default
otherwise.
Returns
- bool
True if an item was successfully remove, false if the buffer is empty.
Remarks
If item
is successfully removed the caller takes ownership of it and is
responsible for releasing its resources. If the attempt to dequeue fails then item
is
default
.
Exceptions
- AbortedException
If the buffer has been closed AND all buffered items have been read.
TryEnqueue(ref T)
Attempt to insert an item at the end of the buffer.
public override sealed bool TryEnqueue(ref T item)
Parameters
item
TThe item to be inserted.
Returns
- bool
True if the item was inserted, false if the buffer is full.
Remarks
On a successful insert the buffer takes ownership of item
and its value is set to
default
. If item
cannot be inserted (either because 'full' or 'closed') then false
is returned and item
is unmodified (still owned by the caller); the caller is then
responsible for releasing any resources.
Exceptions
- AbortedException
If the buffer has already been closed.