Table of Contents

ISegmentOwner<T> Interface

ISegmentOwner<T> complements IMemoryOwner<T> with a unified ownership contract for an ArraySegment<T> that controls the lifetime of its underlying memory. Implementors decide how to acquire and release that memory (pool return, GC collection, or no-op), while callers use a single consistent API. In conjunction with ArrayPool<T>, an allocated ArraySegment<T> has the advantage that the underlying buffer is adjustable in terms of the offset and the size of the segment without losing the ownership of the underlying pooled buffer. Due to the simple conversion to Span<T> and Memory<T>, it is easy to use in the hot path of the code.

Namespace

CryptoHives.Foundation.Memory.Buffers

Inheritance

IDisposableISegmentOwner<T>

Syntax

public interface ISegmentOwner<T> : IDisposable

Type Parameters

T — The element type of the segment.

Overview

ISegmentOwner<T> bundles three concerns:

Concern Member
Data access Segment property and this[int] indexer
Slice adjustment TrySetSegment(offset, length)
Lifetime management Dispose() (from IDisposable)

Three built-in implementations cover the most common ownership strategies:

Class Memory source Dispose behaviour
PooledSegment<T> ArrayPool<T>.Shared Returns array to pool
AllocatedSegment<T> new T[] (GC heap) Clears the segment wrapper
EmptySegment<T> Array.Empty<T>() No-op

Members

Properties

Property Type Description
Segment ArraySegment<T> The current segment view of the underlying array

Indexer

T this[int i] { get; set; }

Gets or sets element i relative to Segment.Offset inside Segment.Array.

Methods

bool TrySetSegment(int offset, int length);

Narrows or repositions the segment view. Returns true on success; false when the underlying array is null or too small to satisfy offset + length.

void Dispose();

Releases ownership of the underlying memory according to the concrete implementation.

Usage

Consuming code

Write consumer code against ISegmentOwner<T> and let the caller decide the ownership strategy via the concrete factory:

void Process(ISegmentOwner<byte> owner)
{
    Span<byte> span = owner.Segment.AsSpan();
    // ... work with span ...
}

// Caller chooses ArrayPool (cheap in hot path)
using ISegmentOwner<byte> pooled = PooledSegment<byte>.Rent(1024);
Process(pooled);

// Or GC-managed array (simple, no pool lifecycle to track)
using ISegmentOwner<byte> alloc = AllocatedSegment<byte>.Create(new byte[1024]);
Process(alloc);

Slicing after rent

using ISegmentOwner<byte> segment = PooledSegment<byte>.Rent(256);

if (segment.TrySetSegment(offset: 16, length: 64))
{
    // Segment is now [16..80) inside the rented array
    Span<byte> slice = segment.Segment.AsSpan();
    DecryptPayload(slice);
}

Thread Safety

Instances are not thread-safe. The intended pattern is single-owner, short-lived, scoped with using.

See Also


© 2026 The Keepers of the CryptoHives