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:
16
circ/lib.go
16
circ/lib.go
@@ -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++
|
||||
|
@@ -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()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user