summaryrefslogtreecommitdiff
path: root/internal/tui/eventstream/ringbuffer.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-25 08:25:42 +0200
committerPaul Buetow <paul@buetow.org>2026-02-25 08:25:42 +0200
commit8d4f799220632411784037783c9275964df98718 (patch)
treeef6fee8e9d2a0dd32b7a6e3ed96d2eacb711a6bd /internal/tui/eventstream/ringbuffer.go
parent615f305f308c849c1a7b6cadb93e5e520455e422 (diff)
Add thread-safe eventstream ring buffer
Diffstat (limited to 'internal/tui/eventstream/ringbuffer.go')
-rw-r--r--internal/tui/eventstream/ringbuffer.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/internal/tui/eventstream/ringbuffer.go b/internal/tui/eventstream/ringbuffer.go
new file mode 100644
index 0000000..a2ec1dc
--- /dev/null
+++ b/internal/tui/eventstream/ringbuffer.go
@@ -0,0 +1,59 @@
+package eventstream
+
+import "sync"
+
+const ringBufferCapacity = 10000
+
+type RingBuffer struct {
+ mu sync.RWMutex
+ buf []StreamEvent
+ start int
+ size int
+ totalPushed uint64
+}
+
+func NewRingBuffer() *RingBuffer {
+ return &RingBuffer{buf: make([]StreamEvent, ringBufferCapacity)}
+}
+
+func (r *RingBuffer) Push(ev StreamEvent) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ if r.size < ringBufferCapacity {
+ idx := (r.start + r.size) % ringBufferCapacity
+ r.buf[idx] = ev
+ r.size++
+ } else {
+ r.buf[r.start] = ev
+ r.start = (r.start + 1) % ringBufferCapacity
+ }
+ r.totalPushed++
+}
+
+func (r *RingBuffer) Snapshot() []StreamEvent {
+ r.mu.RLock()
+ defer r.mu.RUnlock()
+
+ if r.size == 0 {
+ return make([]StreamEvent, 0)
+ }
+
+ out := make([]StreamEvent, r.size)
+ for i := 0; i < r.size; i++ {
+ out[i] = r.buf[(r.start+i)%ringBufferCapacity]
+ }
+ return out
+}
+
+func (r *RingBuffer) Len() int {
+ r.mu.RLock()
+ defer r.mu.RUnlock()
+ return r.size
+}
+
+func (r *RingBuffer) TotalPushed() uint64 {
+ r.mu.RLock()
+ defer r.mu.RUnlock()
+ return r.totalPushed
+}