Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package ringbuffer is a fixed-capacity FIFO that overwrites its oldest entry when full, as a pure, reusable package.

Readme View source

gno.land/p/moul/x/daily/ringbuffer/v0

Fixed-capacity FIFO that overwrites its oldest entryNew, 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.

Overview

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).

Constants 1

const MaxCap

1const MaxCap = 4096
source

MaxCap bounds a buffer so allocation stays predictable.

Functions 1

func New

1func New(capacity int) *RingBuffer
source

New returns an empty buffer of the given capacity, clamped to [0, MaxCap].

Types 1

type RingBuffer

struct
1type RingBuffer struct {
2	buf  []string
3	head int // index of the oldest element
4	n    int // number of live elements
5}
source

RingBuffer is a fixed-capacity FIFO of strings.

Methods on RingBuffer

func At

method on RingBuffer
1func (r *RingBuffer) At(i int) (v string, ok bool)
source

At returns the i-th element counting from the oldest (0 = oldest).

func Cap

method on RingBuffer
1func (r *RingBuffer) Cap() int
source

Cap returns the capacity.

func Empty

method on RingBuffer
1func (r *RingBuffer) Empty() bool
source

Empty reports whether there is nothing to read.

func Full

method on RingBuffer
1func (r *RingBuffer) Full() bool
source

Full reports whether the next Push will overwrite.

func Len

method on RingBuffer
1func (r *RingBuffer) Len() int
source

Len returns how many elements are live.

func Peek

method on RingBuffer
1func (r *RingBuffer) Peek() (v string, ok bool)
source

Peek returns the oldest element without removing it.

func Pop

method on RingBuffer
1func (r *RingBuffer) Pop() (v string, ok bool)
source

Pop removes and returns the oldest element; ok is false when empty.

func Push

method on RingBuffer
1func (r *RingBuffer) Push(v string) (evicted string, dropped bool)
source

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.

func Reset

method on RingBuffer
1func (r *RingBuffer) Reset()
source

Reset empties the buffer, releasing every stored reference.

func Slice

method on RingBuffer
1func (r *RingBuffer) Slice() []string
source

Slice returns the live elements oldest-first, as an independent copy.

Source Files 3