Table of Contents

PooledBufferBuilder<T> Class

Definition

Namespace
Bodu.Buffers
Assembly
Bodu.Core.dll
Package
Bodu.Core 1.0.1
Source
PooledBufferBuilder{T}.cs

Provides an efficient way to accumulate elements into a pooled buffer, with automatic resizing and fast-path optimizations for collection-based and span-based sources.

public sealed class PooledBufferBuilder<T> : IBufferWriter<T>, IMemoryOwner<T>, IDisposable

Type Parameters

T

The type of elements to buffer.

Inheritance
PooledBufferBuilder<T>
Implements
Inherited Members
Extension Methods

Examples

// Accumulate a result of unknown length without per-item array doubling.
using var builder = new PooledBufferBuilder<int>(initialCapacity: 256);

foreach (int value in source)
    builder.Append(value);

ReadOnlySpan<int> span = builder.WrittenSpan;
Console.WriteLine($"Buffered {builder.WrittenCount} values from a pooled buffer of {builder.Capacity}.");
// The rented array is returned to ArrayPool<int>.Shared when 'builder' is disposed.

Remarks

Buffers are rented from Shared and returned on Dispose(). When T is a reference type or contains references, the live portion of the buffer is cleared before the underlying array is returned to the pool, preventing unintended object retention.

Call Reset() to clear accumulated data and reuse the current rented buffer without a pool round-trip. Call Dispose() when the builder is no longer needed.

Constructors

PooledBufferBuilder(int)

Initializes a new instance of the PooledBufferBuilder<T> class with the specified initial capacity.

public PooledBufferBuilder(int initialCapacity = 256)

Parameters

initialCapacity int

The minimum initial capacity of the pooled buffer. Must be greater than zero. Defaults to 256.

Exceptions

ArgumentOutOfRangeException

Thrown when initialCapacity is less than 1.

Properties

Capacity

Gets the current capacity of the internal buffer.

public int Capacity { get; }

Property Value

int

The length of the underlying rented array. This value is always greater than or equal to WrittenCount and may be larger than the capacity requested at construction due to ArrayPool<T> rounding behavior.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

FreeCapacity

Gets the number of elements that can be written to the buffer before the next growth.

public int FreeCapacity { get; }

Property Value

int

The number of remaining slots in the current rented array - equivalent to Capacity minus WrittenCount.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

IsEmpty

Gets a value indicating whether no elements have been written to the buffer.

public bool IsEmpty { get; }

Property Value

bool

true if WrittenCount is zero; otherwise false.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

WrittenCount

Gets the number of elements that have been written to the buffer.

public int WrittenCount { get; }

Property Value

int

The count of elements appended and not yet discarded by Reset().

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

WrittenMemory

Gets a ReadOnlyMemory<T> representing the elements written to the buffer.

public ReadOnlyMemory<T> WrittenMemory { get; }

Property Value

ReadOnlyMemory<T>

A ReadOnlyMemory<T> containing exactly the first WrittenCount buffered elements.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

WrittenSpan

Gets a ReadOnlySpan<T> representing the elements written to the buffer.

public ReadOnlySpan<T> WrittenSpan { get; }

Property Value

ReadOnlySpan<T>

A ReadOnlySpan<T> containing exactly the first WrittenCount buffered elements.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

Methods

AddMany(T, int)

Appends count copies of value to the buffer, growing the internal array if necessary.

public void AddMany(T value, int count)

Parameters

value T

The value to repeat.

count int

The number of times to append value. Must be non-negative.

Exceptions

ArgumentOutOfRangeException

Thrown when count is negative.

ObjectDisposedException

Thrown if the instance has been disposed.

Advance(int)

Notifies the builder that count elements were written into the span or memory most recently returned by GetSpan(int) or GetMemory(int).

public void Advance(int count)

Parameters

count int

The number of elements written. Must be non-negative and must not exceed the length of the buffer most recently returned by GetSpan(int) or GetMemory(int).

Exceptions

ArgumentOutOfRangeException

Thrown when count is negative or would advance WrittenCount past the end of the current internal buffer.

ObjectDisposedException

Thrown if the instance has been disposed.

Append(T)

Appends a single element to the buffer, growing the internal array if necessary.

public void Append(T item)

Parameters

item T

The element to append.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

AppendRange(IEnumerable<T>)

Appends a sequence of elements from the specified IEnumerable<T> source, growing the buffer as needed.

public void AppendRange(IEnumerable<T> source)

Parameters

source IEnumerable<T>

The sequence of elements to append. Must not be null.

Remarks

When source implements ICollection<T>, a single bulk copy is performed instead of element-by-element iteration.

Exceptions

ArgumentNullException

Thrown if source is null.

ObjectDisposedException

Thrown if the instance has been disposed.

AppendRange(ReadOnlyMemory<T>)

Appends all elements from the specified ReadOnlyMemory<T> to the buffer, growing the internal array if necessary.

public void AppendRange(ReadOnlyMemory<T> source)

Parameters

source ReadOnlyMemory<T>

The memory region of elements to append.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

AppendRange(ReadOnlySpan<T>)

Appends all elements from the specified ReadOnlySpan<T> to the buffer, growing the internal array if necessary.

public void AppendRange(ReadOnlySpan<T> source)

Parameters

source ReadOnlySpan<T>

The span of elements to append.

Remarks

source may alias the builder's own storage (for example a span obtained from WrittenSpan or DangerousGetArray()): when a growth is required, the previous rented array is returned to the pool only after the source elements have been copied, so a self-aliasing source remains valid throughout the append.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

CopyTo(Span<T>)

Copies the written elements into destination.

public void CopyTo(Span<T> destination)

Parameters

