/p/moul/x/daily/ringbuffer/v0
gno.land/p/moul/x/daily/ringbuffer/v0
Fixed-capacity FIFO that overwrites its oldest entry — New, Push, Pop,
Peek, At, Slice, Reset, Len, Cap, Full, Empty, MaxCap.
The bounded cousin of a queue, and the bound is the point: on chain an unbounded queue is an unbounded storage bill, whereas a ring buffer's cost is decided once, at construction. The right shape for "last N events", "recent messages", or any rolling window.
1import "gno.land/p/moul/x/daily/ringbuffer/v0"
2
3r := ringbuffer.New(3)
4r.Push("a"); r.Push("b"); r.Push("c")
5evicted, dropped := r.Push("d") // "a", true
6r.Slice() // ["b" "c" "d"]
Push returns what it evicted, so a rolling window never loses data
silently — the one thing this shape must not do. Backed by a flat slice with
head/length indices: no per-element allocation, no shifting on Pop. Pop and
Reset clear the vacated slots so no reference is pinned after it is logically
gone.
A zero-capacity buffer stores nothing and says so (Push hands the value
straight back), and is never reported as Full — a buffer that holds nothing
cannot be full.
Live demo: r/moul/x/daily/ringbufferdemo
· render it at /r/moul/x/daily/ringbufferdemo/v0.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.