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.