Various improvements.

* Expand README.md, provide benchmark results.
* Add docs, benchmarks for binheap and circ packages.
* Add methods Len() and Capacity().
* Change *sync.Cond to sync.Cond.
* TryRecv() and TrySend() distinguish empty and closed errors.
* Improve test coverage.
* Add basic Makefile.
* Fix documentation mistakes.
This commit is contained in:
2023-03-02 21:35:17 -08:00
parent b3b491d9a9
commit b00fe25128
12 changed files with 313 additions and 104 deletions

View File

@@ -9,12 +9,22 @@ type B[T any] struct {
tail int
}
// Make creates a new circular buffer.
// Make creates a new buffer.
func Make[T any](cap int) B[T] {
buf := make([]T, cap)
return B[T]{buf: buf}
}
// Capacity returns the total capacity of the buffer.
func (b *B[T]) Capacity() int {
return cap(b.buf)
}
// Len returns the number of items in the buffer.
func (b *B[T]) Len() int {
return b.len
}
// CanPush returns true if the buffer has space for new items.
func (b *B[T]) CanPush() bool {
return cap(b.buf)-b.len != 0
@@ -32,9 +42,9 @@ func (b *B[T]) PopFront() T {
if !b.CanPop() {
panic("cannot pop from empty buffer")
}
var empty T
item := b.buf[b.head]
// clear buffer slot so that we don't hold on to garbage
// clear buffer slot so as not to hold on to garbage
var empty T
b.buf[b.head] = empty
b.len--
b.head++

View File

@@ -1,6 +1,7 @@
package circ_test
import (
"math/rand"
"testing"
"gogs.humancabbage.net/sam/priorityq/circ"
@@ -9,11 +10,17 @@ import (
func TestRepeatPushPop(t *testing.T) {
t.Parallel()
cb := circ.Make[int](4)
if cb.Capacity() != 4 {
t.Errorf("wrong capacity")
}
for i := 0; i < 50; i++ {
cb.PushBack(1)
cb.PushBack(2)
cb.PushBack(3)
cb.PushBack(4)
if cb.Len() != 4 {
t.Errorf("wrong length")
}
checkPop := func(n int) {
if v := cb.PopFront(); v != n {
t.Errorf("popped %d, expected %d", v, n)
@@ -65,3 +72,30 @@ func TestFullPushPanic(t *testing.T) {
cb.PushBack(1)
cb.PushBack(2)
}
func BenchmarkPush(b *testing.B) {
cb := circ.Make[int](b.N)
rs := rand.NewSource(0)
r := rand.New(rs)
items := make([]int, b.N)
for i := 0; i < b.N; i++ {
items[i] = r.Int()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
cb.PushBack(items[i])
}
}
func BenchmarkPop(b *testing.B) {
cb := circ.Make[int](b.N)
rs := rand.NewSource(0)
r := rand.New(rs)
for i := 0; i < b.N; i++ {
cb.PushBack(r.Int())
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
cb.PopFront()
}
}