diff --git a/deque.go b/deque.go index fc18607..ff10996 100644 --- a/deque.go +++ b/deque.go @@ -8,52 +8,33 @@ const minCapacity = 16 // Deque represents a single instance of the deque data structure. A Deque // instance contains items of the type specified by the type argument. -type Deque[T any] struct { - buf []T - head int - tail int - count int - minCap int -} - -// New creates a new Deque, optionally setting the base capacity when a -// non-zero value is given. The returned Deque instance operates on items of -// the type specified by the type argument. For example, to create a Deque that -// contains strings do one of the following: +// +// For example, to create a Deque that contains strings do one of the +// following: // // var stringDeque deque.Deque[string] -// stringDeque := deque.New[string]() -// stringDeque := new(deque.New[string]) +// stringDeque := new(deque.Deque[string]) +// stringDeque := &deque.Deque[string]{} // // To create a Deque that will never resize to have space for less than 64 -// items, specify a base capacity when calling New: +// items, specify a base capacity: // -// d := deque.New[int](64) +// var d deque.Deque[int] +// d.SetBaseCap(64) // // To ensure the Deque can store 1000 items without needing to resize while // items are added: // // d.Grow(1000) // -// Any values supplied here are rounded up to the nearest power of 2, since the -// Deque grows by powers of 2. -func New[T any](initVals ...int) *Deque[T] { - var baseCap int - if len(initVals) >= 1 { - if len(initVals) >= 2 { - panic("Deque.New: too many arguments") - } - baseCap = initVals[0] - } - - minCap := minCapacity - for minCap < baseCap { - minCap <<= 1 - } - - return &Deque[T]{ - minCap: minCap, - } +// Any values supplied to SetBaseCap and Grow are rounded up to the nearest +// power of 2, since the Deque grows by powers of 2. +type Deque[T any] struct { + buf []T + head int + tail int + count int + minCap int } // Cap returns the current capacity of the Deque. If q is nil, q.Cap() is zero. @@ -65,7 +46,7 @@ func (q *Deque[T]) Cap() int { } // Len returns the number of elements currently stored in the queue. If q is -// nil, q.Len() is zero. +// nil, q.Len() returns zero. func (q *Deque[T]) Len() int { if q == nil { return 0 @@ -196,9 +177,9 @@ func (q *Deque[T]) Clear() { q.count = 0 } -// Grow grows the deque's capacity, if necessary, to guarantee space for -// another n items. After Grow(n), at least n items can be written to the -// buffer without another allocation. If n is negative, Grow will panic. +// Grow grows deque's capacity, if necessary, to guarantee space for another n +// items. After Grow(n), at least n items can be written to the deque without +// another allocation. If n is negative, Grow panics. func (q *Deque[T]) Grow(n int) { if n < 0 { panic("deque.Grow: negative count") @@ -373,9 +354,9 @@ func (q *Deque[T]) Remove(at int) T { return q.PopBack() } -// SetBaseCapacity sets a base capacity so that at least the specified number -// of items can always be stored without resizing. -func (q *Deque[T]) SetBaseCapacity(baseCap int) { +// SetBaseCap sets a base capacity so that at least the specified number of +// items can always be stored without resizing. +func (q *Deque[T]) SetBaseCap(baseCap int) { minCap := minCapacity for minCap < baseCap { minCap <<= 1 diff --git a/deque_test.go b/deque_test.go index 70ac3cc..c91e6b4 100644 --- a/deque_test.go +++ b/deque_test.go @@ -7,7 +7,7 @@ import ( ) func TestEmpty(t *testing.T) { - q := New[string]() + q := new(Deque[string]) if q.Len() != 0 { t.Error("q.Len() =", q.Len(), "expect 0") } @@ -252,7 +252,7 @@ func TestBack(t *testing.T) { func TestGrow(t *testing.T) { var q Deque[int] - assertPanics(t, "should panic when calling New with too many args", func() { + assertPanics(t, "should panic when calling Groe with invalid size", func() { q.Grow(-1) }) @@ -286,7 +286,8 @@ func TestGrow(t *testing.T) { func TestNew(t *testing.T) { minCap := 64 - q := New[string](minCap) + q := &Deque[string]{} + q.SetBaseCap(minCap) if q.Cap() != 0 { t.Fatal("should not have allowcated mem yet") } @@ -299,7 +300,8 @@ func TestNew(t *testing.T) { t.Fatalf("worng capactiy expected %d, got %d", minCap, q.Cap()) } curCap := 128 - q = New[string](minCap) + q = new(Deque[string]) + q.SetBaseCap(minCap) q.Grow(curCap) if q.Cap() != curCap { t.Fatalf("Cap() should return %d, got %d", curCap, q.Cap()) @@ -311,10 +313,6 @@ func TestNew(t *testing.T) { if q.Cap() != curCap { t.Fatalf("Cap() should return %d, got %d", curCap, q.Cap()) } - - assertPanics(t, "should panic when calling New with too many args", func() { - New[int](64, 128) - }) } func checkRotate(t *testing.T, size int) { @@ -538,7 +536,7 @@ func TestInsert(t *testing.T) { } } - qs := New[string]() + qs := new(Deque[string]) qs.Grow(16) for i := 0; i < qs.Cap(); i++ { @@ -801,7 +799,7 @@ func TestRemoveOutOfRangePanics(t *testing.T) { func TestSetMBaseapacity(t *testing.T) { var q Deque[string] - q.SetBaseCapacity(200) + q.SetBaseCap(200) q.PushBack("A") if q.minCap != 256 { t.Fatal("wrong minimum capacity") @@ -816,7 +814,7 @@ func TestSetMBaseapacity(t *testing.T) { if q.Cap() != 256 { t.Fatal("wrong buffer size") } - q.SetBaseCapacity(0) + q.SetBaseCap(0) if q.minCap != minCapacity { t.Fatal("wrong minimum capacity") } @@ -914,7 +912,7 @@ func BenchmarkYoyo(b *testing.B) { func BenchmarkYoyoFixed(b *testing.B) { var q Deque[int] - q.SetBaseCapacity(64000) + q.SetBaseCap(64000) for i := 0; i < b.N; i++ { for j := 0; j < 65536; j++ { q.PushBack(j)