github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/database/internal/treap/immutable.go (about) 1 // Copyright (c) 2015-2016 The btcsuite developers 2 // Copyright (c) 2016 The Dash developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package treap 7 8 import ( 9 "bytes" 10 "math/rand" 11 ) 12 13 // cloneTreapNode returns a shallow copy of the passed node. 14 func cloneTreapNode(node *treapNode) *treapNode { 15 return &treapNode{ 16 key: node.key, 17 value: node.value, 18 priority: node.priority, 19 left: node.left, 20 right: node.right, 21 } 22 } 23 24 // Immutable represents a treap data structure which is used to hold ordered 25 // key/value pairs using a combination of binary search tree and heap semantics. 26 // It is a self-organizing and randomized data structure that doesn't require 27 // complex operations to maintain balance. Search, insert, and delete 28 // operations are all O(log n). In addition, it provides O(1) snapshots for 29 // multi-version concurrency control (MVCC). 30 // 31 // All operations which result in modifying the treap return a new version of 32 // the treap with only the modified nodes updated. All unmodified nodes are 33 // shared with the previous version. This is extremely useful in concurrent 34 // applications since the caller only has to atomically replace the treap 35 // pointer with the newly returned version after performing any mutations. All 36 // readers can simply use their existing pointer as a snapshot since the treap 37 // it points to is immutable. This effectively provides O(1) snapshot 38 // capability with efficient memory usage characteristics since the old nodes 39 // only remain allocated until there are no longer any references to them. 40 type Immutable struct { 41 root *treapNode 42 count int 43 44 // totalSize is the best estimate of the total size of of all data in 45 // the treap including the keys, values, and node sizes. 46 totalSize uint64 47 } 48 49 // newImmutable returns a new immutable treap given the passed parameters. 50 func newImmutable(root *treapNode, count int, totalSize uint64) *Immutable { 51 return &Immutable{root: root, count: count, totalSize: totalSize} 52 } 53 54 // Len returns the number of items stored in the treap. 55 func (t *Immutable) Len() int { 56 return t.count 57 } 58 59 // Size returns a best estimate of the total number of bytes the treap is 60 // consuming including all of the fields used to represent the nodes as well as 61 // the size of the keys and values. Shared values are not detected, so the 62 // returned size assumes each value is pointing to different memory. 63 func (t *Immutable) Size() uint64 { 64 return t.totalSize 65 } 66 67 // get returns the treap node that contains the passed key. It will return nil 68 // when the key does not exist. 69 func (t *Immutable) get(key []byte) *treapNode { 70 for node := t.root; node != nil; { 71 // Traverse left or right depending on the result of the 72 // comparison. 73 compareResult := bytes.Compare(key, node.key) 74 if compareResult < 0 { 75 node = node.left 76 continue 77 } 78 if compareResult > 0 { 79 node = node.right 80 continue 81 } 82 83 // The key exists. 84 return node 85 } 86 87 // A nil node was reached which means the key does not exist. 88 return nil 89 } 90 91 // Has returns whether or not the passed key exists. 92 func (t *Immutable) Has(key []byte) bool { 93 if node := t.get(key); node != nil { 94 return true 95 } 96 return false 97 } 98 99 // Get returns the value for the passed key. The function will return nil when 100 // the key does not exist. 101 func (t *Immutable) Get(key []byte) []byte { 102 if node := t.get(key); node != nil { 103 return node.value 104 } 105 return nil 106 } 107 108 // Put inserts the passed key/value pair. 109 func (t *Immutable) Put(key, value []byte) *Immutable { 110 // Use an empty byte slice for the value when none was provided. This 111 // ultimately allows key existence to be determined from the value since 112 // an empty byte slice is distinguishable from nil. 113 if value == nil { 114 value = emptySlice 115 } 116 117 // The node is the root of the tree if there isn't already one. 118 if t.root == nil { 119 root := newTreapNode(key, value, rand.Int()) 120 return newImmutable(root, 1, nodeSize(root)) 121 } 122 123 // Find the binary tree insertion point and construct a replaced list of 124 // parents while doing so. This is done because this is an immutable 125 // data structure so regardless of where in the treap the new key/value 126 // pair ends up, all ancestors up to and including the root need to be 127 // replaced. 128 // 129 // When the key matches an entry already in the treap, replace the node 130 // with a new one that has the new value set and return. 131 var parents parentStack 132 var compareResult int 133 for node := t.root; node != nil; { 134 // Clone the node and link its parent to it if needed. 135 nodeCopy := cloneTreapNode(node) 136 if oldParent := parents.At(0); oldParent != nil { 137 if oldParent.left == node { 138 oldParent.left = nodeCopy 139 } else { 140 oldParent.right = nodeCopy 141 } 142 } 143 parents.Push(nodeCopy) 144 145 // Traverse left or right depending on the result of comparing 146 // the keys. 147 compareResult = bytes.Compare(key, node.key) 148 if compareResult < 0 { 149 node = node.left 150 continue 151 } 152 if compareResult > 0 { 153 node = node.right 154 continue 155 } 156 157 // The key already exists, so update its value. 158 nodeCopy.value = value 159 160 // Return new immutable treap with the replaced node and 161 // ancestors up to and including the root of the tree. 162 newRoot := parents.At(parents.Len() - 1) 163 newTotalSize := t.totalSize - uint64(len(node.value)) + 164 uint64(len(value)) 165 return newImmutable(newRoot, t.count, newTotalSize) 166 } 167 168 // Link the new node into the binary tree in the correct position. 169 node := newTreapNode(key, value, rand.Int()) 170 parent := parents.At(0) 171 if compareResult < 0 { 172 parent.left = node 173 } else { 174 parent.right = node 175 } 176 177 // Perform any rotations needed to maintain the min-heap and replace 178 // the ancestors up to and including the tree root. 179 newRoot := parents.At(parents.Len() - 1) 180 for parents.Len() > 0 { 181 // There is nothing left to do when the node's priority is 182 // greater than or equal to its parent's priority. 183 parent = parents.Pop() 184 if node.priority >= parent.priority { 185 break 186 } 187 188 // Perform a right rotation if the node is on the left side or 189 // a left rotation if the node is on the right side. 190 if parent.left == node { 191 node.right, parent.left = parent, node.right 192 } else { 193 node.left, parent.right = parent, node.left 194 } 195 196 // Either set the new root of the tree when there is no 197 // grandparent or relink the grandparent to the node based on 198 // which side the old parent the node is replacing was on. 199 grandparent := parents.At(0) 200 if grandparent == nil { 201 newRoot = node 202 } else if grandparent.left == parent { 203 grandparent.left = node 204 } else { 205 grandparent.right = node 206 } 207 } 208 209 return newImmutable(newRoot, t.count+1, t.totalSize+nodeSize(node)) 210 } 211 212 // Delete removes the passed key from the treap and returns the resulting treap 213 // if it exists. The original immutable treap is returned if the key does not 214 // exist. 215 func (t *Immutable) Delete(key []byte) *Immutable { 216 // Find the node for the key while constructing a list of parents while 217 // doing so. 218 var parents parentStack 219 var delNode *treapNode 220 for node := t.root; node != nil; { 221 parents.Push(node) 222 223 // Traverse left or right depending on the result of the 224 // comparison. 225 compareResult := bytes.Compare(key, node.key) 226 if compareResult < 0 { 227 node = node.left 228 continue 229 } 230 if compareResult > 0 { 231 node = node.right 232 continue 233 } 234 235 // The key exists. 236 delNode = node 237 break 238 } 239 240 // There is nothing to do if the key does not exist. 241 if delNode == nil { 242 return t 243 } 244 245 // When the only node in the tree is the root node and it is the one 246 // being deleted, there is nothing else to do besides removing it. 247 parent := parents.At(1) 248 if parent == nil && delNode.left == nil && delNode.right == nil { 249 return newImmutable(nil, 0, 0) 250 } 251 252 // Construct a replaced list of parents and the node to delete itself. 253 // This is done because this is an immutable data structure and 254 // therefore all ancestors of the node that will be deleted, up to and 255 // including the root, need to be replaced. 256 var newParents parentStack 257 for i := parents.Len(); i > 0; i-- { 258 node := parents.At(i - 1) 259 nodeCopy := cloneTreapNode(node) 260 if oldParent := newParents.At(0); oldParent != nil { 261 if oldParent.left == node { 262 oldParent.left = nodeCopy 263 } else { 264 oldParent.right = nodeCopy 265 } 266 } 267 newParents.Push(nodeCopy) 268 } 269 delNode = newParents.Pop() 270 parent = newParents.At(0) 271 272 // Perform rotations to move the node to delete to a leaf position while 273 // maintaining the min-heap while replacing the modified children. 274 var child *treapNode 275 newRoot := newParents.At(newParents.Len() - 1) 276 for delNode.left != nil || delNode.right != nil { 277 // Choose the child with the higher priority. 278 var isLeft bool 279 if delNode.left == nil { 280 child = delNode.right 281 } else if delNode.right == nil { 282 child = delNode.left 283 isLeft = true 284 } else if delNode.left.priority >= delNode.right.priority { 285 child = delNode.left 286 isLeft = true 287 } else { 288 child = delNode.right 289 } 290 291 // Rotate left or right depending on which side the child node 292 // is on. This has the effect of moving the node to delete 293 // towards the bottom of the tree while maintaining the 294 // min-heap. 295 child = cloneTreapNode(child) 296 if isLeft { 297 child.right, delNode.left = delNode, child.right 298 } else { 299 child.left, delNode.right = delNode, child.left 300 } 301 302 // Either set the new root of the tree when there is no 303 // grandparent or relink the grandparent to the node based on 304 // which side the old parent the node is replacing was on. 305 // 306 // Since the node to be deleted was just moved down a level, the 307 // new grandparent is now the current parent and the new parent 308 // is the current child. 309 if parent == nil { 310 newRoot = child 311 } else if parent.left == delNode { 312 parent.left = child 313 } else { 314 parent.right = child 315 } 316 317 // The parent for the node to delete is now what was previously 318 // its child. 319 parent = child 320 } 321 322 // Delete the node, which is now a leaf node, by disconnecting it from 323 // its parent. 324 if parent.right == delNode { 325 parent.right = nil 326 } else { 327 parent.left = nil 328 } 329 330 return newImmutable(newRoot, t.count-1, t.totalSize-nodeSize(delNode)) 331 } 332 333 // ForEach invokes the passed function with every key/value pair in the treap 334 // in ascending order. 335 func (t *Immutable) ForEach(fn func(k, v []byte) bool) { 336 // Add the root node and all children to the left of it to the list of 337 // nodes to traverse and loop until they, and all of their child nodes, 338 // have been traversed. 339 var parents parentStack 340 for node := t.root; node != nil; node = node.left { 341 parents.Push(node) 342 } 343 for parents.Len() > 0 { 344 node := parents.Pop() 345 if !fn(node.key, node.value) { 346 return 347 } 348 349 // Extend the nodes to traverse by all children to the left of 350 // the current node's right child. 351 for node := node.right; node != nil; node = node.left { 352 parents.Push(node) 353 } 354 } 355 } 356 357 // NewImmutable returns a new empty immutable treap ready for use. See the 358 // documentation for the Immutable structure for more details. 359 func NewImmutable() *Immutable { 360 return &Immutable{} 361 }