2 files changed,
112 insertions(+),
0 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-04-02 13:52:47 +0300
Change ID:
zkonnyryrrworrmsulvuvwvutxrtwzuo
Parent:
4eff1eb
jump to
| M | algos/queue.go |
| M | algos/queue_test.go |
M
algos/queue.go
··· 41 41 q.Len-- 42 42 return res, true 43 43 } 44 + 45 +/// Ring buffer based 46 + 47 +type RQueue[T any] struct { 48 + buf []T 49 + head, tail int 50 + Len int 51 +} 52 + 53 +func (q *RQueue[T]) Enqueue(v T) { 54 + if q.Len == len(q.buf) { 55 + q.grow() 56 + } 57 + q.buf[q.tail] = v 58 + q.tail = (q.tail + 1) % len(q.buf) 59 + q.Len++ 60 +} 61 + 62 +func (q *RQueue[T]) Peek() T { 63 + return q.buf[q.head] 64 +} 65 + 66 +func (q *RQueue[T]) Dequeue() (T, bool) { 67 + var zero T 68 + if q.Len == 0 { 69 + return zero, false 70 + } 71 + v := q.buf[q.head] 72 + q.buf[q.head] = zero 73 + q.head = (q.head + 1) % len(q.buf) 74 + q.Len-- 75 + return v, true 76 +} 77 + 78 +func (q *RQueue[T]) grow() { 79 + newCap := max(8, len(q.buf)*2) 80 + newBuf := make([]T, newCap) 81 + if q.head < q.tail { 82 + copy(newBuf, q.buf[q.head:q.tail]) 83 + } else { 84 + head := copy(newBuf, q.buf[q.head:]) 85 + copy(newBuf[head:], q.buf[:q.tail]) 86 + } 87 + q.head = 0 88 + q.tail = q.Len 89 + q.buf = newBuf 90 +}
M
algos/queue_test.go
··· 43 43 is(t, v, 69420) 44 44 } 45 45 46 +func TestRQueue(t *testing.T) { 47 + q := RQueue[int]{} 48 + 49 + q.Enqueue(5) 50 + q.Enqueue(7) 51 + q.Enqueue(9) 52 + 53 + v, ok := q.Dequeue() 54 + is(t, ok, true) 55 + is(t, v, 5) 56 + 57 + is(t, q.Len, 2) 58 + 59 + q.Enqueue(11) 60 + 61 + v, ok = q.Dequeue() 62 + is(t, ok, true) 63 + is(t, v, 7) 64 + 65 + v, ok = q.Dequeue() 66 + is(t, ok, true) 67 + is(t, v, 9) 68 + 69 + is(t, q.Peek(), 11) 70 + 71 + v, ok = q.Dequeue() 72 + is(t, ok, true) 73 + is(t, v, 11) 74 + 75 + _, ok = q.Dequeue() 76 + is(t, ok, false) 77 + 78 + // everything works after removing all elements 79 + q.Enqueue(69420) 80 + is(t, q.Peek(), 69420) 81 + 82 + v, ok = q.Dequeue() 83 + is(t, ok, true) 84 + is(t, v, 69420) 85 +} 86 + 87 +func BenchmarkQueue(b *testing.B) { 88 + q := &Queue[int]{} 89 + for range 256 { 90 + q.Push(1) 91 + } 92 + 93 + for b.Loop() { 94 + q.Push(1) 95 + q.Pop() 96 + } 97 +} 98 + 99 +func BenchmarkRQueue(b *testing.B) { 100 + q := &RQueue[int]{} 101 + for range 256 { 102 + q.Enqueue(1) 103 + } 104 + 105 + for b.Loop() { 106 + q.Enqueue(1) 107 + q.Dequeue() 108 + } 109 +} 110 + 46 111 func is[T comparable](tb testing.TB, a, b T) { 47 112 tb.Helper() 48 113 if a != b {