ilusm.dev

ring

Ring buffer (circular buffer) with fixed capacity - push a value (automatically overwrites the oldest entry when full), pop from the head, peek the head or tail, random-access by index, query size and capacity, check empty/full state, snapshot all items as a list in insertion order, clear, and iterate with a callback.

Load with: use ring

What this module does

A ring buffer is a fixed-size FIFO where new items always fit - when the buffer is full, the oldest item is silently discarded to make room. This makes ring ideal for sliding windows, recent-event logs, audio/video sample buffers, and any producer/consumer pattern where bounded memory is more important than lossless retention.

Internally the buffer is a pre-allocated list with head and tail pointers that wrap around using modular arithmetic.

Quick example

use ring

# Create a ring buffer with capacity 4
r = rgnew(4)

# Push items
r = rgpsh(r, "a")
r = rgpsh(r, "b")
r = rgpsh(r, "c")
r = rgpsh(r, "d")
r = rgpsh(r, "e")   # overwrites "a" (buffer was full)

prn(rgls(r))        # ["b", "c", "d", "e"]
prn(rgsz(r))        # 4
prn(rgfl(r))        # tru (full)

prn(rgpek(r))       # "b" (head)
prn(rglst(r))       # "e" (tail)
prn(rgat(r, 1))     # "c"

# Pop
val = rgpop(r)      # "b"

# Iterate
rgech(r, \(v) prn(v))

# Clear
r = rgclr(r)

Functions

Write

rgnew(cap) / ring.new(cap)

Creates a new ring buffer with integer capacity cap. Pre-allocates a nil-filled list.

rgpsh(r, val) / ring.psh(r, val)

Pushes val onto the tail. If the buffer is full, the head (oldest) item is overwritten and the head advances.

rgclr(r) / ring.clr(r)

Resets the buffer to empty without changing capacity.

Read

rgpop(r) / ring.pop(r)

Removes and returns the head (oldest) item. Returns nil if empty.

rgpek(r) / ring.pek(r)

Returns the head item without removing it. Returns nil if empty.

rglst(r) / ring.lst(r)

Returns the tail (most recently pushed) item without modifying the buffer.

rgat(r, i) / ring.at(r, i)

Returns the item at logical index i (0 = oldest). Returns nil if out of bounds.

rgls(r) / ring.ls(r)

Returns a snapshot list of all current items in insertion order (oldest first).

State

rgsz(r) / ring.sz(r)

Current number of items in the buffer.

rgcp(r)

Buffer capacity.

rgmt(r) / ring.mt(r)

Returns tru if the buffer is empty.

rgfl(r) / ring.fl(r)

Returns tru if the buffer is full.

Iteration

rgech(r, fn) / ring.ech(r, fn)

Calls fn(item) for each item in insertion order (oldest first).

Notes

  • Requires trl.