all repos

scratch @ 22fce74

⭐ me doing recreational ~~drugs~~ programming
2 files changed, 112 insertions(+), 0 deletions(-)
algos: queue on top of ring buffer, because performance is cool
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-04-02 13:52:47 +0300
Change ID: zkonnyryrrworrmsulvuvwvutxrtwzuo
Parent: 4eff1eb
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 {