all repos

scratch @ 22fce74c68f0bb2986216005c93d194c39621527

⭐ 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
Authored at: 2026-03-31 17:31:04 +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 {