destination Span<T>

The target span. Must be at least WrittenCount elements long.

Exceptions

ArgumentException

Thrown when destination is too small.

ObjectDisposedException

Thrown if the instance has been disposed.

DangerousGetArray()

Returns an ArraySegment<T> that aliases the underlying rented array, bounded to the written region.

public ArraySegment<T> DangerousGetArray()

Returns

ArraySegment<T>

An ArraySegment<T> starting at offset 0 with a count equal to WrittenCount. The segment points directly into pooled memory and must not be used after Dispose() is called.

Remarks

This method is an escape hatch for APIs that require a byte[] or ArraySegment<T> rather than a Span<T> or Memory<T>. Treat the returned segment as borrowed - do not retain it beyond the lifetime of this builder.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

Dispose()

Releases the pooled buffer and resets the internal state of the builder.

public void Dispose()

Remarks

After calling this method, further operations on the instance will throw ObjectDisposedException.

EnsureCapacity(int)

Ensures the internal buffer can hold at least minimum elements, growing via a new pooled allocation when needed.

public void EnsureCapacity(int minimum)

Parameters

minimum int

The minimum total capacity required. Must be non-negative. No-ops when the current Capacity already satisfies the request.

Exceptions

ArgumentOutOfRangeException

Thrown when minimum is negative.

ObjectDisposedException

Thrown if the instance has been disposed.

GetMemory(int)

Returns a Memory<T> of at least sizeHint elements into which the caller can write, automatically growing the buffer if necessary.

public Memory<T> GetMemory(int sizeHint = 0)

Parameters

sizeHint int

The minimum number of elements required. When zero or negative, at least one element of free space is ensured. The returned memory may be larger than the hint.

Returns

Memory<T>

A writable Memory<T> beginning at the current write position and spanning all free capacity. Call Advance(int) after writing to commit the data.

Exceptions

ArgumentOutOfRangeException

Thrown when sizeHint is negative.

ObjectDisposedException

Thrown if the instance has been disposed.

GetSpan(int)

Returns a Span<T> of at least sizeHint elements into which the caller can write, automatically growing the buffer if necessary.

public Span<T> GetSpan(int sizeHint = 0)

Parameters

sizeHint int

The minimum number of elements required. When zero or negative, at least one element of free space is ensured. The returned span may be larger than the hint.

Returns

Span<T>

A writable Span<T> beginning at the current write position and spanning all free capacity. Call Advance(int) after writing to commit the data.

Exceptions

ArgumentOutOfRangeException

Thrown when sizeHint is negative.

ObjectDisposedException

Thrown if the instance has been disposed.

Reset()

Resets the builder to an empty state, retaining the current rented buffer to avoid a pool round-trip.

public void Reset()

Remarks

Any reference slots in the valid portion of the buffer are cleared to prevent unintended object retention. The underlying array is not returned to Shared; call Dispose() to release it.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

Sort(IComparer<T>?)

Sorts the written elements in place using the specified comparer, or the default comparer when comparer is null.

public void Sort(IComparer<T>? comparer = null)

Parameters

comparer IComparer<T>

The comparer to use, or null to use Default.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

Sort(Comparison<T>)

Sorts the written elements in place using the specified comparison delegate.

public void Sort(Comparison<T> comparison)

Parameters

comparison Comparison<T>

The comparison to use. Must not be null.

Exceptions

ArgumentNullException

Thrown when comparison is null.

ObjectDisposedException

Thrown if the instance has been disposed.

ToArrayAndDispose()

Copies the written elements into a freshly allocated array and disposes the builder in a single call.

public T[] ToArrayAndDispose()

Returns

T[]

A new array of length WrittenCount containing the written elements in order. The returned array is owned by the caller and is independent of any pooled storage.

Remarks

This is the canonical "build, materialize, release" shortcut for callers that want a managed array and do not need to continue mutating the builder. After this call returns, the builder is disposed and any further operation on it throws ObjectDisposedException.

Exceptions

ObjectDisposedException

Thrown if the instance has already been disposed.

TryCopyFrom(IReadOnlyCollection<T>)

Attempts to populate the buffer from the specified IReadOnlyCollection<T> using a fast-path CopyTo when the source also implements ICollection<T>.

public bool TryCopyFrom(IReadOnlyCollection<T> source)

Parameters

source IReadOnlyCollection<T>

The source collection to copy from. Must not be null.

Returns

bool

true if the copy was performed via CopyTo(T[], int); false if the source does not implement ICollection<T> and no copy was performed.

Remarks

When successful, any previously buffered data is discarded and replaced with the contents of source. The current rented array is reused when its capacity is sufficient, and WrittenCount is set to the source element count.

Exceptions

ArgumentNullException

Thrown if source is null.

ObjectDisposedException

Thrown if the instance has been disposed.

TryCopyTo(Span<T>)

Attempts to copy the written elements into destination without throwing when the destination is too small.

public bool TryCopyTo(Span<T> destination)

Parameters

destination Span<T>

The target span to copy into.

Returns

bool

true when destination has space for at least WrittenCount elements and the copy was performed; false when the destination is too small, in which case nothing is written.

Remarks

Use this overload in code paths that probe the destination size and act on the boolean rather than catching ArgumentException from CopyTo(Span<T>).

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

Explicit Interface Implementations

IMemoryOwner<T>.Memory

Gets the written region of the buffer as a Memory<T>, as required by IMemoryOwner<T>.

Memory<T> IMemoryOwner<T>.Memory { get; }

Returns

Memory<T>

A Memory<T> covering exactly the first WrittenCount elements.

Exceptions

ObjectDisposedException

Thrown if the instance has been disposed.

Applies to

ProductVersions
.NET8, 10