Class ScyllaQueue<T>
High-performance FIFO queue backed by a circular buffer, with optional fixed-capacity mode, a thread-safe synchronized wrapper, and a fluent builder for configuration.
Inherited Members
Namespace: Scylla.Core.Structures
Assembly: ScyllaCore.dll
Syntax
public sealed class ScyllaQueue<T> : IScyllaCollection<T>, IScyllaCollection
Type Parameters
| Name | Description |
|---|---|
| T | The element type stored in the queue. May be a value type or a reference type.
When |
Remarks
The queue uses a single circular buffer array where _head is the index of the
oldest element (the next to be dequeued) and _tail is the index of the next
write position. Both pointers advance modulo the buffer length, so the buffer is reused
without shifting elements. Growth reallocates the buffer and resets the layout so that
_head == 0 and _tail == _count (linear, unwrapped).
Growth strategy: When not fixed-capacity and the buffer is full, the buffer doubles
in size (capped at 0x7FEFFFFF, matching the .NET BCL maximum array length). The
growth is triggered by TryEnqueue(T) and can be pre-triggered with
EnsureCapacity(int).
Fixed-capacity mode: When constructed with fixedCapacity: true, the buffer
never grows. TryEnqueue(T) returns false when the queue is full, and
EnsureCapacity(int) throws InvalidOperationException.
Thread safety: This class is unsynchronized by default. Use AsSynchronized(object) to obtain a ScyllaQueue<T>.SynchronizedScyllaQueue wrapper that serializes all operations through a lock.
// Direct construction - auto-growing queue with initial capacity 64
var queue = new ScyllaQueue<int>(capacity: 64);
// Fixed-capacity construction - never grows, TryEnqueue returns false when full
var fixedQueue = new ScyllaQueue<int>(capacity: 64, fixedCapacity: true);
// Fluent builder - synchronized wrapper for concurrent producer/consumer
IScyllaCollection<string> safeQueue = ScyllaQueue<string>.CreateBuilder()
.WithCapacity(128)
.FixedCapacity()
.Synchronized()
.Build();
Constructors
ScyllaQueue(int, bool)
Initializes a new ScyllaQueue<T> with the specified initial capacity and optional fixed-capacity constraint.
Declaration
public ScyllaQueue(int capacity = 4, bool fixedCapacity = false)
Parameters
| Type | Name | Description |
|---|---|---|
| int | capacity | The initial capacity of the internal circular buffer. Values less than |
| bool | fixedCapacity | When |
Properties
Capabilities
Gets the feature flags indicating which optional operations this queue supports.
Declaration
public ScyllaCollectionCapabilities Capabilities { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionCapabilities | HasCapacity |
SupportsPeek |
SupportsCopyTo |
SupportsContains.
The |
Capacity
Gets the current capacity of the internal circular buffer.
Declaration
public int Capacity { get; }
Property Value
| Type | Description |
|---|---|
| int | The number of elements the buffer can hold before the next growth event.
In fixed-capacity mode this is the permanent maximum and equals the value passed to
the constructor (or |
Count
Gets the number of elements currently in the queue.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int | A non-negative integer representing the current element count. Returns |
IsEmpty
Gets a value indicating whether the queue contains no elements.
Declaration
public bool IsEmpty { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
IsFixedCapacity
Gets a value indicating whether this queue operates in fixed-capacity mode.
Declaration
public bool IsFixedCapacity { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
IsFull
Gets a value indicating whether the queue is at full capacity.
Declaration
public bool IsFull { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
SyncRoot
Gets the synchronization root object for this queue.
Declaration
public object SyncRoot { get; }
Property Value
| Type | Description |
|---|---|
| object | Always |
ThreadSafety
Gets the thread-safety level of this queue.
Declaration
public ScyllaCollectionThreadSafety ThreadSafety { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionThreadSafety | Always Unsynchronized. Use AsSynchronized(object) to obtain a thread-safe wrapper. |
Methods
AsSynchronized(object)
Creates and returns a ScyllaQueue<T>.SynchronizedScyllaQueue that wraps this queue and serializes all operations through a lock.
Declaration
public ScyllaQueue<T>.SynchronizedScyllaQueue AsSynchronized(object syncRoot = null)
Parameters
| Type | Name | Description |
|---|---|---|
| object | syncRoot | An optional external lock object to use for synchronization. When |
Returns
| Type | Description |
|---|---|
| ScyllaQueue<T>.SynchronizedScyllaQueue | A ScyllaQueue<T>.SynchronizedScyllaQueue that delegates to this queue and protects every operation with the specified (or a newly created private) lock. |
Remarks
The wrapper wraps this specific queue instance. Any direct modifications to this
unsynchronized queue after calling AsSynchronized are not protected by the
wrapper's lock, so callers should exclusively use the returned wrapper for concurrent
scenarios.
See Also
Clear()
Removes all elements from the queue and resets it to an empty state.
Declaration
public void Clear()
Remarks
When T is a reference type, all occupied slots in the
circular buffer are explicitly cleared to default using
Clear(Array, int, int) before the head and tail pointers are reset. This
prevents the internal buffer from retaining strong references to objects that the
caller has logically discarded, allowing the garbage collector to reclaim them.
For value types, the slot-clear step is skipped for performance.
The clear correctly handles both the contiguous layout (_head < _tail)
and the wrapped layout (_head >= _tail) of the circular buffer.
After this method returns, Count is 0, but
Capacity and IsFixedCapacity are unchanged.
Contains(T, IEqualityComparer<T>)
Determines whether the queue contains the specified item by performing a linear search through all elements in FIFO order.
Declaration
public bool Contains(T item, IEqualityComparer<T> comparer = null)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | The item to locate. For reference types, |
| IEqualityComparer<T> | comparer | Optional equality comparer used to compare elements. When |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
This is an O(n) operation. It correctly handles the wrapped circular buffer layout by advancing the search index modulo the buffer length.
CopyTo(Span<T>)
Copies elements from the queue into the provided span in FIFO order (oldest element first), using an efficient two-segment block copy that avoids per-element overhead.
Declaration
public int CopyTo(Span<T> destination)
Parameters
| Type | Name | Description |
|---|---|---|
| Span<T> | destination | The caller-owned span to receive the elements. If smaller than Count,
only the first |
Returns
| Type | Description |
|---|---|
| int | The number of elements copied, equal to |
Remarks
The copy is performed using MemoryExtensions.CopyTo
on contiguous segments of the circular buffer. Two calls are issued when the live
region wraps around the end of the buffer; one call suffices for the contiguous case.
This is more efficient than a per-element loop and avoids any heap allocation.
CopyTo(T[], int)
Copies elements from the queue into the provided array starting at
destinationIndex, in FIFO order (oldest element first).
Declaration
public int CopyTo(T[] destination, int destinationIndex)
Parameters
| Type | Name | Description |
|---|---|---|
| T[] | destination | The array to copy elements into. Must not be |
| int | destinationIndex | The zero-based index in |
Returns
| Type | Description |
|---|---|
| int | The number of elements copied, equal to
|
Remarks
Uses Copy(Array, Array, int) on up to two contiguous segments of the internal circular buffer to avoid per-element overhead. Prefer the CopyTo(Span<T>) overload in synchronous hot paths to avoid boxing.
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when |
| ArgumentOutOfRangeException | Thrown when |
CreateBuilder()
Creates and returns a new fluent ScyllaQueue<T>.Builder for constructing a ScyllaQueue<T> with a discoverable, named-parameter API.
Declaration
public static ScyllaQueue<T>.Builder CreateBuilder()
Returns
| Type | Description |
|---|---|
| ScyllaQueue<T>.Builder | A new ScyllaQueue<T>.Builder instance initialized with default settings
( |
Remarks
// Fixed-capacity queue with 64 slots
var queue = ScyllaQueue<int>.CreateBuilder()
.WithCapacity(64)
.FixedCapacity()
.Build();
// Thread-safe auto-growing queue via synchronized wrapper
IScyllaCollection<string> safe = ScyllaQueue<string>.CreateBuilder()
.WithCapacity(128)
.Synchronized()
.Build();
See Also
EnsureCapacity(int)
Ensures the queue can hold at least minCapacity elements without
triggering an automatic growth event during subsequent enqueue operations.
Declaration
public void EnsureCapacity(int minCapacity)
Parameters
| Type | Name | Description |
|---|---|---|
| int | minCapacity | The minimum number of elements the queue must be able to hold. If the current Capacity is already at least this value, no action is taken. |
Remarks
Calling this method pre-allocates the internal buffer to avoid repeated small growths when a known number of elements will be enqueued. It has no effect when the current capacity already satisfies the requirement.
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when this method is called on a fixed-capacity queue (IsFixedCapacity
is |
GetEnumerator()
Returns a value-type ScyllaQueue<T>.Enumerator that iterates through the queue in FIFO order (oldest element first), without allocating a heap object.
Declaration
public ScyllaQueue<T>.Enumerator GetEnumerator()
Returns
| Type | Description |
|---|---|
| ScyllaQueue<T>.Enumerator | An ScyllaQueue<T>.Enumerator struct positioned before the first element. Use in a
|
Remarks
The enumerator snapshots Scylla.Core.Structures.ScyllaQueue<T>._count and Scylla.Core.Structures.ScyllaQueue<T>._head at the moment it is created. Elements added or removed after construction are not reflected during iteration. Modifying the queue while iterating produces undefined but safe behavior (no exceptions, but iteration may visit stale or duplicate elements).
TryAdd(T)
Attempts to add an item to the back of the queue. This method implements TryAdd(T) and delegates to TryEnqueue(T).
Declaration
public bool TryAdd(T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | The item to enqueue. |
Returns
| Type | Description |
|---|---|
| bool |
|
TryDequeue(out T)
Attempts to remove and return the oldest (front) element from the queue.
Declaration
public bool TryDequeue(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
After a successful dequeue, the slot at _head is explicitly set to
default to release the element reference and allow garbage collection when
T is a reference type. _head then advances by one
modulo the buffer length and Scylla.Core.Structures.ScyllaQueue<T>._count is decremented.
See Also
TryEnqueue(T)
Attempts to add an item to the back of the queue, growing the internal buffer if needed.
Declaration
public bool TryEnqueue(T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | The item to enqueue. |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
After a successful enqueue, _tail advances by one modulo the buffer length and
Scylla.Core.Structures.ScyllaQueue<T>._count is incremented. The internal buffer is grown via
Grow(int) before the write when the queue is full and not fixed-capacity.
See Also
TryPeek(out T)
Attempts to inspect the front element without removing it. This method implements TryPeek(out T) and delegates to TryPeekFront(out T).
Declaration
public bool TryPeek(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
TryPeekFront(out T)
Attempts to inspect the oldest (front) element without removing it from the queue.
Declaration
public bool TryPeekFront(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
See Also
TryRemove(out T)
Attempts to remove and return the front element from the queue. This method implements TryRemove(out T) and delegates to TryDequeue(out T).
Declaration
public bool TryRemove(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|