github.com/maypok86/otter@v1.2.1/internal/expiry/queue_test.go (about) 1 // Copyright (c) 2024 Alexey Mayshev. All rights reserved. 2 // Copyright 2009 The Go Authors. All rights reserved. 3 // 4 // Copyright notice. Initial version of the following tests was based on 5 // the following file from the Go Programming Language core repo: 6 // https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/container/list/list_test.go 7 // 8 // Use of this source code is governed by a BSD-style 9 // license that can be found in the LICENSE file. 10 // That can be found at https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:LICENSE 11 12 package expiry 13 14 import ( 15 "strconv" 16 "testing" 17 18 "github.com/maypok86/otter/internal/generated/node" 19 ) 20 21 func checkQueueLen[K comparable, V any](t *testing.T, q *queue[K, V], length int) bool { 22 t.Helper() 23 24 if n := q.length(); n != length { 25 t.Errorf("q.length() = %d, want %d", n, length) 26 return false 27 } 28 return true 29 } 30 31 func checkQueuePointers[K comparable, V any](t *testing.T, q *queue[K, V], nodes []node.Node[K, V]) { 32 t.Helper() 33 34 if !checkQueueLen(t, q, len(nodes)) { 35 return 36 } 37 38 // zero length queues must be the zero value 39 if len(nodes) == 0 { 40 if !(node.Equals(q.head, nil) && node.Equals(q.tail, nil)) { 41 t.Errorf("q.head = %p, q.tail = %p; both should be nil", q.head, q.tail) 42 } 43 return 44 } 45 46 // check internal and external prev/next connections 47 for i, n := range nodes { 48 var prev node.Node[K, V] 49 if i > 0 { 50 prev = nodes[i-1] 51 } 52 if p := n.PrevExp(); !node.Equals(p, prev) { 53 t.Errorf("elt[%d](%p).prev = %p, want %p", i, n, p, prev) 54 } 55 56 var next node.Node[K, V] 57 if i < len(nodes)-1 { 58 next = nodes[i+1] 59 } 60 if nn := n.NextExp(); !node.Equals(nn, next) { 61 t.Errorf("nodes[%d](%p).next = %p, want %p", i, n, nn, next) 62 } 63 } 64 } 65 66 func newNode[K comparable](e K) node.Node[K, K] { 67 m := node.NewManager[K, K](node.Config{WithCost: true, WithExpiration: true}) 68 return m.Create(e, e, 0, 0) 69 } 70 71 func TestQueue(t *testing.T) { 72 q := newQueue[string, string]() 73 checkQueuePointers(t, q, []node.Node[string, string]{}) 74 75 // Single element queue 76 e := newNode("a") 77 q.push(e) 78 checkQueuePointers(t, q, []node.Node[string, string]{e}) 79 q.remove(e) 80 q.push(e) 81 checkQueuePointers(t, q, []node.Node[string, string]{e}) 82 q.remove(e) 83 checkQueuePointers(t, q, []node.Node[string, string]{}) 84 85 // Bigger queue 86 e2 := newNode("2") 87 e1 := newNode("1") 88 e3 := newNode("3") 89 e4 := newNode("4") 90 q.push(e1) 91 q.push(e2) 92 q.push(e3) 93 q.push(e4) 94 checkQueuePointers(t, q, []node.Node[string, string]{e1, e2, e3, e4}) 95 96 q.remove(e2) 97 checkQueuePointers(t, q, []node.Node[string, string]{e1, e3, e4}) 98 99 // move from middle 100 q.remove(e3) 101 q.push(e3) 102 checkQueuePointers(t, q, []node.Node[string, string]{e1, e4, e3}) 103 104 q.clear() 105 q.push(e3) 106 q.push(e1) 107 q.push(e4) 108 checkQueuePointers(t, q, []node.Node[string, string]{e3, e1, e4}) 109 110 // should be no-op 111 q.remove(e3) 112 q.push(e3) 113 checkQueuePointers(t, q, []node.Node[string, string]{e1, e4, e3}) 114 115 // Check standard iteration. 116 sum := 0 117 for e := q.head; !node.Equals(e, nil); e = e.NextExp() { 118 i, err := strconv.Atoi(e.Value()) 119 if err != nil { 120 continue 121 } 122 sum += i 123 } 124 if sum != 8 { 125 t.Errorf("sum over l = %d, want 8", sum) 126 } 127 128 // Clear all elements by iterating 129 var next node.Node[string, string] 130 for e := q.head; !node.Equals(e, nil); e = next { 131 next = e.NextExp() 132 q.remove(e) 133 } 134 checkQueuePointers(t, q, []node.Node[string, string]{}) 135 } 136 137 func TestQueue_Remove(t *testing.T) { 138 q := newQueue[int, int]() 139 140 e1 := newNode(1) 141 e2 := newNode(2) 142 q.push(e1) 143 q.push(e2) 144 checkQueuePointers(t, q, []node.Node[int, int]{e1, e2}) 145 e := q.head 146 q.remove(e) 147 checkQueuePointers(t, q, []node.Node[int, int]{e2}) 148 q.remove(e) 149 checkQueuePointers(t, q, []node.Node[int, int]{e2}) 150 }