Add iterators for mq and npq.
All checks were successful
Build & Test / Main (push) Successful in 13s

This commit is contained in:
Sam Fredrickson 2024-09-07 02:10:40 -07:00
parent c5dde2ab43
commit 9a15ebed25
4 changed files with 80 additions and 0 deletions

View File

@ -28,6 +28,7 @@
package mq package mq
import ( import (
"iter"
"sync" "sync"
"gogs.humancabbage.net/sam/priorityq" "gogs.humancabbage.net/sam/priorityq"
@ -199,3 +200,18 @@ func (s *state[T]) trySend(value T, buf *queue.Q[T]) error {
s.canRecv.Broadcast() s.canRecv.Broadcast()
return nil return nil
} }
// Iter returns an iterator that consumes values until the queue is closed.
func (s *state[T]) Iter() iter.Seq[T] {
return func(yield func(T) bool) {
for {
t, ok := s.Recv()
if !ok {
return
}
if !yield(t) {
return
}
}
}
}

View File

@ -164,6 +164,30 @@ func TestConcProducerConsumer(t *testing.T) {
wg.Wait() wg.Wait()
} }
func TestIter(t *testing.T) {
t.Parallel()
q := mq.Make[int](4)
q.Send(1)
q.Send(2)
q.Send(3)
q.SendHigh(0)
q.Close()
i := 0
for v := range q.Iter() {
if v != i {
t.Errorf("expected %d, got %d", i, v)
}
i++
}
// to test yield() returning false
q = mq.Make[int](4)
q.Send(3)
for _ = range q.Iter() {
break
}
}
func BenchmarkSend(b *testing.B) { func BenchmarkSend(b *testing.B) {
q := mq.Make[int](b.N) q := mq.Make[int](b.N)
b.ResetTimer() b.ResetTimer()

View File

@ -38,6 +38,7 @@ package npq
import ( import (
"fmt" "fmt"
"iter"
"sync" "sync"
"gogs.humancabbage.net/sam/priorityq" "gogs.humancabbage.net/sam/priorityq"
@ -212,3 +213,18 @@ func (s *state[P, T]) validatePriority(priority P) {
priority, s.min, s.max)) priority, s.min, s.max))
} }
} }
// Iter returns an iterator that consumes values until the queue is closed.
func (s *state[P, T]) Iter() iter.Seq[T] {
return func(yield func(T) bool) {
for {
t, ok := s.Recv()
if !ok {
return
}
if !yield(t) {
return
}
}
}
}

View File

@ -186,6 +186,30 @@ func TestConcProducerConsumer(t *testing.T) {
wg.Wait() wg.Wait()
} }
func TestIter(t *testing.T) {
t.Parallel()
q := npq.Make[int, int](4, 0, 16)
q.Send(4, 0)
q.Send(3, 1)
q.Send(2, 2)
q.Send(1, 3)
q.Close()
i := 0
for v := range q.Iter() {
if v != i {
t.Errorf("expected %d, got %d", i, v)
}
i++
}
// to test yield() returning false
q = npq.Make[int, int](4, 0, 16)
q.Send(1, 3)
for _ = range q.Iter() {
break
}
}
const highPriority = 2 const highPriority = 2
func BenchmarkSend(b *testing.B) { func BenchmarkSend(b *testing.B) {