github.com/Nigel2392/go-datastructures@v1.1.5/hashmap/bucketnode.go (about) 1 package hashmap 2 3 import ( 4 "github.com/Nigel2392/go-datastructures" 5 ) 6 7 type keyNode[T1 datastructures.Hashable[T1], T2 any] struct { 8 _hash uint64 9 key T1 10 value T2 11 next *keyNode[T1, T2] 12 } 13 14 func (n *keyNode[T1, T2]) insert(v *keyNode[T1, T2]) { 15 if n.key.Equals(v.key) { 16 n.value = v.value 17 return 18 } 19 20 if n.next == nil { 21 n.next = v 22 return 23 } 24 25 n.next.insert(v) 26 } 27 28 func (n *keyNode[T1, T2]) retrieve(other *keyNode[T1, T2]) (value T2, ok bool) { 29 if n == nil { 30 return 31 } 32 33 if n.key.Equals(other.key) { 34 return n.value, true 35 } 36 37 return n.next.retrieve(other) 38 } 39 40 func (n *keyNode[T1, T2]) delete(other *keyNode[T1, T2]) (newRoot *keyNode[T1, T2], deleted bool) { 41 if n == nil { 42 return nil, false 43 } 44 45 if n.key.Equals(other.key) { 46 return n.next, true 47 } 48 49 n.next, deleted = n.next.delete(other) 50 return n, deleted 51 } 52 53 func (n *keyNode[T1, T2]) pop(other *keyNode[T1, T2]) (newRoot *keyNode[T1, T2], value T2, ok bool) { 54 if n == nil { 55 return 56 } 57 58 if n.key.Equals(other.key) { 59 return n.next, n.value, true 60 } 61 62 n.next, value, ok = n.next.pop(other) 63 return n, value, ok 64 } 65 66 func (n *keyNode[T1, T2]) deleteIf(predicate func(k T1, v T2) bool) (newRoot *keyNode[T1, T2], amountDeleted int) { 67 if n == nil { 68 return 69 } 70 71 if predicate(n.key, n.value) { 72 newRoot, amountDeleted = n.next.deleteIf(predicate) 73 return newRoot, amountDeleted + 1 74 } 75 76 n.next, amountDeleted = n.next.deleteIf(predicate) 77 return n, amountDeleted 78 } 79 80 type bucketNode[T1 datastructures.Hashable[T1], T2 any] struct { 81 _hash uint64 82 next *keyNode[T1, T2] 83 left *bucketNode[T1, T2] 84 right *bucketNode[T1, T2] 85 } 86 87 func (n *bucketNode[T1, T2]) insert(v *keyNode[T1, T2]) { 88 if n._hash == v._hash { 89 if n.next == nil { 90 n.next = v 91 return 92 } 93 n.next.insert(v) 94 return 95 } else if n._hash < v._hash { 96 if n.right == nil { 97 n.right = &bucketNode[T1, T2]{ 98 _hash: v._hash, 99 next: v, 100 } 101 } else { 102 n.right.insert(v) 103 } 104 return 105 } else if n._hash > v._hash { 106 if n.left == nil { 107 n.left = &bucketNode[T1, T2]{ 108 _hash: v._hash, 109 next: v, 110 } 111 } else { 112 n.left.insert(v) 113 } 114 return 115 } 116 } 117 118 func (n *bucketNode[T1, T2]) retrieve(k *keyNode[T1, T2]) (value T2, ok bool) { 119 if n == nil { 120 return 121 } 122 123 if n._hash < k._hash { 124 return n.right.retrieve(k) 125 } else if n._hash > k._hash { 126 return n.left.retrieve(k) 127 } 128 129 return n.next.retrieve(k) 130 } 131 132 func (n *bucketNode[T1, T2]) delete(other *keyNode[T1, T2]) (newRoot *bucketNode[T1, T2], deleted bool) { 133 if n == nil { 134 return nil, false 135 } 136 137 if other._hash < n._hash { 138 n.left, deleted = n.left.delete(other) 139 } else if other._hash > n._hash { 140 n.right, deleted = n.right.delete(other) 141 } else { 142 n.next, deleted = n.next.delete(other) 143 } 144 if n.next == nil { 145 if n.left == nil { 146 return n.right, true 147 } else if n.right == nil { 148 return n.left, true 149 } 150 151 // find the min node in the right subtree 152 var minNode = n.right.findMin() 153 n._hash = minNode._hash 154 n.next = minNode.next 155 // delete the min node from the right subtree 156 n.right, deleted = n.right.deleteNode(minNode) 157 } 158 return n, deleted 159 } 160 161 func (n *bucketNode[T1, T2]) deleteIf(predicate func(T1, T2) bool) (newRoot *bucketNode[T1, T2], amountDeleted int) { 162 if n == nil { 163 return nil, 0 164 } 165 var deleted int 166 n.left, deleted = n.left.deleteIf(predicate) 167 amountDeleted += deleted 168 n.right, deleted = n.right.deleteIf(predicate) 169 amountDeleted += deleted 170 n.next, deleted = n.next.deleteIf(predicate) 171 amountDeleted += deleted 172 return n, amountDeleted 173 } 174 175 // deleteNode deletes the node with the given hash 176 func (n *bucketNode[T1, T2]) deleteNode(other *bucketNode[T1, T2]) (newRoot *bucketNode[T1, T2], deleted bool) { 177 if n == nil { 178 return nil, false 179 } 180 181 if other._hash < n._hash { 182 n.left, deleted = n.left.deleteNode(other) 183 } else if other._hash > n._hash { 184 n.right, deleted = n.right.deleteNode(other) 185 } else { 186 if n.left == nil { 187 return n.right, true 188 } else if n.right == nil { 189 return n.left, true 190 } 191 192 // find the min node in the right subtree 193 var minNode = n.right.findMin() 194 n._hash = minNode._hash 195 n.next = minNode.next 196 // delete the min node from the right subtree 197 n.right, deleted = n.right.deleteNode(minNode) 198 } 199 return n, deleted 200 } 201 202 func (n *bucketNode[T1, T2]) pop(k *keyNode[T1, T2]) (newRoot *bucketNode[T1, T2], value T2, ok bool) { 203 if n == nil { 204 return nil, value, false 205 } 206 207 if k._hash < n._hash { 208 n.left, value, ok = n.left.pop(k) 209 } else if k._hash > n._hash { 210 n.right, value, ok = n.right.pop(k) 211 } else { 212 n.next, value, ok = n.next.pop(k) 213 if n.next == nil { 214 if n.left == nil { 215 return n.right, value, ok 216 } else if n.right == nil { 217 return n.left, value, ok 218 } 219 220 // find the min node in the right subtree 221 var minNode = n.right.findMin() 222 n._hash = minNode._hash 223 n.next = minNode.next 224 // delete the min node from the right subtree 225 n.right, _ = n.right.deleteNode(minNode) 226 } 227 } 228 229 return n, value, ok 230 } 231 232 func (n *bucketNode[T1, T2]) findMin() *bucketNode[T1, T2] { 233 if n.left == nil { 234 return n 235 } 236 237 return n.left.findMin() 238 } 239 240 func (n *bucketNode[T1, T2]) traverse(f func(k T1, v T2) bool) (continueLoop bool) { 241 if n == nil { 242 return true 243 } 244 if !n.left.traverse(f) { 245 return true 246 } 247 for n.next != nil { 248 if !f(n.next.key, n.next.value) { 249 return false 250 } 251 n.next = n.next.next 252 } 253 if !n.right.traverse(f) { 254 return true 255 } 256 return true 257 }