Table of Contents

RingBackedCollection<T> Class

Definition

Namespace
Bodu.Collections.Generic
Assembly
Bodu.Collections.dll
Package
Bodu.Collections 1.0.0
Source
RingBackedCollection{T}.Enumerator.cs

Provides the shared low-level mechanics for ring-buffer-backed collections - a contiguous backing array, head/tail indices with modulo wrap, a live element count, and a structural-version counter - as a reusable base type for CircularBuffer<T> and Deque<T>.

public abstract class RingBackedCollection<T> : ICollection, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable

Type Parameters

T

Specifies the type of elements stored in the collection.

Inheritance
RingBackedCollection<T>
Implements
Derived
Inherited Members
Extension Methods

Examples

// The common surface is consumed through a concrete derivative - CircularBuffer<T> here.
// The same Count, Capacity, IsEmpty, indexer, ToArray, and TrimExcess members are available
// on every RingBackedCollection<T> subtype.
RingBackedCollection<int> ring = new CircularBuffer<int>(capacity: 4);
((CircularBuffer<int>)ring).Enqueue(10);
((CircularBuffer<int>)ring).Enqueue(20);

Console.WriteLine(ring.Count);    // 2
Console.WriteLine(ring.Capacity); // 4
Console.WriteLine(ring[0]);       // 10 - head-relative indexer
ring.TrimExcess();                // shrink Capacity towards Count

Remarks

RingBackedCollection<T> is intended as an extension point for new ring-backed collection types. It owns the storage and exposes:

The protected mutators perform no capacity or emptiness validation: derived classes must enforce those contracts before calling. This keeps the hot path branch-free in the common cases. Each mutator bumps the internal structural-version counter so any in-flight enumerators are correctly invalidated.

Concrete derived types layer their own public API on top of these primitives:

  • CircularBuffer<T> adds the single-ended Enqueue / Dequeue / Peek surface with an AllowOverwrite toggle and eviction events.
  • Deque<T> adds the double-ended AddFirst / AddLast / RemoveFirst / RemoveLast / PeekFirst / PeekLast surface, with an AllowGrow toggle for fixed-vs-growable behavior.

This type is not thread-safe. For thread-safe single-ended FIFO access, use ConcurrentCircularBuffer<T> in the Bodu.Collections.Concurrent package - its lock-free Vyukov implementation does not share storage with this hierarchy.

Constructors

RingBackedCollection(IEnumerable<T>, int)

Initializes a new instance of the RingBackedCollection<T> class containing elements copied from collection, with the specified capacity. When the source is larger than the capacity, only the most recent capacity elements are retained.

protected RingBackedCollection(IEnumerable<T> collection, int capacity)

Parameters

collection IEnumerable<T>

The collection from which elements are copied. Must not be null.

capacity int

The backing-array capacity. Must be greater than zero.

Exceptions

ArgumentNullException

collection is null.

ArgumentOutOfRangeException

capacity is less than 1.

RingBackedCollection(int)

Initializes a new instance of the RingBackedCollection<T> class with a backing array of the specified capacity.

protected RingBackedCollection(int capacity)

Parameters

capacity int

The initial backing-array capacity. Must be greater than zero.

Exceptions

ArgumentOutOfRangeException

capacity is less than 1.

Properties

Capacity

Gets the maximum number of elements that the collection can currently hold without resizing the backing array.

public int Capacity { get; }

Property Value

int

The length of the underlying array.

Count

Gets the number of elements contained in the ICollection.

public int Count { get; }

Property Value

int

The number of elements contained in the ICollection.

IsEmpty

Gets a value indicating whether the collection contains no elements.

public bool IsEmpty { get; }

Property Value

bool

true if Count is zero; otherwise, false.

IsFull

Gets a value indicating whether the collection has reached the current backing-array capacity. On a fixed-capacity buffer this signals that the next add will throw or be rejected; on a growable collection it is a transient state that the next add resolves by resizing.

public bool IsFull { get; }

Property Value

bool

true if Count equals Capacity.

this[int]

Gets the element at the specified zero-based logical index, where 0 refers to the head element.

public T this[int index] { get; }

Parameters

index int

The zero-based, head-relative index. Must be in [0, Count).

Property Value

T

The element at the given logical position.

Exceptions

ArgumentOutOfRangeException

index is negative or not less than Count.

Methods

AddHead(T)

Adds item at the position immediately before the head and retreats the head. The caller must ensure Count < Capacity before invoking.

protected void AddHead(T item)

Parameters

item T

The element to prepend.

AddTail(T)

Adds item at the tail position and advances the tail. The caller must ensure Count < Capacity before invoking.

protected void AddTail(T item)

Parameters

item T

The element to append.

Clear()

Removes all elements from the collection, clearing the live region of the backing array and resetting head, tail, and count. Bumps the structural version when something was cleared.

