-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathringbuffer.go
More file actions
77 lines (67 loc) · 2.05 KB
/
Copy pathringbuffer.go
File metadata and controls
77 lines (67 loc) · 2.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package gds
// RingBuffer is a fixed-capacity circular buffer (FIFO).
// When full, Push returns false and the buffer is unchanged.
// It is not safe for concurrent use.
type RingBuffer[T any] struct {
buf []T
head int // index of the oldest element
tail int // index where the next element will be written
len int
cap int
}
// NewRingBuffer returns an empty RingBuffer with the given capacity.
// Panics if capacity is less than 1.
func NewRingBuffer[T any](capacity int) *RingBuffer[T] {
if capacity < 1 {
panic("gds: RingBuffer capacity must be >= 1")
}
return &RingBuffer[T]{buf: make([]T, capacity), cap: capacity}
}
// Push writes item to the buffer.
// Returns false without modifying the buffer if it is full.
func (r *RingBuffer[T]) Push(item T) bool {
if r.len == r.cap {
return false
}
r.buf[r.tail] = item
r.tail = (r.tail + 1) % r.cap
r.len++
return true
}
// Pop removes and returns the oldest element.
// Returns the zero value and false if the buffer is empty.
func (r *RingBuffer[T]) Pop() (T, bool) {
if r.len == 0 {
var zero T
return zero, false
}
item := r.buf[r.head]
r.buf[r.head] = *new(T) // release reference for GC
r.head = (r.head + 1) % r.cap
r.len--
return item, true
}
// Peek returns the oldest element without removing it.
// Returns the zero value and false if the buffer is empty.
func (r *RingBuffer[T]) Peek() (T, bool) {
if r.len == 0 {
var zero T
return zero, false
}
return r.buf[r.head], true
}
// Len returns the number of elements currently in the buffer.
func (r *RingBuffer[T]) Len() int { return r.len }
// Cap returns the maximum number of elements the buffer can hold.
func (r *RingBuffer[T]) Cap() int { return r.cap }
// IsFull reports whether the buffer is at capacity.
func (r *RingBuffer[T]) IsFull() bool { return r.len == r.cap }
// IsEmpty reports whether the buffer has no elements.
func (r *RingBuffer[T]) IsEmpty() bool { return r.len == 0 }
// Clear discards all elements and resets the buffer.
func (r *RingBuffer[T]) Clear() {
r.buf = make([]T, r.cap)
r.head = 0
r.tail = 0
r.len = 0
}