eve.util.ringbuffer

A fixed-capacity ring buffer for byte data.

Part of EVE's Buffer Ownership Redesign (BUFFER-OWNERSHIP-REDESIGN.md §4.1). Provides Solution A: a pre-sized ring buffer that eliminates GC allocation on the send hot path when configured via preallocatedSendBuffer.

Designed for send-queue use in Layer 2 transports: pre-allocated once at connection setup, then zero-allocation in steady state. All hot-path methods are @nogc @safe nothrow.

Data is stored in a single contiguous ubyte[] slab. The write position (_head) and read position (_tail) wrap around modulo _capacity. _used tracks the number of live bytes so that the full/empty ambiguity is resolved without wasting a slot.

Layout when partially filled (no wrap): [....TTTTTTTTTHHHH........] ^tail ^head

Layout when wrapped: HHHH........TTTTTTTTTTTT ^head ^tail

Design decision: separate _used counter instead of the traditional "waste one slot" approach. This allows capacity() bytes of usable storage rather than capacity - 1, which matters for send queues where the buffer is sized to match highWaterMark.

struct RingBuffer

Types 1

Fixed-capacity ring buffer for ubyte data.

Allocation occurs once in initialize(). All subsequent operations are @nogc. Call dispose() to release the backing storage.

The struct is non-copyable (@disable this(this)) to prevent accidental duplication of the backing slice. Pass by reference or store as a field in a class.

Buffer Ownership (TERMINOLOGY.md): The backing storage is EVE-Owned after initialize(). append() uses Copy semantics — the caller may reuse or free the source buffer immediately. front() returns a Borrowed slice valid only until the next append() or consume() call.

Fields
ubyte[] _storage
size_t _capacity
size_t _head
size_t _tail
size_t _used
Methods
void initialize(size_t capacity) @trusted nothrowAllocate backing storage for the ring buffer.
void dispose() @trusted nothrowRelease backing storage immediately.
bool append(scope const(ubyte)[] data) @trusted nothrow @nogcAppend data to the buffer.
const(ubyte)[] front() const @trusted nothrow @nogcGet a contiguous view of the front (readable) portion of the buffer.
void consume(size_t n) @safe nothrow @nogcAdvance the read position past `n` consumed bytes.
void clear() @safe nothrow @nogcReset the buffer to empty without releasing storage.
size_t length() const @safe nothrow @nogcNumber of bytes currently stored.
size_t capacity() const @safe nothrow @nogcTotal capacity of the backing storage.
size_t freeSpace() const @safe nothrow @nogcBytes available for future `append()` calls.
bool empty() const @safe nothrow @nogcWhether the buffer contains no data.
bool full() const @safe nothrow @nogcWhether no more data can be appended without consuming first.