github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/internal/persistent/map.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // The persistent package defines various persistent data structures; 6 // that is, data structures that can be efficiently copied and modified 7 // in sublinear time. 8 package persistent 9 10 import ( 11 "fmt" 12 "math/rand" 13 "strings" 14 "sync/atomic" 15 ) 16 17 // Implementation details: 18 // * Each value is reference counted by nodes which hold it. 19 // * Each node is reference counted by its parent nodes. 20 // * Each map is considered a top-level parent node from reference counting perspective. 21 // * Each change does always effectivelly produce a new top level node. 22 // 23 // Functions which operate directly with nodes do have a notation in form of 24 // `foo(arg1:+n1, arg2:+n2) (ret1:+n3)`. 25 // Each argument is followed by a delta change to its reference counter. 26 // In case if no change is expected, the delta will be `-0`. 27 28 // Map is an associative mapping from keys to values, both represented as 29 // interface{}. Key comparison and iteration order is defined by a 30 // client-provided function that implements a strict weak order. 31 // 32 // Maps can be Cloned in constant time. 33 // Get, Store, and Delete operations are done on average in logarithmic time. 34 // Maps can be Updated in O(m log(n/m)) time for maps of size n and m, where m < n. 35 // 36 // Values are reference counted, and a client-supplied release function 37 // is called when a value is no longer referenced by a map or any clone. 38 // 39 // Internally the implementation is based on a randomized persistent treap: 40 // https://en.wikipedia.org/wiki/Treap. 41 type Map struct { 42 less func(a, b interface{}) bool 43 root *mapNode 44 } 45 46 func (m *Map) String() string { 47 var buf strings.Builder 48 buf.WriteByte('{') 49 var sep string 50 m.Range(func(k, v interface{}) { 51 fmt.Fprintf(&buf, "%s%v: %v", sep, k, v) 52 sep = ", " 53 }) 54 buf.WriteByte('}') 55 return buf.String() 56 } 57 58 type mapNode struct { 59 key interface{} 60 value *refValue 61 weight uint64 62 refCount int32 63 left, right *mapNode 64 } 65 66 type refValue struct { 67 refCount int32 68 value interface{} 69 release func(key, value interface{}) 70 } 71 72 func newNodeWithRef(key, value interface{}, release func(key, value interface{})) *mapNode { 73 return &mapNode{ 74 key: key, 75 value: &refValue{ 76 value: value, 77 release: release, 78 refCount: 1, 79 }, 80 refCount: 1, 81 weight: rand.Uint64(), 82 } 83 } 84 85 func (node *mapNode) shallowCloneWithRef() *mapNode { 86 atomic.AddInt32(&node.value.refCount, 1) 87 return &mapNode{ 88 key: node.key, 89 value: node.value, 90 weight: node.weight, 91 refCount: 1, 92 } 93 } 94 95 func (node *mapNode) incref() *mapNode { 96 if node != nil { 97 atomic.AddInt32(&node.refCount, 1) 98 } 99 return node 100 } 101 102 func (node *mapNode) decref() { 103 if node == nil { 104 return 105 } 106 if atomic.AddInt32(&node.refCount, -1) == 0 { 107 if atomic.AddInt32(&node.value.refCount, -1) == 0 { 108 if node.value.release != nil { 109 node.value.release(node.key, node.value.value) 110 } 111 node.value.value = nil 112 node.value.release = nil 113 } 114 node.left.decref() 115 node.right.decref() 116 } 117 } 118 119 // NewMap returns a new map whose keys are ordered by the given comparison 120 // function (a strict weak order). It is the responsibility of the caller to 121 // Destroy it at later time. 122 func NewMap(less func(a, b interface{}) bool) *Map { 123 return &Map{ 124 less: less, 125 } 126 } 127 128 // Clone returns a copy of the given map. It is a responsibility of the caller 129 // to Destroy it at later time. 130 func (pm *Map) Clone() *Map { 131 return &Map{ 132 less: pm.less, 133 root: pm.root.incref(), 134 } 135 } 136 137 // Destroy destroys the map. 138 // 139 // After Destroy, the Map should not be used again. 140 func (pm *Map) Destroy() { 141 // The implementation of these two functions is the same, 142 // but their intent is different. 143 pm.Clear() 144 } 145 146 // Clear removes all entries from the map. 147 func (pm *Map) Clear() { 148 pm.root.decref() 149 pm.root = nil 150 } 151 152 // Range calls f sequentially in ascending key order for all entries in the map. 153 func (pm *Map) Range(f func(key, value interface{})) { 154 pm.root.forEach(f) 155 } 156 157 func (node *mapNode) forEach(f func(key, value interface{})) { 158 if node == nil { 159 return 160 } 161 node.left.forEach(f) 162 f(node.key, node.value.value) 163 node.right.forEach(f) 164 } 165 166 // Get returns the map value associated with the specified key, or nil if no entry 167 // is present. The ok result indicates whether an entry was found in the map. 168 func (pm *Map) Get(key interface{}) (interface{}, bool) { 169 node := pm.root 170 for node != nil { 171 if pm.less(key, node.key) { 172 node = node.left 173 } else if pm.less(node.key, key) { 174 node = node.right 175 } else { 176 return node.value.value, true 177 } 178 } 179 return nil, false 180 } 181 182 // SetAll updates the map with key/value pairs from the other map, overwriting existing keys. 183 // It is equivalent to calling Set for each entry in the other map but is more efficient. 184 // Both maps must have the same comparison function, otherwise behavior is undefined. 185 func (pm *Map) SetAll(other *Map) { 186 root := pm.root 187 pm.root = union(root, other.root, pm.less, true) 188 root.decref() 189 } 190 191 // Set updates the value associated with the specified key. 192 // If release is non-nil, it will be called with entry's key and value once the 193 // key is no longer contained in the map or any clone. 194 func (pm *Map) Set(key, value interface{}, release func(key, value interface{})) { 195 first := pm.root 196 second := newNodeWithRef(key, value, release) 197 pm.root = union(first, second, pm.less, true) 198 first.decref() 199 second.decref() 200 } 201 202 // union returns a new tree which is a union of first and second one. 203 // If overwrite is set to true, second one would override a value for any duplicate keys. 204 // 205 // union(first:-0, second:-0) (result:+1) 206 // Union borrows both subtrees without affecting their refcount and returns a 207 // new reference that the caller is expected to call decref. 208 func union(first, second *mapNode, less func(a, b interface{}) bool, overwrite bool) *mapNode { 209 if first == nil { 210 return second.incref() 211 } 212 if second == nil { 213 return first.incref() 214 } 215 216 if first.weight < second.weight { 217 second, first, overwrite = first, second, !overwrite 218 } 219 220 left, mid, right := split(second, first.key, less, false) 221 var result *mapNode 222 if overwrite && mid != nil { 223 result = mid.shallowCloneWithRef() 224 } else { 225 result = first.shallowCloneWithRef() 226 } 227 result.weight = first.weight 228 result.left = union(first.left, left, less, overwrite) 229 result.right = union(first.right, right, less, overwrite) 230 left.decref() 231 mid.decref() 232 right.decref() 233 return result 234 } 235 236 // split the tree midway by the key into three different ones. 237 // Return three new trees: left with all nodes with smaller than key, mid with 238 // the node matching the key, right with all nodes larger than key. 239 // If there are no nodes in one of trees, return nil instead of it. 240 // If requireMid is set (such as during deletion), then all return arguments 241 // are nil if mid is not found. 242 // 243 // split(n:-0) (left:+1, mid:+1, right:+1) 244 // Split borrows n without affecting its refcount, and returns three 245 // new references that that caller is expected to call decref. 246 func split(n *mapNode, key interface{}, less func(a, b interface{}) bool, requireMid bool) (left, mid, right *mapNode) { 247 if n == nil { 248 return nil, nil, nil 249 } 250 251 if less(n.key, key) { 252 left, mid, right := split(n.right, key, less, requireMid) 253 if requireMid && mid == nil { 254 return nil, nil, nil 255 } 256 newN := n.shallowCloneWithRef() 257 newN.left = n.left.incref() 258 newN.right = left 259 return newN, mid, right 260 } else if less(key, n.key) { 261 left, mid, right := split(n.left, key, less, requireMid) 262 if requireMid && mid == nil { 263 return nil, nil, nil 264 } 265 newN := n.shallowCloneWithRef() 266 newN.left = right 267 newN.right = n.right.incref() 268 return left, mid, newN 269 } 270 mid = n.shallowCloneWithRef() 271 return n.left.incref(), mid, n.right.incref() 272 } 273 274 // Delete deletes the value for a key. 275 func (pm *Map) Delete(key interface{}) { 276 root := pm.root 277 left, mid, right := split(root, key, pm.less, true) 278 if mid == nil { 279 return 280 } 281 pm.root = merge(left, right) 282 left.decref() 283 mid.decref() 284 right.decref() 285 root.decref() 286 } 287 288 // merge two trees while preserving the weight invariant. 289 // All nodes in left must have smaller keys than any node in right. 290 // 291 // merge(left:-0, right:-0) (result:+1) 292 // Merge borrows its arguments without affecting their refcount 293 // and returns a new reference that the caller is expected to call decref. 294 func merge(left, right *mapNode) *mapNode { 295 switch { 296 case left == nil: 297 return right.incref() 298 case right == nil: 299 return left.incref() 300 case left.weight > right.weight: 301 root := left.shallowCloneWithRef() 302 root.left = left.left.incref() 303 root.right = merge(left.right, right) 304 return root 305 default: 306 root := right.shallowCloneWithRef() 307 root.left = merge(left, right.left) 308 root.right = right.right.incref() 309 return root 310 } 311 }