diff --git a/.travis.yml b/.travis.yml index ff0d458..9bad2ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,11 @@ go: - "1.13.x" - "1.14.x" - "1.15.x" + - "1.16.x" + - "1.17.x" + - "1.18.x" + - "1.19.x" + - "1.20.x" - tip before_install: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b34faf..5e42e71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,3 +31,8 @@ # 1.0.4 - Fixed bug related to PushFront/PopBack: [here](https://github.com/ef-ds/deque/pull/21) - The minor change had no significant performance impact + +# 2.0.0 +- Updated Deque to support generics! +- This is a breaking change and will require users to specify the desired data type used with Deque (such as Deque[int]). We recommend the users to update their existing code to use the specific data type the Deque needs to handle (such as int, string, etc), but the interface type can still be used. Just declare Deque as "var d deque.Deque[interface{}]" and use it normally. No other changes should be required to use Deque v2.0.0. +- Deque v2 is up to 10% faster and uses up to 35% less memory it used to use in most test cases! Benchmark tests: [v1.0.3 vs v2.0.0](testdata/release_v2.0.0.md); [comparison tests](https://github.com/ef-ds/deque-bench-tests/blob/master/PERFORMANCE.md) diff --git a/README.md b/README.md index e7c3021..487eedc 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,6 @@ From a configured [Go environment](https://golang.org/doc/install#testing): go get -u github.com/ef-ds/deque ``` -If you are using dep: -```sh -dep ensure -add github.com/ef-ds/deque@1.0.4 -``` - We recommend to target only released versions for production use. @@ -30,7 +25,7 @@ import ( ) func main() { - var d deque.Deque + var d deque.Deque[int] for i := 1; i <= 5; i++ { d.PushBack(i) @@ -64,7 +59,7 @@ import ( ) func main() { - var d deque.Deque + var d deque.Deque[int] for i := 1; i <= 5; i++ { d.PushBack(i) @@ -87,6 +82,9 @@ Output: Also refer to the [integration](integration_test.go) and [API](api_test.go) tests. +## Generics + +Starting with v2.0.0, Deque supports generics. Looking for a previous non-generic stable release? Check out version [1.0.4](https://github.com/ef-ds/deque/releases/tag/v1.0.4). ## Tests diff --git a/api_test.go b/api_test.go index 1429510..9b412ec 100644 --- a/api_test.go +++ b/api_test.go @@ -27,16 +27,16 @@ import ( ) func TestPopFrontWithZeroValueShouldReturnReadyToUseDeque(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] d.PushBack(1) d.PushBack(2) v, ok := d.PopFront() - if !ok || v.(int) != 1 { + if !ok || v != 1 { t.Errorf("Expected: 1; Got: %d", v) } v, ok = d.PopFront() - if !ok || v.(int) != 2 { + if !ok || v != 2 { t.Errorf("Expected: 2; Got: %d", v) } _, ok = d.PopFront() @@ -46,16 +46,16 @@ func TestPopFrontWithZeroValueShouldReturnReadyToUseDeque(t *testing.T) { } func TestPopBackWithZeroValueShouldReturnReadyToUseDeque(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] d.PushBack(1) d.PushBack(2) v, ok := d.PopBack() - if !ok || v.(int) != 2 { + if !ok || v != 2 { t.Errorf("Expected: 2; Got: %d", v) } v, ok = d.PopBack() - if !ok || v.(int) != 1 { + if !ok || v != 1 { t.Errorf("Expected: 1; Got: %d", v) } _, ok = d.PopBack() @@ -65,7 +65,7 @@ func TestPopBackWithZeroValueShouldReturnReadyToUseDeque(t *testing.T) { } func TestWithZeroValueAndEmptyShouldReturnAsEmpty(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] if _, ok := d.Front(); ok { t.Error("Expected: false as the queue is empty; Got: true") } @@ -84,7 +84,7 @@ func TestWithZeroValueAndEmptyShouldReturnAsEmpty(t *testing.T) { } func TestInitShouldReturnEmptyDeque(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] d.PushBack(1) d.Init() @@ -107,7 +107,7 @@ func TestInitShouldReturnEmptyDeque(t *testing.T) { } func TestPopFrontWithNilValuesShouldReturnAllValuesInOrder(t *testing.T) { - d := deque.New() + d := deque.New[interface{}]() d.PushBack(1) d.PushBack(nil) d.PushBack(2) @@ -136,7 +136,7 @@ func TestPopFrontWithNilValuesShouldReturnAllValuesInOrder(t *testing.T) { } func TestPopBackWithNilValuesShouldReturnAllValuesInOrder(t *testing.T) { - d := deque.New() + d := deque.New[interface{}]() d.PushBack(1) d.PushBack(nil) d.PushBack(2) diff --git a/benchmark_test.go b/benchmark_test.go index 4492dc5..2dbb2fb 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -52,7 +52,7 @@ var ( } // Used to store temp values, avoiding any compiler optimizations. - tmp interface{} + tmp *testData tmp2 bool fillCount = 10000 @@ -63,7 +63,7 @@ func BenchmarkFillQueue(b *testing.B) { for _, test := range tests { b.Run(strconv.Itoa(test.count), func(b *testing.B) { for n := 0; n < b.N; n++ { - q := deque.New() + q := deque.New[*testData]() for i := 0; i < test.count; i++ { q.PushBack(nil) } @@ -79,7 +79,7 @@ func BenchmarkFillStack(b *testing.B) { for _, test := range tests { b.Run(strconv.Itoa(test.count), func(b *testing.B) { for n := 0; n < b.N; n++ { - q := deque.New() + q := deque.New[*testData]() for i := 0; i < test.count; i++ { q.PushFront(nil) } @@ -100,7 +100,7 @@ func BenchmarkRefillQueue(b *testing.B) { } b.Run(strconv.Itoa(test.count), func(b *testing.B) { - q := deque.New() + q := deque.New[*testData]() for n := 0; n < b.N; n++ { for n := 0; n < refillCount; n++ { for i := 0; i < test.count; i++ { @@ -118,7 +118,7 @@ func BenchmarkRefillQueue(b *testing.B) { func BenchmarkRefillStack(b *testing.B) { for _, test := range tests { b.Run(strconv.Itoa(test.count), func(b *testing.B) { - q := deque.New() + q := deque.New[*testData]() for n := 0; n < b.N; n++ { for n := 0; n < refillCount; n++ { for i := 0; i < test.count; i++ { @@ -134,7 +134,7 @@ func BenchmarkRefillStack(b *testing.B) { } func BenchmarkRefillFullQueue(b *testing.B) { - d := deque.New() + d := deque.New[*testData]() for i := 0; i < fillCount; i++ { d.PushBack(nil) } @@ -166,7 +166,7 @@ func BenchmarkRefillFullQueue(b *testing.B) { } func BenchmarkRefillFullStack(b *testing.B) { - d := deque.New() + d := deque.New[*testData]() for i := 0; i < fillCount; i++ { d.PushBack(nil) } @@ -192,7 +192,7 @@ func BenchmarkRefillFullStack(b *testing.B) { } func BenchmarkStableQueue(b *testing.B) { - d := deque.New() + d := deque.New[*testData]() for i := 0; i < fillCount; i++ { d.PushBack(nil) } @@ -214,7 +214,7 @@ func BenchmarkStableQueue(b *testing.B) { } func BenchmarkStableStack(b *testing.B) { - d := deque.New() + d := deque.New[*testData]() for i := 0; i < fillCount; i++ { d.PushBack(nil) } @@ -239,7 +239,7 @@ func BenchmarkSlowIncreaseQueue(b *testing.B) { for _, test := range tests { b.Run(strconv.Itoa(test.count), func(b *testing.B) { for n := 0; n < b.N; n++ { - d := deque.New() + d := deque.New[*testData]() for i := 0; i < test.count; i++ { d.PushBack(nil) d.PushBack(nil) @@ -257,7 +257,7 @@ func BenchmarkSlowIncreaseStack(b *testing.B) { for _, test := range tests { b.Run(strconv.Itoa(test.count), func(b *testing.B) { for n := 0; n < b.N; n++ { - d := deque.New() + d := deque.New[*testData]() for i := 0; i < test.count; i++ { d.PushFront(nil) d.PushFront(nil) @@ -272,7 +272,7 @@ func BenchmarkSlowIncreaseStack(b *testing.B) { } func BenchmarkSlowDecreaseQueue(b *testing.B) { - d := deque.New() + d := deque.New[*testData]() for _, test := range tests { items := test.count / 2 for i := 0; i <= items; i++ { @@ -300,7 +300,7 @@ func BenchmarkSlowDecreaseQueue(b *testing.B) { } func BenchmarkSlowDecreaseStack(b *testing.B) { - d := deque.New() + d := deque.New[*testData]() for _, test := range tests { items := test.count / 2 for i := 0; i <= items; i++ { @@ -336,7 +336,7 @@ func BenchmarkMicroserviceQueue(b *testing.B) { b.Run(strconv.Itoa(test.count), func(b *testing.B) { for n := 0; n < b.N; n++ { - d := deque.New() + d := deque.New[*testData]() // Simulate stable traffic for i := 0; i < test.count; i++ { @@ -395,7 +395,7 @@ func BenchmarkMicroserviceStack(b *testing.B) { b.Run(strconv.Itoa(test.count), func(b *testing.B) { for n := 0; n < b.N; n++ { - d := deque.New() + d := deque.New[*testData]() // Simulate stable traffic for i := 0; i < test.count; i++ { diff --git a/deque.go b/deque.go index 8c1b639..64c1255 100644 --- a/deque.go +++ b/deque.go @@ -60,13 +60,13 @@ const ( // Deque implements an unbounded, dynamically growing double-ended-queue (deque). // The zero value for deque is an empty deque ready to use. -type Deque struct { +type Deque[T any] struct { // Head points to the first node of the linked list. - head *node + head *node[T] // Tail points to the last node of the linked list. // In an empty deque, head and tail points to the same node. - tail *node + tail *node[T] // Hp is the index pointing to the current first element in the deque // (i.e. first element added in the current deque values). @@ -84,43 +84,45 @@ type Deque struct { // spareLinks holds the number of already used, but now empty, ready-to-be-reused, slices. spareLinks int + + tZero T } // Node represents a deque node. // Each node holds a slice of user managed values. -type node struct { +type node[T any] struct { // v holds the list of user added values in this node. - v []interface{} + v []T // n points to the next node in the linked list. - n *node + n *node[T] // p points to the previous node in the linked list. - p *node + p *node[T] } // New returns an initialized deque. -func New() *Deque { - return new(Deque) +func New[T any]() *Deque[T] { + return new(Deque[T]) } // Init initializes or clears deque d. -func (d *Deque) Init() *Deque { - *d = Deque{} +func (d *Deque[T]) Init() *Deque[T] { + *d = Deque[T]{} return d } // Len returns the number of elements of deque d. // The complexity is O(1). -func (d *Deque) Len() int { return d.len } +func (d *Deque[T]) Len() int { return d.len } // Front returns the first element of deque d or nil if the deque is empty. // The second, bool result indicates whether a valid value was returned; // if the deque is empty, false will be returned. // The complexity is O(1). -func (d *Deque) Front() (interface{}, bool) { +func (d *Deque[T]) Front() (T, bool) { if d.len == 0 { - return nil, false + return d.tZero, false } return d.head.v[d.hp], true } @@ -129,20 +131,20 @@ func (d *Deque) Front() (interface{}, bool) { // The second, bool result indicates whether a valid value was returned; // if the deque is empty, false will be returned. // The complexity is O(1). -func (d *Deque) Back() (interface{}, bool) { +func (d *Deque[T]) Back() (T, bool) { if d.len == 0 { - return nil, false + return d.tZero, false } return d.tail.v[d.tp-1], true } // PushFront adds value v to the the front of the deque. // The complexity is O(1). -func (d *Deque) PushFront(v interface{}) { +func (d *Deque[T]) PushFront(v T) { switch { case d.head == nil: // No nodes present yet. - h := &node{v: make([]interface{}, firstSliceSize)} + h := &node[T]{v: make([]T, firstSliceSize)} h.n = h h.p = h d.head = h @@ -167,7 +169,7 @@ func (d *Deque) PushFront(v interface{}) { // The first slice hasn't grown big enough yet. l := len(d.head.v) nl := l * sliceGrowthFactor - n := make([]interface{}, nl) + n := make([]T, nl) diff := nl - l d.tp += diff d.hp += diff @@ -183,7 +185,7 @@ func (d *Deque) PushFront(v interface{}) { d.hlp = d.hp default: // No available nodes, so make one. - n := &node{v: make([]interface{}, maxInternalSliceSize)} + n := &node[T]{v: make([]T, maxInternalSliceSize)} n.n = d.head n.p = d.tail d.head.p = n @@ -198,11 +200,11 @@ func (d *Deque) PushFront(v interface{}) { // PushBack adds value v to the the back of the deque. // The complexity is O(1). -func (d *Deque) PushBack(v interface{}) { +func (d *Deque[T]) PushBack(v T) { switch { case d.head == nil: // No nodes present yet. - h := &node{v: make([]interface{}, firstSliceSize)} + h := &node[T]{v: make([]T, firstSliceSize)} h.n = h h.p = h d.head = h @@ -216,7 +218,7 @@ func (d *Deque) PushBack(v interface{}) { d.tp++ case d.tp < maxFirstSliceSize: // We're on the first slice and it hasn't grown large enough yet. - nv := make([]interface{}, len(d.tail.v)*sliceGrowthFactor) + nv := make([]T, len(d.tail.v)*sliceGrowthFactor) copy(nv, d.tail.v) d.tail.v = nv d.tail.v[d.tp] = v @@ -231,7 +233,7 @@ func (d *Deque) PushBack(v interface{}) { d.tp = 1 default: // No available nodes, so make one. - n := &node{v: make([]interface{}, maxInternalSliceSize)} + n := &node[T]{v: make([]T, maxInternalSliceSize)} n.n = d.head n.p = d.tail d.tail.n = n @@ -247,13 +249,13 @@ func (d *Deque) PushBack(v interface{}) { // The second, bool result indicates whether a valid value was returned; // if the deque is empty, false will be returned. // The complexity is O(1). -func (d *Deque) PopFront() (interface{}, bool) { +func (d *Deque[T]) PopFront() (T, bool) { if d.len == 0 { - return nil, false + return d.tZero, false } vp := &d.head.v[d.hp] v := *vp - *vp = nil // Avoid memory leaks + *vp = d.tZero // Avoid memory leaks d.len-- switch { case d.hp < d.hlp: @@ -285,15 +287,15 @@ func (d *Deque) PopFront() (interface{}, bool) { // The second, bool result indicates whether a valid value was returned; // if the deque is empty, false will be returned. // The complexity is O(1). -func (d *Deque) PopBack() (interface{}, bool) { +func (d *Deque[T]) PopBack() (T, bool) { if d.len == 0 { - return nil, false + return d.tZero, false } d.len-- d.tp-- vp := &d.tail.v[d.tp] v := *vp - *vp = nil // Avoid memory leaks + *vp = d.tZero // Avoid memory leaks switch { case d.tp > 0: // There's space before tp. diff --git a/doc_test.go b/doc_test.go index fee4439..1927229 100644 --- a/doc_test.go +++ b/doc_test.go @@ -7,7 +7,7 @@ import ( ) func Example_fIFOQueue() { - var d deque.Deque + var d deque.Deque[int] for i := 1; i <= 5; i++ { d.PushBack(i) } @@ -19,7 +19,7 @@ func Example_fIFOQueue() { } func Example_stack() { - var d deque.Deque + var d deque.Deque[int] for i := 1; i <= 5; i++ { d.PushBack(i) } diff --git a/go.mod b/go.mod index 4369ebf..71c51cc 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/ef-ds/deque -go 1.15 +go 1.18 diff --git a/integration_test.go b/integration_test.go index e5f5c9f..55039bc 100644 --- a/integration_test.go +++ b/integration_test.go @@ -31,13 +31,13 @@ const ( ) func TestFillQueueShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } for i := 0; i < pushCount; i++ { - if v, ok := d.PopFront(); !ok || v.(int) != i { + if v, ok := d.PopFront(); !ok || v != i { t.Errorf("Expected: %d; Got: %d", i, v) } } @@ -47,14 +47,14 @@ func TestFillQueueShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestRefillQueueShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < refillCount; i++ { for j := 0; j < pushCount; j++ { d.PushBack(j) } for j := 0; j < pushCount; j++ { - if v, ok := d.PopFront(); !ok || v.(int) != j { + if v, ok := d.PopFront(); !ok || v != j { t.Errorf("Expected: %d; Got: %d", i, v) } } @@ -65,7 +65,7 @@ func TestRefillQueueShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestRefillFullQueueShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } @@ -75,7 +75,7 @@ func TestRefillFullQueueShouldRetrieveAllElementsInOrder(t *testing.T) { d.PushBack(j) } for j := 0; j < pushCount; j++ { - if v, ok := d.PopFront(); !ok || v.(int) != j { + if v, ok := d.PopFront(); !ok || v != j { t.Errorf("Expected: %d; Got: %d", j, v) } } @@ -86,7 +86,7 @@ func TestRefillFullQueueShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestSlowIncreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] count := 0 for i := 0; i < pushCount; i++ { @@ -94,7 +94,7 @@ func TestSlowIncreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { d.PushBack(count) count++ d.PushBack(count) - if v, ok := d.PopFront(); !ok || v.(int) != i+1 { + if v, ok := d.PopFront(); !ok || v != i+1 { t.Errorf("Expected: %d; Got: %d", i+1, v) } } @@ -104,7 +104,7 @@ func TestSlowIncreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestSlowDecreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] push := 0 for i := 0; i < pushCount; i++ { d.PushBack(push) @@ -114,11 +114,11 @@ func TestSlowDecreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { count := -1 for i := 0; i < pushCount-1; i++ { count++ - if v, ok := d.PopFront(); !ok || v.(int) != count { + if v, ok := d.PopFront(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } count++ - if v, ok := d.PopFront(); !ok || v.(int) != count { + if v, ok := d.PopFront(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } @@ -126,7 +126,7 @@ func TestSlowDecreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { push++ } count++ - if v, ok := d.PopFront(); !ok || v.(int) != count { + if v, ok := d.PopFront(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } if d.Len() != 0 { @@ -135,11 +135,11 @@ func TestSlowDecreaseQueueShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestStableQueueShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) - if v, ok := d.PopFront(); !ok || v.(int) != i { + if v, ok := d.PopFront(); !ok || v != i { t.Errorf("Expected: %d; Got: %d", i, v) } } @@ -149,7 +149,7 @@ func TestStableQueueShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestStableQueueFullShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } @@ -157,7 +157,7 @@ func TestStableQueueFullShouldRetrieveAllElementsInOrder(t *testing.T) { count := 0 for i := 0; i < pushCount-1; i++ { d.PushBack(i) - if v, ok := d.PopFront(); !ok || v.(int) != count { + if v, ok := d.PopFront(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } count++ @@ -168,13 +168,13 @@ func TestStableQueueFullShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestFillStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } for i := pushCount - 1; i >= 0; i-- { - if v, ok := d.PopBack(); !ok || v.(int) != i { + if v, ok := d.PopBack(); !ok || v != i { t.Errorf("Expected: %d; Got: %d", i, v) } } @@ -184,14 +184,14 @@ func TestFillStackShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestRefillStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < refillCount; i++ { for j := 0; j < pushCount; j++ { d.PushBack(j) } for j := pushCount - 1; j >= 0; j-- { - if v, ok := d.PopBack(); !ok || v.(int) != j { + if v, ok := d.PopBack(); !ok || v != j { t.Errorf("Expected: %d; Got: %d", i, v) } } @@ -202,7 +202,7 @@ func TestRefillStackShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestRefillFullStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } @@ -212,7 +212,7 @@ func TestRefillFullStackShouldRetrieveAllElementsInOrder(t *testing.T) { d.PushBack(j) } for j := pushCount - 1; j >= 0; j-- { - if v, ok := d.PopBack(); !ok || v.(int) != j { + if v, ok := d.PopBack(); !ok || v != j { t.Errorf("Expected: %d; Got: %d", j, v) } } @@ -223,7 +223,7 @@ func TestRefillFullStackShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestSlowIncreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] count := 0 for i := 0; i < pushCount; i++ { @@ -231,7 +231,7 @@ func TestSlowIncreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { d.PushBack(count) count++ d.PushBack(count) - if v, ok := d.PopBack(); !ok || v.(int) != count { + if v, ok := d.PopBack(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } } @@ -241,7 +241,7 @@ func TestSlowIncreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestSlowDecreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] push := 0 for i := 0; i < pushCount; i++ { d.PushBack(push) @@ -251,11 +251,11 @@ func TestSlowDecreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { count := push for i := 0; i < pushCount-1; i++ { count-- - if v, ok := d.PopBack(); !ok || v.(int) != count { + if v, ok := d.PopBack(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } count-- - if v, ok := d.PopBack(); !ok || v.(int) != count { + if v, ok := d.PopBack(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } @@ -263,7 +263,7 @@ func TestSlowDecreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { count++ } count-- - if v, ok := d.PopBack(); !ok || v.(int) != count { + if v, ok := d.PopBack(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } if d.Len() != 0 { @@ -272,11 +272,11 @@ func TestSlowDecreaseStackShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestStableStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) - if v, ok := d.PopBack(); !ok || v.(int) != i { + if v, ok := d.PopBack(); !ok || v != i { t.Errorf("Expected: %d; Got: %d", i, v) } } @@ -286,7 +286,7 @@ func TestStableStackShouldRetrieveAllElementsInOrder(t *testing.T) { } func TestStableFullStackShouldRetrieveAllElementsInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } @@ -294,7 +294,7 @@ func TestStableFullStackShouldRetrieveAllElementsInOrder(t *testing.T) { count := 0 for i := 0; i < pushCount; i++ { d.PushBack(i) - if v, ok := d.PopFront(); !ok || v.(int) != count { + if v, ok := d.PopFront(); !ok || v != count { t.Errorf("Expected: %d; Got: %d", count, v) } count++ @@ -307,13 +307,13 @@ func TestStableFullStackShouldRetrieveAllElementsInOrder(t *testing.T) { func TestPushPopFrontShouldRetrieveAllElementsInOrder(t *testing.T) { pushPopFrontBackShouldRetrieveAllElementsInOrder( t, - func(d *deque.Deque) (interface{}, bool) { + func(d *deque.Deque[int]) (int, bool) { return d.PopFront() }, - func(d *deque.Deque) (interface{}, bool) { + func(d *deque.Deque[int]) (int, bool) { return d.Front() }, - func(v, lastGet, lastPut interface{}) bool { + func(v, lastGet, lastPut int) bool { return v == lastGet }, ) @@ -322,20 +322,20 @@ func TestPushPopFrontShouldRetrieveAllElementsInOrder(t *testing.T) { func TestPushPopBackShouldRetrieveAllElementsInOrder(t *testing.T) { pushPopFrontBackShouldRetrieveAllElementsInOrder( t, - func(d *deque.Deque) (interface{}, bool) { + func(d *deque.Deque[int]) (int, bool) { return d.PopBack() }, - func(d *deque.Deque) (interface{}, bool) { + func(d *deque.Deque[int]) (int, bool) { return d.Back() }, - func(v, lastGet, lastPut interface{}) bool { + func(v, lastGet, lastPut int) bool { return v == lastPut }, ) } func TestMixedPushBackPopFrontBackShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushBack(i) } @@ -357,8 +357,8 @@ func TestMixedPushBackPopFrontBackShouldReturnAllValuesInOrder(t *testing.T) { } count++ } - if v, ok := d.PopBack(); ok || v != nil { - t.Errorf("Expected: nil; Got: %d", v) + if _, ok := d.PopBack(); ok { + t.Errorf("Expected: !ok; Got: %t", ok) } if d.Len() != 0 { t.Errorf("Expected: 0; Got: %d", d.Len()) @@ -366,7 +366,7 @@ func TestMixedPushBackPopFrontBackShouldReturnAllValuesInOrder(t *testing.T) { } func TestMixedPushFrontPopFrontBackShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { d.PushFront(i) } @@ -388,8 +388,8 @@ func TestMixedPushFrontPopFrontBackShouldReturnAllValuesInOrder(t *testing.T) { } count++ } - if v, ok := d.PopBack(); ok || v != nil { - t.Errorf("Expected: nil; Got: %d", v) + if _, ok := d.PopBack(); ok { + t.Errorf("Expected: !ok; Got: %t", ok) } if d.Len() != 0 { t.Errorf("Expected: 0; Got: %d", d.Len()) @@ -397,7 +397,7 @@ func TestMixedPushFrontPopFrontBackShouldReturnAllValuesInOrder(t *testing.T) { } func TestMixedPushFrontBackPopFrontShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { if i%2 == 0 { @@ -424,8 +424,8 @@ func TestMixedPushFrontBackPopFrontShouldReturnAllValuesInOrder(t *testing.T) { expectedValue = 1 } } - if v, ok := d.PopFront(); ok || v != nil { - t.Errorf("Expected: nil; Got: %d", v) + if _, ok := d.PopFront(); ok { + t.Errorf("Expected: ok; Got: %t", ok) } if d.Len() != 0 { t.Errorf("Expected: 0; Got: %d", d.Len()) @@ -433,7 +433,7 @@ func TestMixedPushFrontBackPopFrontShouldReturnAllValuesInOrder(t *testing.T) { } func TestMixedPushFrontBackPopBackShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < pushCount; i++ { if i%2 == 0 { @@ -458,8 +458,8 @@ func TestMixedPushFrontBackPopBackShouldReturnAllValuesInOrder(t *testing.T) { expectedValue = 0 } } - if v, ok := d.PopBack(); ok || v != nil { - t.Errorf("Expected: nil; Got: %d", v) + if _, ok := d.PopBack(); ok { + t.Errorf("Expected: !ok; Got: %t", ok) } if d.Len() != 0 { t.Errorf("Expected: 0; Got: %d", d.Len()) @@ -467,7 +467,7 @@ func TestMixedPushFrontBackPopBackShouldReturnAllValuesInOrder(t *testing.T) { } func TestPushFrontPopFrontRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < refillCount; i++ { for k := 0; k < pushCount; k++ { @@ -476,7 +476,7 @@ func TestPushFrontPopFrontRefillWith0ToPushCountItemsShouldReturnAllValuesInOrde } for j := k; j > 0; j-- { v, ok := d.PopFront() - if !ok || v == nil || v.(int) != j-1 { + if !ok || v != j-1 { t.Errorf("Expected: %d; Got: %d", j-1, v) } } @@ -488,7 +488,7 @@ func TestPushFrontPopFrontRefillWith0ToPushCountItemsShouldReturnAllValuesInOrde } func TestPushFrontPopBackRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < refillCount; i++ { for k := 0; k < pushCount; k++ { @@ -497,7 +497,7 @@ func TestPushFrontPopBackRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder } for j := 0; j < k; j++ { v, ok := d.PopBack() - if !ok || v == nil || v.(int) != j { + if !ok || v != j { t.Errorf("Expected: %d; Got: %d", j, v) } } @@ -509,7 +509,7 @@ func TestPushFrontPopBackRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder } func TestPushBackPopFrontRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < refillCount; i++ { for k := 1; k < pushCount; k++ { @@ -518,7 +518,7 @@ func TestPushBackPopFrontRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder } for j := 0; j < k; j++ { v, ok := d.PopFront() - if !ok || v == nil || v.(int) != j { + if !ok || v != j { t.Errorf("Expected: %d; Got: %d", j, v) } } @@ -530,7 +530,7 @@ func TestPushBackPopFrontRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder } func TestPushBackPopBackRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder(t *testing.T) { - var d deque.Deque + var d deque.Deque[int] for i := 0; i < refillCount; i++ { for k := 1; k < pushCount; k++ { @@ -539,7 +539,7 @@ func TestPushBackPopBackRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder( } for j := k; j > 0; j-- { v, ok := d.PopBack() - if !ok || v == nil || v.(int) != j-1 { + if !ok || v != j-1 { t.Errorf("Expected: %d; Got: %d", j-1, v) } } @@ -552,7 +552,7 @@ func TestPushBackPopBackRefillWith0ToPushCountItemsShouldReturnAllValuesInOrder( // Helper methods ------------------------------------------------ -func pushPopFrontBackShouldRetrieveAllElementsInOrder(t *testing.T, popFunc, frontbackFunc func(*deque.Deque) (interface{}, bool), checkValueFunc func(v, lastGet, lastPut interface{}) bool) { +func pushPopFrontBackShouldRetrieveAllElementsInOrder(t *testing.T, popFunc, frontbackFunc func(*deque.Deque[int]) (int, bool), checkValueFunc func(v, lastGet, lastPut int) bool) { tests := map[string]struct { putCount []int getCount []int @@ -585,11 +585,11 @@ func pushPopFrontBackShouldRetrieveAllElementsInOrder(t *testing.T, popFunc, fro for name, test := range tests { t.Run(name, func(t *testing.T) { - d := deque.New() + d := deque.New[int]() lastPut := 0 lastGet := 0 var ok bool - var v interface{} + var v int for count := 0; count < len(test.getCount); count++ { for i := 1; i <= test.putCount[count]; i++ { lastPut++ @@ -602,11 +602,11 @@ func pushPopFrontBackShouldRetrieveAllElementsInOrder(t *testing.T, popFunc, fro for i := 1; i <= test.getCount[count]; i++ { lastGet++ v, ok = frontbackFunc(d) - if !ok || !checkValueFunc(v.(int), lastGet, lastPut-lastGet+1) { + if !ok || !checkValueFunc(v, lastGet, lastPut-lastGet+1) { t.Errorf("Expected: %d; Got: %d or %d", lastGet, lastPut-lastGet+1, v) } v, ok = popFunc(d) - if !ok || !checkValueFunc(v.(int), lastGet, lastPut-lastGet+1) { + if !ok || !checkValueFunc(v, lastGet, lastPut-lastGet+1) { t.Errorf("Expected: %d; Got: %d or %d", lastGet, lastPut-lastGet+1, v) } } @@ -615,11 +615,11 @@ func pushPopFrontBackShouldRetrieveAllElementsInOrder(t *testing.T, popFunc, fro if d.Len() != 0 { t.Errorf("Expected: %d; Got: %d", 0, d.Len()) } - if v, ok = frontbackFunc(d); ok || v != nil { - t.Errorf("Expected: nil as the queue should be empty; Got: %d", v) + if v, ok = frontbackFunc(d); ok { + t.Errorf("Expected: !ok as the queue should be empty; Got: %t", ok) } - if v, ok = popFunc(d); ok || v != nil { - t.Errorf("Expected: nil as the queue should be empty; Got: %d", v) + if v, ok = popFunc(d); ok { + t.Errorf("Expected: !ok as the queue should be empty; Got: %t", ok) } }) } diff --git a/testdata/release_v2.0.0.md b/testdata/release_v2.0.0.md new file mode 100644 index 0000000..4750340 --- /dev/null +++ b/testdata/release_v2.0.0.md @@ -0,0 +1,420 @@ + +# v1.0.3 vs v2.0.0 +## Fill tests +### FIFO queue +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkFillDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkFillDequeQueue.txt +name old time/op new time/op delta +/0-4 41.1ns ± 1% 40.5ns ± 0% -1.42% (p=0.000 n=8+8) +/1-4 168ns ± 2% 160ns ± 1% -4.62% (p=0.000 n=10+10) +/10-4 579ns ± 1% 621ns ±24% ~ (p=0.730 n=9+9) +/100-4 4.65µs ± 1% 4.15µs ± 6% -10.67% (p=0.000 n=9+9) +/1000-4 36.6µs ± 0% 34.3µs ± 2% -6.39% (p=0.000 n=9+10) +/10000-4 368µs ± 1% 346µs ± 1% -6.02% (p=0.000 n=10+9) +/100000-4 3.78ms ± 0% 3.84ms ± 0% +1.54% (p=0.000 n=8+9) +/1000000-4 44.3ms ± 1% 42.1ms ± 2% -4.92% (p=0.000 n=10+9) + +name old alloc/op new alloc/op delta +/0-4 64.0B ± 0% 64.0B ± 0% ~ (all equal) +/1-4 192B ± 0% 160B ± 0% -16.67% (p=0.000 n=10+10) +/10-4 592B ± 0% 432B ± 0% -27.03% (p=0.000 n=10+10) +/100-4 7.20kB ± 0% 4.48kB ± 0% -37.78% (p=0.000 n=10+10) +/1000-4 34.0kB ± 0% 25.2kB ± 0% -26.05% (p=0.000 n=10+10) +/10000-4 323kB ± 0% 243kB ± 0% -24.93% (p=0.002 n=8+10) +/100000-4 3.22MB ± 0% 2.42MB ± 0% -24.88% (p=0.000 n=9+10) +/1000000-4 32.2MB ± 0% 24.2MB ± 0% -24.85% (p=0.000 n=10+10) + +name old allocs/op new allocs/op delta +/0-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/1-4 4.00 ± 0% 4.00 ± 0% ~ (all equal) +/10-4 14.0 ± 0% 14.0 ± 0% ~ (all equal) +/100-4 107 ± 0% 107 ± 0% ~ (all equal) +/1000-4 1.01k ± 0% 1.01k ± 0% ~ (all equal) +/10000-4 10.1k ± 0% 10.1k ± 0% ~ (all equal) +/100000-4 101k ± 0% 101k ± 0% ~ (all equal) +/1000000-4 1.01M ± 0% 1.01M ± 0% ~ (all equal) +``` +### LIFO stack +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkFillDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkFillDequeStack.txt +name old time/op new time/op delta +/0-4 40.4ns ± 0% 40.0ns ± 1% -1.09% (p=0.000 n=10+9) +/1-4 163ns ± 0% 158ns ± 2% -3.27% (p=0.000 n=9+9) +/10-4 578ns ± 0% 555ns ± 2% -4.04% (p=0.000 n=10+9) +/100-4 4.59µs ± 0% 4.13µs ± 2% -10.10% (p=0.000 n=8+9) +/1000-4 36.1µs ± 0% 35.0µs ± 7% -3.25% (p=0.003 n=8+10) +/10000-4 365µs ± 1% 349µs ± 2% -4.38% (p=0.000 n=10+10) +/100000-4 3.77ms ± 0% 3.86ms ± 1% +2.44% (p=0.000 n=10+9) +/1000000-4 43.9ms ± 1% 42.3ms ± 3% -3.70% (p=0.000 n=10+10) + +name old alloc/op new alloc/op delta +/0-4 64.0B ± 0% 64.0B ± 0% ~ (all equal) +/1-4 192B ± 0% 160B ± 0% -16.67% (p=0.000 n=10+10) +/10-4 592B ± 0% 432B ± 0% -27.03% (p=0.000 n=10+10) +/100-4 7.20kB ± 0% 4.48kB ± 0% -37.78% (p=0.000 n=10+10) +/1000-4 34.0kB ± 0% 25.2kB ± 0% -26.05% (p=0.000 n=10+10) +/10000-4 323kB ± 0% 243kB ± 0% -24.93% (p=0.002 n=8+10) +/100000-4 3.22MB ± 0% 2.42MB ± 0% -24.88% (p=0.000 n=10+10) +/1000000-4 32.2MB ± 0% 24.2MB ± 0% -24.85% (p=0.000 n=10+9) + +name old allocs/op new allocs/op delta +/0-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/1-4 4.00 ± 0% 4.00 ± 0% ~ (all equal) +/10-4 14.0 ± 0% 14.0 ± 0% ~ (all equal) +/100-4 107 ± 0% 107 ± 0% ~ (all equal) +/1000-4 1.01k ± 0% 1.01k ± 0% ~ (all equal) +/10000-4 10.1k ± 0% 10.1k ± 0% ~ (all equal) +/100000-4 101k ± 0% 101k ± 0% ~ (all equal) +/1000000-4 1.01M ± 0% 1.01M ± 0% ~ (all equal) +``` + +## Microservice tests +### FIFO queue +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkMicroserviceDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkMicroserviceDequeQueue.txt +name old time/op new time/op delta +/0-4 44.3ns ± 0% 45.9ns ± 2% +3.52% (p=0.000 n=9+9) +/1-4 456ns ± 0% 429ns ± 1% -5.78% (p=0.000 n=9+9) +/10-4 2.80µs ± 0% 2.70µs ± 1% -3.61% (p=0.000 n=9+9) +/100-4 24.2µs ± 0% 23.8µs ± 1% -1.82% (p=0.000 n=9+10) +/1000-4 226µs ± 1% 229µs ± 5% ~ (p=0.247 n=10+10) +/10000-4 2.37ms ± 4% 2.32ms ± 3% ~ (p=0.052 n=10+10) +/100000-4 26.2ms ± 1% 25.7ms ± 1% -1.91% (p=0.000 n=10+10) +/1000000-4 266ms ± 1% 274ms ± 1% +2.94% (p=0.000 n=10+10) + +name old alloc/op new alloc/op delta +/0-4 64.0B ± 0% 64.0B ± 0% ~ (all equal) +/1-4 544B ± 0% 384B ± 0% -29.41% (p=0.000 n=10+10) +/10-4 2.58kB ± 0% 1.90kB ± 0% -26.09% (p=0.000 n=10+10) +/100-4 20.9kB ± 0% 16.2kB ± 0% -22.77% (p=0.000 n=10+10) +/1000-4 134kB ± 0% 123kB ± 0% -8.13% (p=0.000 n=10+10) +/10000-4 1.43MB ± 0% 1.28MB ± 0% -10.77% (p=0.000 n=10+10) +/100000-4 14.4MB ± 0% 12.8MB ± 0% -11.05% (p=0.000 n=9+10) +/1000000-4 144MB ± 0% 128MB ± 0% -11.08% (p=0.000 n=10+10) + +name old allocs/op new allocs/op delta +/0-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/1-4 11.0 ± 0% 11.0 ± 0% ~ (all equal) +/10-4 75.0 ± 0% 75.0 ± 0% ~ (all equal) +/100-4 709 ± 0% 709 ± 0% ~ (all equal) +/1000-4 7.01k ± 0% 7.01k ± 0% ~ (all equal) +/10000-4 70.2k ± 0% 70.2k ± 0% ~ (all equal) +/100000-4 702k ± 0% 702k ± 0% ~ (all equal) +/1000000-4 7.02M ± 0% 7.02M ± 0% ~ (p=0.332 n=10+10) +``` +### LIFO stack +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkMicroserviceDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkMicroserviceDequeStack.txt +name old time/op new time/op delta +/0-4 45.3ns ± 6% 45.3ns ± 1% ~ (p=0.156 n=10+9) +/1-4 384ns ±12% 356ns ± 0% -7.37% (p=0.000 n=10+9) +/10-4 2.60µs ± 2% 2.50µs ± 1% -3.89% (p=0.000 n=9+10) +/100-4 29.3µs ±80% 22.8µs ± 1% -21.95% (p=0.000 n=9+10) +/1000-4 228µs ± 8% 221µs ± 1% -3.19% (p=0.000 n=8+8) +/10000-4 2.70ms ±14% 2.28ms ± 2% -15.66% (p=0.000 n=10+9) +/100000-4 27.2ms ±17% 24.8ms ± 0% -8.94% (p=0.000 n=9+8) +/1000000-4 265ms ± 1% 267ms ± 1% ~ (p=0.075 n=10+10) + +name old alloc/op new alloc/op delta +/0-4 64.0B ± 0% 64.0B ± 0% ~ (all equal) +/1-4 288B ± 0% 256B ± 0% -11.11% (p=0.000 n=10+10) +/10-4 1.55kB ± 0% 1.39kB ± 0% -10.31% (p=0.000 n=10+10) +/100-4 16.8kB ± 0% 14.1kB ± 0% -16.19% (p=0.000 n=10+10) +/1000-4 130kB ± 0% 121kB ± 0% -6.82% (p=0.000 n=10+10) +/10000-4 1.42MB ± 0% 1.27MB ± 0% -10.55% (p=0.000 n=10+10) +/100000-4 14.4MB ± 0% 12.8MB ± 0% -11.04% (p=0.000 n=10+9) +/1000000-4 144MB ± 0% 128MB ± 0% -11.08% (p=0.000 n=10+8) + +name old allocs/op new allocs/op delta +/0-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/1-4 10.0 ± 0% 10.0 ± 0% ~ (all equal) +/10-4 74.0 ± 0% 74.0 ± 0% ~ (all equal) +/100-4 707 ± 0% 707 ± 0% ~ (all equal) +/1000-4 7.01k ± 0% 7.01k ± 0% ~ (all equal) +/10000-4 70.2k ± 0% 70.2k ± 0% ~ (all equal) +/100000-4 702k ± 0% 702k ± 0% ~ (all equal) +/1000000-4 7.02M ± 0% 7.02M ± 0% ~ (p=0.871 n=10+10) +``` + +## Other tests +### FIFO queue +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillDequeQueue.txt +name old time/op new time/op delta +/1-4 3.61µs ± 0% 3.86µs ± 7% +7.04% (p=0.000 n=10+9) +/10-4 34.9µs ± 1% 34.7µs ± 3% ~ (p=0.258 n=9+9) +/100-4 346µs ± 3% 334µs ± 2% -3.37% (p=0.002 n=10+10) +/1000-4 3.38ms ± 2% 3.28ms ± 2% -2.84% (p=0.001 n=10+10) +/10000-4 37.6ms ± 7% 35.5ms ± 5% -5.60% (p=0.000 n=10+10) +/100000-4 384ms ± 2% 417ms ±10% +8.61% (p=0.000 n=8+10) + +name old alloc/op new alloc/op delta +/1-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/10-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/100-4 160kB ± 0% 160kB ± 0% -0.00% (p=0.000 n=10+8) +/1000-4 1.60MB ± 0% 1.60MB ± 0% -0.00% (p=0.000 n=7+10) +/10000-4 30.1MB ± 0% 23.1MB ± 0% -23.17% (p=0.000 n=10+9) +/100000-4 320MB ± 0% 241MB ± 0% -24.70% (p=0.000 n=9+10) + +name old allocs/op new allocs/op delta +/1-4 100 ± 0% 100 ± 0% ~ (all equal) +/10-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/100-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/1000-4 100k ± 0% 100k ± 0% ~ (all equal) +/10000-4 1.01M ± 0% 1.01M ± 0% -0.00% (p=0.000 n=10+10) +/100000-4 10.1M ± 0% 10.1M ± 0% -0.00% (p=0.028 n=10+10) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillFullDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillFullDequeQueue.txt +name old time/op new time/op delta +/1-4 3.41µs ± 0% 3.53µs ± 1% +3.53% (p=0.000 n=9+10) +/10-4 34.2µs ± 1% 34.1µs ± 0% ~ (p=0.887 n=10+7) +/100-4 334µs ± 1% 333µs ± 1% ~ (p=0.095 n=10+9) +/1000-4 3.33ms ± 1% 3.32ms ± 1% -0.44% (p=0.040 n=9+9) +/10000-4 36.9ms ± 0% 35.3ms ± 1% -4.38% (p=0.000 n=9+8) +/100000-4 376ms ± 0% 387ms ± 1% +3.06% (p=0.000 n=8+9) + +name old alloc/op new alloc/op delta +/1-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/10-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/100-4 160kB ± 0% 160kB ± 0% ~ (all equal) +/1000-4 1.60MB ± 0% 1.60MB ± 0% -0.00% (p=0.016 n=10+10) +/10000-4 30.1MB ± 0% 23.1MB ± 0% -23.16% (p=0.000 n=10+10) +/100000-4 320MB ± 0% 241MB ± 0% -24.70% (p=0.000 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 100 ± 0% 100 ± 0% ~ (all equal) +/10-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/100-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/1000-4 100k ± 0% 100k ± 0% ~ (all equal) +/10000-4 1.01M ± 0% 1.01M ± 0% -0.00% (p=0.001 n=9+10) +/100000-4 10.1M ± 0% 10.1M ± 0% -0.00% (p=0.000 n=8+9) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowIncreaseDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowIncreaseDequeQueue.txt +name old time/op new time/op delta +/1-4 234ns ±21% 192ns ± 0% -18.01% (p=0.000 n=10+10) +/10-4 1.14µs ± 4% 1.03µs ± 0% -10.13% (p=0.000 n=9+9) +/100-4 7.83µs ± 1% 7.28µs ± 0% -7.06% (p=0.000 n=10+9) +/1000-4 69.3µs ± 1% 67.4µs ± 1% -2.78% (p=0.000 n=10+10) +/10000-4 688µs ± 0% 688µs ± 6% ~ (p=0.190 n=9+9) +/100000-4 8.11ms ± 1% 7.55ms ± 2% -7.00% (p=0.000 n=9+10) +/1000000-4 82.1ms ± 1% 82.6ms ± 1% +0.58% (p=0.004 n=10+9) + +name old alloc/op new alloc/op delta +/1-4 208B ± 0% 176B ± 0% -15.38% (p=0.000 n=10+10) +/10-4 1.78kB ± 0% 1.10kB ± 0% -37.84% (p=0.000 n=10+10) +/100-4 8.80kB ± 0% 6.08kB ± 0% -30.91% (p=0.000 n=10+10) +/1000-4 54.2kB ± 0% 43.3kB ± 0% -20.14% (p=0.000 n=10+10) +/10000-4 487kB ± 0% 405kB ± 0% -16.95% (p=0.000 n=10+8) +/100000-4 4.82MB ± 0% 4.02MB ± 0% -16.62% (p=0.000 n=10+8) +/1000000-4 48.2MB ± 0% 40.2MB ± 0% -16.60% (p=0.000 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 5.00 ± 0% 5.00 ± 0% ~ (all equal) +/10-4 25.0 ± 0% 25.0 ± 0% ~ (all equal) +/100-4 207 ± 0% 207 ± 0% ~ (all equal) +/1000-4 2.02k ± 0% 2.02k ± 0% ~ (all equal) +/10000-4 20.1k ± 0% 20.1k ± 0% ~ (all equal) +/100000-4 201k ± 0% 201k ± 0% ~ (all equal) +/1000000-4 2.01M ± 0% 2.01M ± 0% ~ (all equal) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowDecreaseDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowDecreaseDequeQueue.txt +name old time/op new time/op delta +/1-4 35.8ns ± 4% 34.9ns ± 2% -2.66% (p=0.000 n=9+9) +/10-4 375ns ± 6% 352ns ± 1% -6.22% (p=0.000 n=10+9) +/100-4 3.60µs ± 2% 3.43µs ± 1% -4.58% (p=0.000 n=9+10) +/1000-4 36.2µs ± 5% 34.2µs ± 1% -5.40% (p=0.000 n=10+9) +/10000-4 364µs ± 8% 342µs ± 1% -6.00% (p=0.000 n=9+10) +/100000-4 3.51ms ± 1% 3.42ms ± 0% -2.43% (p=0.000 n=10+9) +/1000000-4 35.2ms ± 1% 34.2ms ± 1% -2.65% (p=0.000 n=10+9) + +name old alloc/op new alloc/op delta +/1-4 16.0B ± 0% 16.0B ± 0% ~ (all equal) +/10-4 160B ± 0% 160B ± 0% ~ (all equal) +/100-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/1000-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/10000-4 160kB ± 0% 160kB ± 0% ~ (all equal) +/100000-4 1.60MB ± 0% 1.60MB ± 0% -0.00% (p=0.011 n=10+10) +/1000000-4 16.0MB ± 0% 16.0MB ± 0% -0.00% (p=0.011 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/10-4 10.0 ± 0% 10.0 ± 0% ~ (all equal) +/100-4 100 ± 0% 100 ± 0% ~ (all equal) +/1000-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/10000-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/100000-4 100k ± 0% 100k ± 0% ~ (all equal) +/1000000-4 1.00M ± 0% 1.00M ± 0% ~ (all equal) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkStableDequeQueuev1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkStableDequeQueue.txt +name old time/op new time/op delta +/1-4 33.4ns ± 2% 34.2ns ± 1% +2.18% (p=0.002 n=9+9) +/10-4 339ns ± 1% 345ns ± 2% +1.77% (p=0.000 n=9+10) +/100-4 3.45µs ± 6% 3.34µs ± 1% ~ (p=0.122 n=10+8) +/1000-4 33.1µs ± 1% 33.5µs ± 1% +1.12% (p=0.001 n=9+10) +/10000-4 332µs ± 1% 335µs ± 0% +0.72% (p=0.004 n=10+8) +/100000-4 3.30ms ± 1% 3.35ms ± 1% +1.34% (p=0.000 n=10+10) +/1000000-4 33.1ms ± 1% 33.5ms ± 1% +1.06% (p=0.006 n=10+9) + +name old alloc/op new alloc/op delta +/1-4 16.0B ± 0% 16.0B ± 0% ~ (all equal) +/10-4 160B ± 0% 160B ± 0% ~ (all equal) +/100-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/1000-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/10000-4 160kB ± 0% 160kB ± 0% ~ (all equal) +/100000-4 1.60MB ± 0% 1.60MB ± 0% ~ (p=0.982 n=10+10) +/1000000-4 16.0MB ± 0% 16.0MB ± 0% ~ (p=0.065 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/10-4 10.0 ± 0% 10.0 ± 0% ~ (all equal) +/100-4 100 ± 0% 100 ± 0% ~ (all equal) +/1000-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/10000-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/100000-4 100k ± 0% 100k ± 0% ~ (all equal) +/1000000-4 1.00M ± 0% 1.00M ± 0% ~ (all equal) +``` + +### LIFO stack +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillDequeStack.txt +name old time/op new time/op delta +/1-4 4.08µs ±15% 3.98µs ±14% ~ (p=0.367 n=10+9) +/10-4 36.3µs ± 4% 37.5µs ±22% ~ (p=0.968 n=9+10) +/100-4 350µs ± 3% 389µs ±21% +11.04% (p=0.003 n=8+10) +/1000-4 3.49ms ± 3% 3.28ms ± 1% -5.99% (p=0.000 n=10+9) +/10000-4 38.0ms ± 5% 34.6ms ± 1% -9.09% (p=0.000 n=10+9) +/100000-4 397ms ± 2% 387ms ± 1% -2.55% (p=0.000 n=8+10) + +name old alloc/op new alloc/op delta +/1-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/10-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/100-4 160kB ± 0% 160kB ± 0% -0.00% (p=0.000 n=10+10) +/1000-4 1.60MB ± 0% 1.60MB ± 0% -0.00% (p=0.000 n=9+10) +/10000-4 30.1MB ± 0% 23.1MB ± 0% -23.14% (p=0.000 n=8+10) +/100000-4 320MB ± 0% 241MB ± 0% -24.71% (p=0.000 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 100 ± 0% 100 ± 0% ~ (all equal) +/10-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/100-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/1000-4 100k ± 0% 100k ± 0% ~ (all equal) +/10000-4 1.01M ± 0% 1.01M ± 0% -0.00% (p=0.001 n=9+10) +/100000-4 10.1M ± 0% 10.1M ± 0% -0.00% (p=0.001 n=10+10) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillFullDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkRefillFullDequeStack.txt +name old time/op new time/op delta +/1-4 3.40µs ± 1% 3.48µs ± 1% +2.40% (p=0.000 n=10+10) +/10-4 33.5µs ± 1% 33.6µs ± 1% ~ (p=0.720 n=10+9) +/100-4 332µs ± 1% 326µs ± 0% -1.74% (p=0.000 n=8+9) +/1000-4 3.31ms ± 1% 3.25ms ± 1% -1.77% (p=0.000 n=7+9) +/10000-4 36.6ms ± 1% 34.8ms ± 1% -4.87% (p=0.000 n=9+10) +/100000-4 371ms ± 0% 384ms ± 1% +3.46% (p=0.000 n=9+9) + +name old alloc/op new alloc/op delta +/1-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/10-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/100-4 160kB ± 0% 160kB ± 0% ~ (all equal) +/1000-4 1.60MB ± 0% 1.60MB ± 0% -0.00% (p=0.003 n=10+9) +/10000-4 30.1MB ± 0% 23.1MB ± 0% -23.14% (p=0.000 n=10+9) +/100000-4 320MB ± 0% 241MB ± 0% -24.71% (p=0.000 n=9+10) + +name old allocs/op new allocs/op delta +/1-4 100 ± 0% 100 ± 0% ~ (all equal) +/10-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/100-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/1000-4 100k ± 0% 100k ± 0% ~ (all equal) +/10000-4 1.01M ± 0% 1.01M ± 0% -0.00% (p=0.033 n=10+10) +/100000-4 10.1M ± 0% 10.1M ± 0% -0.00% (p=0.000 n=9+10) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowIncreaseDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowIncreaseDequeStack.txt +name old time/op new time/op delta +/1-4 198ns ± 0% 198ns ± 2% ~ (p=0.493 n=10+10) +/10-4 925ns ±10% 908ns ± 1% ~ (p=0.481 n=9+8) +/100-4 8.35µs ± 5% 7.60µs ± 2% -9.06% (p=0.000 n=10+10) +/1000-4 70.1µs ± 3% 68.7µs ± 1% -1.92% (p=0.003 n=10+9) +/10000-4 722µs ± 3% 715µs ± 1% ~ (p=0.083 n=10+8) +/100000-4 8.08ms ± 3% 7.98ms ±11% ~ (p=0.143 n=10+10) +/1000000-4 81.0ms ± 1% 83.7ms ± 2% +3.35% (p=0.000 n=10+10) + +name old alloc/op new alloc/op delta +/1-4 208B ± 0% 176B ± 0% -15.38% (p=0.000 n=10+10) +/10-4 752B ± 0% 592B ± 0% -21.28% (p=0.000 n=10+10) +/100-4 8.80kB ± 0% 6.08kB ± 0% -30.91% (p=0.000 n=10+10) +/1000-4 50.0kB ± 0% 41.2kB ± 0% -17.72% (p=0.000 n=10+10) +/10000-4 483kB ± 0% 403kB ± 0% -16.67% (p=0.000 n=8+10) +/100000-4 4.82MB ± 0% 4.02MB ± 0% -16.62% (p=0.000 n=10+9) +/1000000-4 48.2MB ± 0% 40.2MB ± 0% -16.60% (p=0.000 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 5.00 ± 0% 5.00 ± 0% ~ (all equal) +/10-4 24.0 ± 0% 24.0 ± 0% ~ (all equal) +/100-4 207 ± 0% 207 ± 0% ~ (all equal) +/1000-4 2.01k ± 0% 2.01k ± 0% ~ (all equal) +/10000-4 20.1k ± 0% 20.1k ± 0% ~ (all equal) +/100000-4 201k ± 0% 201k ± 0% ~ (all equal) +/1000000-4 2.01M ± 0% 2.01M ± 0% ~ (all equal) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowDecreaseDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkSlowDecreaseDequeStack.txt +name old time/op new time/op delta +/1-4 35.2ns ± 1% 34.7ns ± 1% -1.44% (p=0.000 n=10+10) +/10-4 356ns ± 1% 353ns ± 1% -0.63% (p=0.019 n=8+10) +/100-4 3.48µs ± 0% 3.42µs ± 0% -1.69% (p=0.000 n=8+8) +/1000-4 34.8µs ± 1% 34.0µs ± 1% -2.19% (p=0.000 n=9+10) +/10000-4 348µs ± 1% 340µs ± 1% -2.38% (p=0.000 n=9+10) +/100000-4 3.55ms ± 5% 3.41ms ± 1% -3.87% (p=0.000 n=10+9) +/1000000-4 35.4ms ± 7% 34.2ms ± 1% -3.56% (p=0.000 n=9+9) + +name old alloc/op new alloc/op delta +/1-4 16.0B ± 0% 16.0B ± 0% ~ (all equal) +/10-4 160B ± 0% 160B ± 0% ~ (all equal) +/100-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/1000-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/10000-4 160kB ± 0% 160kB ± 0% ~ (all equal) +/100000-4 1.60MB ± 0% 1.60MB ± 0% -0.00% (p=0.023 n=8+9) +/1000000-4 16.0MB ± 0% 16.0MB ± 0% -0.00% (p=0.041 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/10-4 10.0 ± 0% 10.0 ± 0% ~ (all equal) +/100-4 100 ± 0% 100 ± 0% ~ (all equal) +/1000-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/10000-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/100000-4 100k ± 0% 100k ± 0% ~ (all equal) +/1000000-4 1.00M ± 0% 1.00M ± 0% ~ (all equal) +``` +``` +benchstat ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkStableDequeStackv1.0.3.txt ./../../../ef-ds/deque-bench-tests/testdata/BenchmarkStableDequeStack.txt +name old time/op new time/op delta +/1-4 32.8ns ± 1% 33.7ns ± 1% +2.72% (p=0.000 n=10+8) +/10-4 332ns ± 1% 339ns ± 1% +2.19% (p=0.000 n=9+10) +/100-4 3.24µs ± 1% 3.33µs ± 2% +2.82% (p=0.000 n=8+9) +/1000-4 33.2µs ± 7% 32.5µs ± 1% ~ (p=0.360 n=10+8) +/10000-4 322µs ± 2% 325µs ± 1% +0.69% (p=0.034 n=10+8) +/100000-4 3.23ms ± 1% 3.26ms ± 1% +1.05% (p=0.001 n=10+10) +/1000000-4 32.2ms ± 1% 32.5ms ± 1% +0.84% (p=0.003 n=10+10) + +name old alloc/op new alloc/op delta +/1-4 16.0B ± 0% 16.0B ± 0% ~ (all equal) +/10-4 160B ± 0% 160B ± 0% ~ (all equal) +/100-4 1.60kB ± 0% 1.60kB ± 0% ~ (all equal) +/1000-4 16.0kB ± 0% 16.0kB ± 0% ~ (all equal) +/10000-4 160kB ± 0% 160kB ± 0% ~ (all equal) +/100000-4 1.60MB ± 0% 1.60MB ± 0% ~ (p=0.127 n=10+10) +/1000000-4 16.0MB ± 0% 16.0MB ± 0% -0.00% (p=0.018 n=10+10) + +name old allocs/op new allocs/op delta +/1-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) +/10-4 10.0 ± 0% 10.0 ± 0% ~ (all equal) +/100-4 100 ± 0% 100 ± 0% ~ (all equal) +/1000-4 1.00k ± 0% 1.00k ± 0% ~ (all equal) +/10000-4 10.0k ± 0% 10.0k ± 0% ~ (all equal) +/100000-4 100k ± 0% 100k ± 0% ~ (all equal) +/1000000-4 1.00M ± 0% 1.00M ± 0% ~ (all equal) +``` diff --git a/unit_test.go b/unit_test.go index 4051c40..44aef19 100644 --- a/unit_test.go +++ b/unit_test.go @@ -31,12 +31,12 @@ const ( ) func TestNewShouldReturnInitiazedInstanceOfDeque(t *testing.T) { - d := New() + d := New[interface{}]() assertInvariants(t, d, nil) } func TestInvariantsWhenEmptyInMiddleOfSlice(t *testing.T) { - d := new(Deque) + d := new(Deque[interface{}]) d.PushBack(0) assertInvariants(t, d, nil) d.PushBack(1) @@ -50,7 +50,7 @@ func TestInvariantsWhenEmptyInMiddleOfSlice(t *testing.T) { } func TestPushFrontPopBackShouldHaveAllInternalLinksInARing(t *testing.T) { - d := New() + d := New[interface{}]() pushValue, extraAddedItems, spareLinks := 0, 0, 0 // Push maxFirstSliceSize items to fill the first array @@ -218,7 +218,7 @@ func TestPushFrontPopBackShouldHaveAllInternalLinksInARing(t *testing.T) { } func TestPushFrontPopFrontShouldHaveAllInternalLinksInARing(t *testing.T) { - d := New() + d := New[interface{}]() pushValue, spareLinks := 0, 0 // Push maxFirstSliceSize + maxInternalSliceSize + 1 items to fill the first, second @@ -338,7 +338,7 @@ func TestPushFrontPopFrontShouldHaveAllInternalLinksInARing(t *testing.T) { } func TestPushBackPopBackShouldHaveAllInternalLinksInARing(t *testing.T) { - d := New() + d := New[interface{}]() pushValue, extraAddedItems, spareLinks := 0, 0, 0 // Push maxFirstSliceSize items to fill the first array @@ -493,7 +493,7 @@ func TestPushBackPopBackShouldHaveAllInternalLinksInARing(t *testing.T) { } func TestPushBackPopFrontShouldHaveAllInternalLinksInARing(t *testing.T) { - d := New() + d := New[interface{}]() pushValue, spareLinks := 0, 0 // Push maxFirstSliceSize + maxInternalSliceSize + 1 items to fill the first, second @@ -627,7 +627,7 @@ func TestPushBackPopFrontShouldHaveAllInternalLinksInARing(t *testing.T) { } func TestPushFrontShouldReuseSpareLinks(t *testing.T) { - d := New() + d := New[interface{}]() count := maxInternalSliceSize * 3 // Fills the deque for i := 0; i < count; i++ { @@ -653,7 +653,7 @@ func TestPushFrontShouldReuseSpareLinks(t *testing.T) { } func TestPushFrontPopBackStableShouldReuseHeadSlice(t *testing.T) { - d := New() + d := New[interface{}]() for i := 0; i < pushCount; i++ { d.PushFront(i) @@ -673,7 +673,7 @@ func TestPushFrontPopBackStableShouldReuseHeadSlice(t *testing.T) { } func TestPushBackShouldReuseSpareLinks(t *testing.T) { - d := New() + d := New[interface{}]() count := maxInternalSliceSize * 3 // Fills the deque for i := 0; i < count; i++ { @@ -699,7 +699,7 @@ func TestPushBackShouldReuseSpareLinks(t *testing.T) { } func TestPopFrontWithRefillShouldKeepMaxSpareLinks(t *testing.T) { - d := New() + d := New[interface{}]() count := maxInternalSliceSize * (maxSpareLinks + 2) for i := 0; i < refillCount; i++ { for j := 0; j < count; j++ { @@ -732,7 +732,7 @@ func TestPopFrontWithRefillShouldKeepMaxSpareLinks(t *testing.T) { } func TestPopBackWithRefillShouldKeepMaxSpareLinks(t *testing.T) { - d := New() + d := New[interface{}]() count := maxInternalSliceSize * (maxSpareLinks + 2) for i := 0; i < refillCount; i++ { for j := 0; j < count; j++ { @@ -767,7 +767,7 @@ func TestPopBackWithRefillShouldKeepMaxSpareLinks(t *testing.T) { // Helper methods----------------------------------------------------------------------------------- // Checks the internal slices and its links. -func checkLinks(t *testing.T, d *Deque, length, headSliceSize, tailSliceSize, spareLinks int, headNext, headPrevious, tailNext, tailPrevious *node) { +func checkLinks(t *testing.T, d *Deque[interface{}], length, headSliceSize, tailSliceSize, spareLinks int, headNext, headPrevious, tailNext, tailPrevious *node[interface{}]) { t.Helper() if d.Len() != length { t.Errorf("unexpected length; Expected: %d; Got: %d", length, d.Len()) @@ -801,7 +801,7 @@ func checkLinks(t *testing.T, d *Deque, length, headSliceSize, tailSliceSize, sp // assertInvariants checks all the invariant conditions in d that we can think of. // If val is non-nil it is used to find the expected value for an item at index // i measured from the head of the queue. -func assertInvariants(t *testing.T, d *Deque, val func(i int) interface{}) { +func assertInvariants(t *testing.T, d *Deque[interface{}], val func(i int) interface{}) { t.Helper() fail := func(what string, got, want interface{}) { t.Errorf("invariant fail: %s; got %v want %v", what, got, want) @@ -851,7 +851,7 @@ func assertInvariants(t *testing.T, d *Deque, val func(i int) interface{}) { elemCount := 0 smallNodeCount := 0 index := 0 - walkLinks(t, d, func(n *node) { + walkLinks(t, d, func(n *node[interface{}]) { if len(n.v) < maxInternalSliceSize { smallNodeCount++ if len(n.v) > maxFirstSliceSize { @@ -928,7 +928,7 @@ func assertInvariants(t *testing.T, d *Deque, val func(i int) interface{}) { // walkLinks calls f for each node in the linked list. // It also checks link invariants: -func walkLinks(t *testing.T, d *Deque, f func(n *node)) { +func walkLinks(t *testing.T, d *Deque[interface{}], f func(n *node[interface{}])) { t.Helper() fail := func(what string, got, want interface{}) { t.Errorf("link invariant %s fail; got %v want %v", what, got, want)