const MaxCap
MaxCap bounds a buffer so allocation stays predictable.
Package ringbuffer is a fixed-capacity FIFO that overwrites its oldest entry when full, as a pure, reusable package.
gno.land/p/moul/x/daily/ringbuffer/v0Fixed-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.
Package ringbuffer is a fixed-capacity FIFO that overwrites its oldest entry when full, as a pure, reusable package.
This is the bounded cousin of an unbounded 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. It is the right shape for "last N events", "recent messages", or any rolling window.
Backed by a flat slice with head/length indices — no per-element allocation, no shifting on Pop.
A live demo of this package is at r/moul/x/daily/ringbufferdemo(/r/moul/x/daily/ringbufferdemo/v0).
RingBuffer is a fixed-capacity FIFO of strings.
At returns the i-th element counting from the oldest (0 = oldest).
Cap returns the capacity.
Empty reports whether there is nothing to read.
Full reports whether the next Push will overwrite.
Len returns how many elements are live.
Peek returns the oldest element without removing it.
Pop removes and returns the oldest element; ok is false when empty.
Push appends v. When the buffer is full the OLDEST element is dropped to make room, and that element is returned with dropped=true — losing data silently is the one thing a rolling window must not do.
A zero-capacity buffer accepts nothing and reports the value straight back.
Reset empties the buffer, releasing every stored reference.
Slice returns the live elements oldest-first, as an independent copy.