public void Clear()

Exceptions

InvalidOperationException

The method is invoked from within an eviction event handler.

Contains(T)

Determines whether the collection contains the specified element using Default.

public bool Contains(T item)

Parameters

item T

The element to locate. May be null for reference types.

Returns

bool

true if found; otherwise, false.

CopyTo(T[], int)

Copies the collection's elements to array in head-to-tail logical order, starting at index.

public void CopyTo(T[] array, int index)

Parameters

array T[]

The destination array. Must not be null.

index int

The zero-based starting index in array.

Exceptions

ArgumentNullException

array is null.

ArgumentOutOfRangeException

index is negative.

ArgumentException

The destination is too small to hold the contents starting at index.

GetEnumerator()

Returns an enumerator that iterates the collection's elements in head-to-tail logical order.

public RingBackedCollection<T>.Enumerator GetEnumerator()

Returns

RingBackedCollection<T>.Enumerator

An RingBackedCollection<T>.Enumerator for the collection.

Remarks

The enumerator captures a structural-version token at creation. Any subsequent structural mutation - including Clear, TrimExcess, or any of the derived-type mutators - invalidates the enumerator. The next MoveNext() or Reset() call throws InvalidOperationException.

OverwriteTail(T)

Writes item at the slot occupied by the tail (which equals the head when the collection is full) and advances both head and tail by one slot. Used by the eviction path of CircularBuffer<T> when overwriting the oldest element. Count is unchanged.

protected void OverwriteTail(T item)

Parameters

item T

The element to write into the slot occupied by the tail.

Remarks

The caller must ensure Count == Capacity before invoking.

PeekHead()

Returns the head element without removing it. The caller must ensure Count > 0.

protected T PeekHead()

Returns

T

The current head element.

PeekTail()

Returns the tail element without removing it. The caller must ensure Count > 0.

protected T PeekTail()

Returns

T

The element immediately preceding _tail in modulo order.

RemoveHead()

Removes and returns the head element, clearing its slot. The caller must ensure Count > 0 before invoking.

protected T RemoveHead()

Returns

T

The element that was at the head.

RemoveTail()

Removes and returns the tail element, clearing its slot. The caller must ensure Count > 0 before invoking.

protected T RemoveTail()

Returns

T

The element that was at the tail.

Resize(int)

Replaces the backing array with one of size newCapacity, copying the live region into the new array starting at index zero. Resets Bodu.Collections.Generic.RingBackedCollection`1._head to zero and Bodu.Collections.Generic.RingBackedCollection`1._tail to the position just after the last element.

protected void Resize(int newCapacity)

Parameters

newCapacity int

The new capacity. Must satisfy newCapacity >= Count and newCapacity >= 1.

ToArray()

Returns a new array containing the collection's elements in head-to-tail logical order.

public T[] ToArray()

Returns

T[]

A freshly allocated array of length Count.

TrimExcess()

Reduces the backing-array capacity to match Count, freeing unused memory. If the collection is empty, the capacity is reduced to one slot to keep operations valid.

public void TrimExcess()

Exceptions

InvalidOperationException

The method is invoked from within an eviction event handler.

Explicit Interface Implementations

IEnumerable<T>.GetEnumerator()

Returns an enumerator that iterates through the collection.

IEnumerator<T> IEnumerable<T>.GetEnumerator()

Returns

IEnumerator<T>

An enumerator that can be used to iterate through the collection.

ICollection.CopyTo(Array, int)

Copies the collection's elements to a one-dimensional Array, starting at the specified index, in head-to-tail logical order.

void ICollection.CopyTo(Array array, int index)

Parameters

array Array

The destination array. Must be single-dimensional and zero-based.

index int

The zero-based starting index in array.

Exceptions

ArgumentNullException

array is null.

ArgumentException

array is multidimensional, not zero-based, or has an incompatible element type.

ArgumentOutOfRangeException

index is less than zero.

ICollection.IsSynchronized

Gets a value indicating whether access to the collection is synchronized (thread-safe). Always returns false; ring-backed collections are not thread-safe by themselves.

bool ICollection.IsSynchronized { get; }

Returns

bool

Always false.

Remarks

External synchronization is the caller's responsibility. For a thread-safe FIFO buffer, see ConcurrentCircularBuffer<T> in the Bodu.Collections.Concurrent package.

ICollection.SyncRoot

Gets a lazily-initialized object that can be used to synchronize access to the collection.

object ICollection.SyncRoot { get; }

Returns

object

A non-null object suitable as a Monitor target.

IEnumerable.GetEnumerator()

Returns an enumerator that iterates through a collection.

IEnumerator IEnumerable.GetEnumerator()

Returns

IEnumerator

An IEnumerator object that can be used to iterate through the collection.

Applies to

ProductVersions
.NET8, 10