Class ScyllaStack<T>
High-performance LIFO (last-in, first-out) stack backed by a contiguous managed array buffer.
Inherited Members
Namespace: Scylla.Core.Structures
Assembly: ScyllaCore.dll
Syntax
public sealed class ScyllaStack<T> : IScyllaCollection<T>, IScyllaCollection
Type Parameters
| Name | Description |
|---|---|
| T | The element type stored in the stack. May be any managed or value type. For reference types, Clear() explicitly nulls out cleared slots to release object graph references and avoid unintentional retention. |
Remarks
Push, Pop, and Peek are all O(1) amortized. When operating in variable-capacity mode
(the default), the internal buffer doubles in size whenever it is exhausted, following
the same growth strategy used by the .NET BCL. The maximum buffer size is capped at
0x7FEFFFFF elements, matching the .NET runtime's maximum safe array length.
Fixed-capacity mode: Pass fixedCapacity: true to the constructor (or call
FixedCapacity(bool) on the builder) to prevent automatic growth.
In fixed-capacity mode, TryPush(T) returns false instead of resizing
when the stack is full, and EnsureCapacity(int) throws
InvalidOperationException.
Thread safety: This class is unsynchronized by default.
Call AsSynchronized(object) to obtain a ScyllaStack<T>.SynchronizedScyllaStack
wrapper that guards every operation with a lock statement.
Enumeration: GetEnumerator() returns a value-type
ScyllaStack<T>.Enumerator that iterates top-to-bottom without heap allocation.
Modifying the stack during enumeration produces undefined results; the enumerator
takes a snapshot of Count at construction time and will stop early if
items are removed concurrently.
For Burst/DOTS usage where T must be unmanaged,
use ScyllaStackDOTS<T> instead.
// Direct construction
var stack = new ScyllaStack<int>(capacity: 64, fixedCapacity: true);
// Using fluent builder for complex configuration
var stack = ScyllaStack<string>.CreateBuilder()
.WithCapacity(128)
.FixedCapacity()
.Synchronized()
.Build();
Constructors
ScyllaStack(int, bool)
Initializes a new ScyllaStack<T> with the specified initial capacity and growth behavior.
Declaration
public ScyllaStack(int capacity = 4, bool fixedCapacity = false)
Parameters
| Type | Name | Description |
|---|---|---|
| int | capacity | The initial capacity of the internal backing buffer. Values less than 1 are silently clamped to 1. The buffer will not be resized until this many elements have been pushed. |
| bool | fixedCapacity | When |
Properties
Capabilities
Gets the ScyllaCollectionCapabilities flags that describe the optional operations supported by this stack. Reports HasCapacity, SupportsPeek, SupportsCopyTo, and SupportsContains.
Declaration
public ScyllaCollectionCapabilities Capabilities { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionCapabilities |
Capacity
Gets the current capacity of the backing buffer, i.e. the number of elements the stack can hold before the next automatic resize (or push failure in fixed-capacity mode).
Declaration
public int Capacity { get; }
Property Value
| Type | Description |
|---|---|
| int |
Count
Gets the number of elements currently held in the stack.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int |
IsEmpty
Gets a value indicating whether the stack contains no elements.
Declaration
public bool IsEmpty { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsFixedCapacity
Gets a value indicating whether this stack operates in fixed-capacity mode.
When true, the backing buffer never grows: TryPush(T) returns
false when full and EnsureCapacity(int) throws.
When false, the buffer doubles automatically as needed.
Declaration
public bool IsFixedCapacity { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsFull
Gets a value indicating whether the stack is currently full.
This is only meaningful when IsFixedCapacity is true; a
variable-capacity stack will always grow to accommodate the next push.
Declaration
public bool IsFull { get; }
Property Value
| Type | Description |
|---|---|
| bool |
SyncRoot
Gets the synchronization root for this stack. Always returns null because
this unsynchronized stack does not own a lock object. Use AsSynchronized(object)
to obtain a wrapper with a valid SyncRoot.
Declaration
public object SyncRoot { get; }
Property Value
| Type | Description |
|---|---|
| object |
ThreadSafety
Gets Unsynchronized, indicating that no internal locking is performed. Use AsSynchronized(object) to obtain a thread-safe wrapper.
Declaration
public ScyllaCollectionThreadSafety ThreadSafety { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionThreadSafety |
Methods
AsSynchronized(object)
Creates and returns a ScyllaStack<T>.SynchronizedScyllaStack wrapper around this stack that serializes all operations through a single lock object.
Declaration
public ScyllaStack<T>.SynchronizedScyllaStack AsSynchronized(object syncRoot = null)
Parameters
| Type | Name | Description |
|---|---|---|
| object | syncRoot | An optional external object to use as the synchronization lock. Pass a shared
|
Returns
| Type | Description |
|---|---|
| ScyllaStack<T>.SynchronizedScyllaStack | A ScyllaStack<T>.SynchronizedScyllaStack that wraps this stack instance. |
Remarks
After calling this method, all concurrent access to the stack should be performed exclusively through the returned wrapper to preserve thread safety. Accessing the original unsynchronized stack and the wrapper from different threads simultaneously produces a data race.
Clear()
Removes all elements from the stack and resets it to an empty state.
Declaration
public void Clear()
Remarks
For reference types (!typeof(T).IsValueType), the cleared slots in the
backing buffer are explicitly set to default via Clear(Array, int, int)
so that the garbage collector can reclaim the referenced objects. For value types,
only the element count is reset; the buffer contents are not overwritten.
The backing buffer is not resized or deallocated by this method.
Contains(T, IEqualityComparer<T>)
Determines whether the stack contains the specified item. This operation is O(n).
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 | The equality comparer used to compare elements against |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
The search scans all elements from index 0 to Count - 1 (i.e. bottom
to top). Short-circuits on the first match. Returns false immediately when the
stack is empty, without allocating a comparer.
CopyTo(Span<T>)
Copies elements from the stack into destination in top-to-bottom order.
Element 0 of the destination receives the current top of the stack.
Declaration
public int CopyTo(Span<T> destination)
Parameters
| Type | Name | Description |
|---|---|---|
| Span<T> | destination | The span to write into. A zero-length span causes the method to return 0 immediately. |
Returns
| Type | Description |
|---|---|
| int | The number of elements actually written to |
Remarks
Copies min(Count, destination.Length) elements. If the destination span is
shorter than the stack, only the topmost elements are copied; bottom elements are
silently omitted. No elements are removed from the stack.
CopyTo(T[], int)
Copies elements from the stack into destination starting at
destinationIndex, in top-to-bottom order.
Element at destinationIndex receives the current top of the stack.
Declaration
public int CopyTo(T[] destination, int destinationIndex)
Parameters
| Type | Name | Description |
|---|---|---|
| T[] | destination | The target array. Must not be |
| int | destinationIndex | The zero-based index in |
Returns
| Type | Description |
|---|---|
| int | The number of elements actually written to |
Remarks
Copies min(Count, destination.Length - destinationIndex) elements.
If the available space in the destination array is less than Count,
only as many elements as will fit are copied (topmost first). No elements are removed
from the stack.
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when |
| ArgumentOutOfRangeException | Thrown when |
CreateBuilder()
Creates a new fluent ScyllaStack<T>.Builder for configuring and constructing a ScyllaStack<T> instance.
Declaration
public static ScyllaStack<T>.Builder CreateBuilder()
Returns
| Type | Description |
|---|---|
| ScyllaStack<T>.Builder | A new, unconfigured ScyllaStack<T>.Builder instance. |
Remarks
The builder provides a discoverable, named-parameter-style API that is easier to read than positional constructor arguments, especially when enabling fixed-capacity mode or a synchronized wrapper. Call Build() to obtain an IScyllaCollection<T> (useful when the synchronized wrapper may be returned), or BuildConcrete() to obtain the concrete ScyllaStack<T> type directly.
var stack = ScyllaStack<int>.CreateBuilder()
.WithCapacity(64)
.FixedCapacity()
.Build();
EnsureCapacity(int)
Ensures the backing buffer can hold at least minCapacity elements
without a further resize.
Declaration
public void EnsureCapacity(int minCapacity)
Parameters
| Type | Name | Description |
|---|---|---|
| int | minCapacity | The minimum total number of elements the stack must be able to hold after this call. Must be a non-negative integer. Passing zero or a value smaller than the current capacity is a no-op. |
Remarks
If the current capacity already meets or exceeds minCapacity, this
method is a no-op. Otherwise, Grow(int) is called with the requested minimum,
which may allocate a buffer larger than requested (up to double the current size).
Use this method before a batch of pushes to avoid repeated incremental reallocations.
Exceptions
| Type | Condition |
|---|---|
| InvalidOperationException | Thrown when this stack is in fixed-capacity mode. A fixed-capacity stack cannot grow after construction; use a variable-capacity stack or pre-size it appropriately. |
GetEnumerator()
Returns a value-type ScyllaStack<T>.Enumerator that iterates the stack from top to bottom.
Declaration
public ScyllaStack<T>.Enumerator GetEnumerator()
Returns
| Type | Description |
|---|---|
| ScyllaStack<T>.Enumerator | A new ScyllaStack<T>.Enumerator positioned before the first (top) element. |
Remarks
Because ScyllaStack<T>.Enumerator is a struct, calling this method on the
concrete ScyllaStack<T> type (rather than through an interface) avoids
a heap allocation. The C# compiler's foreach statement will use this overload
automatically when the static type is ScyllaStack<T>.
The enumerator captures a snapshot of Count at construction time. Modifying the stack after calling GetEnumerator() may cause the enumeration to produce incorrect results or terminate early.
TryAdd(T)
Attempts to push item onto the top of the stack.
This method is the TryAdd(T) implementation and
delegates directly to TryPush(T).
Declaration
public bool TryAdd(T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | The item to push. May be |
Returns
| Type | Description |
|---|---|
| bool |
|
TryPeek(out T)
Attempts to read the top element without removing it. This method is the TryPeek(out T) implementation and delegates directly to TryPeekTop(out T).
Declaration
public bool TryPeek(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
TryPeekTop(out T)
Attempts to read the top element of the stack without removing it.
Declaration
public bool TryPeekTop(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
TryPop(out T)
Attempts to pop the top element from the stack, removing it in the process.
Declaration
public bool TryPop(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
The slot vacated by the popped element is cleared to default so that
reference types are released for garbage collection even if the backing buffer
is not resized.
TryPush(T)
Attempts to push item onto the top of the stack.
Declaration
public bool TryPush(T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | The item to push. May be |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
If the backing buffer is full and the stack is in variable-capacity mode, the buffer
is first doubled via Grow(int) before the element is written. This growth is
amortized O(1) over many pushes. If the stack is in fixed-capacity mode and full, no
allocation occurs and the method returns false immediately.
TryRemove(out T)
Attempts to pop the top element from the stack. This method is the TryRemove(out T) implementation and delegates directly to TryPop(out T).
Declaration
public bool TryRemove(out T item)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|