RingBuffer
Defined in: src/util/RingBuffer.ts:39
A first-in-first-out queue whose removal from the front is O(1).
Array.prototype.shift() is O(n): it reindexes every remaining element.
That is invisible on a queue of ten and quadratic on a queue of a hundred
thousand — and since #1148 removed the default mailbox bound, an actor that
falls behind its producers has no ceiling short of the heap. A deep mailbox
was paying one memmove of the whole backlog per message delivered (#408).
This is the standard circular buffer: elements live in a fixed array between
a moving head and head + count, both wrapping at the end, so removing
the front advances an index instead of moving the payload. Growth doubles
the array and re-lays the elements from index 0, which is the one O(n) step
and happens log2(n) times — amortized O(1) per push.
Deliberately not a general-purpose deque. It carries exactly the five operations its callers need — push, shift, pop, unshiftAll and drain — because every extra one is another index-wrapping edge case, and this type sits on the message path of every actor in the system.
Type Parameters
Section titled “Type Parameters”T
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new RingBuffer<
T>():RingBuffer<T>
Returns
Section titled “Returns”RingBuffer<T>
Accessors
Section titled “Accessors”length
Section titled “length”Get Signature
Section titled “Get Signature”get length():
number
Defined in: src/util/RingBuffer.ts:57
Number of queued elements.
Returns
Section titled “Returns”number
Methods
Section titled “Methods”drain()
Section titled “drain()”drain():
T[]
Defined in: src/util/RingBuffer.ts:128
Remove every element and return them in queue order.
Returns a fresh array rather than handing out the backing store: the ring
is not a dense T[] and the caller must not see its holes or its
wrap-around. The backing store is released too, so draining a queue that
grew to a million entries gives the memory back instead of holding a
million empty slots for an actor that is usually shutting down.
Returns
Section titled “Returns”T[]
pop():
T|undefined
Defined in: src/util/RingBuffer.ts:89
Remove and return the back element, or undefined when empty. O(1).
The mirror of shift, and it exists for one caller: a bound that has to make room for something inserted at the front sheds at the back, because that is the end furthest from the arrival (#772). Without it a mailbox could only evict what it was about to deliver.
Returns
Section titled “Returns”T | undefined
push()
Section titled “push()”push(
item):void
Defined in: src/util/RingBuffer.ts:62
Append to the back. Amortized O(1).
Parameters
Section titled “Parameters”T
Returns
Section titled “Returns”void
shift()
Section titled “shift()”shift():
T|undefined
Defined in: src/util/RingBuffer.ts:69
Remove and return the front element, or undefined when empty. O(1).
Returns
Section titled “Returns”T | undefined
unshiftAll()
Section titled “unshiftAll()”unshiftAll(
items):void
Defined in: src/util/RingBuffer.ts:109
Insert items at the FRONT, preserving their order relative to each
other and placing all of them ahead of what is already queued.
One bulk move rather than n individual unshifts, and — unlike
Array.prototype.unshift(...items) — no spread, so a stash replay of a
thousand messages neither reindexes the backlog n times nor pushes a
thousand arguments onto the call stack.
Parameters
Section titled “Parameters”readonly T[]
Returns
Section titled “Returns”void
