Fixed-capacity FIFO circular buffer backed by a pre-allocated array.
Not safe for concurrent use. If you need concurrent access, use RingQueue[T].
buf := carousel.NewRingBuffer[int](3)
buf.Push(1)
buf.Push(2)
buf.Push(3)
buf.ForcePush(4)
value, _ := buf.Pop()
fmt.Println(value)
fmt.Println(buf.Drain())NewRingBuffer[T](capacity int) *RingBuffer[T]
Allocates a new buffer of the given capacity. Panics if capacity < 1.
Push(item T) bool
Appends item to the back. Returns false if the buffer is full — the item is not added and the buffer is unchanged.
ForcePush(item T) bool
Appends item to the back. If the buffer is full, the oldest item is silently evicted to make room. Returns true if an eviction occurred.
Pop() (T, bool)
Removes and returns the front item. Returns the zero value of T and false if the buffer is empty.
Peek() (T, bool)
Returns the front item without removing it. Returns the zero value of T and false if the buffer is empty.
Drain() []T
Removes and returns all items in FIFO order. Returns nil if the buffer is empty. Internal slots are zeroed after draining so that held references are released to the GC.
Clear()
Removes all items and zeros all internal slots. Equivalent to Drain but discards the items.
Snapshot() []T
Returns a copy of all items in FIFO order without removing them. Returns nil if the buffer is empty. The returned slice is independent of the buffer; mutations to either do not affect the other. Independence is shallow: if T is a pointer type or contains pointers, the pointed-to values are shared between the snapshot and the buffer.
Len() int
Number of items currently in the buffer.
Cap() int
Maximum number of items the buffer can hold. Fixed at construction time.
Run make bench-sync to refresh these local numbers.
Measured on darwin/arm64 (Apple M1 Max).
| Operation | ns/op | B/op | allocs/op |
|---|---|---|---|
Push |
2.914 | 0 | 0 |
ForcePush |
5.459 | 0 | 0 |
Pop |
2.901 | 0 | 0 |
Drain (256 items) |
1,287 | 6,528 | 1 |
Snapshot (256 items) |
673.3 | 6,528 | 1 |
Snapshot (256 items, wrap) |
599.1 | 6,528 | 1 |
Drain and Snapshot each allocate one []T slice to hold the returned items; all other operations are zero-allocation. Snapshot's wrap variant matches the non-wrap variant within noise — both go through bulk copy, never a per-element loop.