From 335ef4d8e8ce7be33d79e541105ac7be72c2b3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Sat, 5 Oct 2024 01:28:46 +0200 Subject: [PATCH] v0.0.523 ringbuffer --- dataext/ringBuffer.go | 92 +++++++++++++++++++++++++++++++++++++++++++ goextVersion.go | 4 +- 2 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 dataext/ringBuffer.go diff --git a/dataext/ringBuffer.go b/dataext/ringBuffer.go new file mode 100644 index 0000000..2697848 --- /dev/null +++ b/dataext/ringBuffer.go @@ -0,0 +1,92 @@ +package dataext + +import "iter" + +type RingBuffer[T any] struct { + items []T // + capacity int // max number of items the buffer can hold + size int // how many items are in the buffer + head int // ptr to next item +} + +func NewRingBuffer[T any](capacity int) *RingBuffer[T] { + return &RingBuffer[T]{ + items: make([]T, capacity), + capacity: capacity, + size: 0, + head: 0, + } +} + +func (rb *RingBuffer[T]) Push(item T) { + if rb.size < rb.capacity { + rb.size++ + } + rb.items[rb.head] = item + rb.head = (rb.head + 1) % rb.capacity +} + +func (rb *RingBuffer[T]) Peek() (T, bool) { + if rb.size == 0 { + return *new(T), false + } + return rb.items[(rb.head-1+rb.capacity)%rb.capacity], true +} + +func (rb *RingBuffer[T]) Items() []T { + if rb.size < rb.capacity { + return rb.items[:rb.size] + } + return append(rb.items[rb.head:], rb.items[:rb.head]...) +} + +func (rb *RingBuffer[T]) Size() int { + return rb.size +} + +func (rb *RingBuffer[T]) Capacity() int { + return rb.capacity +} + +func (rb *RingBuffer[T]) Clear() { + rb.size = 0 + rb.head = 0 +} + +func (rb *RingBuffer[T]) IsFull() bool { + return rb.size == rb.capacity +} + +func (rb *RingBuffer[T]) At(i int) T { + if i < 0 || i >= rb.size { + panic("Index out of bounds") + } + return rb.items[(rb.head+i)%rb.capacity] +} + +func (rb *RingBuffer[T]) Get(i int) (T, bool) { + if i < 0 || i >= rb.size { + return *new(T), false + } + return rb.items[(rb.head+i)%rb.capacity], true +} + +func (rb *RingBuffer[T]) Iter() iter.Seq[T] { + return func(yield func(T) bool) { + for i := 0; i < rb.size; i++ { + if !yield(rb.At(i)) { + return + } + } + } +} + +func (rb *RingBuffer[T]) Iter2() iter.Seq2[int, T] { + return func(yield func(int, T) bool) { + for i := 0; i < rb.size; i++ { + if !yield(i, rb.At(i)) { + return + } + } + } +} diff --git a/goextVersion.go b/goextVersion.go index 2194e31..b099fd4 100644 --- a/goextVersion.go +++ b/goextVersion.go @@ -1,5 +1,5 @@ package goext -const GoextVersion = "0.0.522" +const GoextVersion = "0.0.523" -const GoextVersionTimestamp = "2024-10-05T01:12:00+0200" +const GoextVersionTimestamp = "2024-10-05T01:28:46+0200"