golang.org/x/tools/gopls@v0.15.3/internal/util/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 "golang.org/x/tools/gopls/internal/util/constraints" 17 ) 18 19 // Implementation details: 20 // * Each value is reference counted by nodes which hold it. 21 // * Each node is reference counted by its parent nodes. 22 // * Each map is considered a top-level parent node from reference counting perspective. 23 // * Each change does always effectively produce a new top level node. 24 // 25 // Functions which operate directly with nodes do have a notation in form of 26 // `foo(arg1:+n1, arg2:+n2) (ret1:+n3)`. 27 // Each argument is followed by a delta change to its reference counter. 28 // In case if no change is expected, the delta will be `-0`. 29 30 // Map is an associative mapping from keys to values. 31 // 32 // Maps can be Cloned in constant time. 33 // Get, Set, and Delete operations are done on average in logarithmic time. 34 // Maps can be merged (via SetAll) 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 // 42 // The zero value is ready to use. 43 type Map[K constraints.Ordered, V any] struct { 44 // Map is a generic wrapper around a non-generic implementation to avoid a 45 // significant increase in the size of the executable. 46 root *mapNode 47 } 48 49 func (*Map[K, V]) less(l, r any) bool { 50 return l.(K) < r.(K) 51 } 52 53 func (m *Map[K, V]) String() string { 54 var buf strings.Builder 55 buf.WriteByte('{') 56 var sep string 57 m.Range(func(k K, v V) { 58 fmt.Fprintf(&buf, "%s%v: %v", sep, k, v) 59 sep = ", " 60 }) 61 buf.WriteByte('}') 62 return buf.String() 63 } 64 65 type mapNode struct { 66 key any 67 value *refValue 68 weight uint64 69 refCount int32 70 left, right *mapNode 71 } 72 73 type refValue struct { 74 refCount int32 75 value any 76 release func(key, value any) 77 } 78 79 func newNodeWithRef[K constraints.Ordered, V any](key K, value V, release func(key, value any)) *mapNode { 80 return &mapNode{ 81 key: key, 82 value: &refValue{ 83 value: value, 84 release: release, 85 refCount: 1, 86 }, 87 refCount: 1, 88 weight: rand.Uint64(), 89 } 90 } 91 92 func (node *mapNode) shallowCloneWithRef() *mapNode { 93 atomic.AddInt32(&node.value.refCount, 1) 94 return &mapNode{ 95 key: node.key, 96 value: node.value, 97 weight: node.weight, 98 refCount: 1, 99 } 100 } 101 102 func (node *mapNode) incref() *mapNode { 103 if node != nil { 104 atomic.AddInt32(&node.refCount, 1) 105 } 106 return node 107 } 108 109 func (node *mapNode) decref() { 110 if node == nil { 111 return 112 } 113 if atomic.AddInt32(&node.refCount, -1) == 0 { 114 if atomic.AddInt32(&node.value.refCount, -1) == 0 { 115 if node.value.release != nil { 116 node.value.release(node.key, node.value.value) 117 } 118 node.value.value = nil 119 node.value.release = nil 120 } 121 node.left.decref() 122 node.right.decref() 123 } 124 } 125 126 // Clone returns a copy of the given map. It is a responsibility of the caller 127 // to Destroy it at later time. 128 func (pm *Map[K, V]) Clone() *Map[K, V] { 129 return &Map[K, V]{ 130 root: pm.root.incref(), 131 } 132 } 133 134 // Destroy destroys the map. 135 // 136 // After Destroy, the Map should not be used again. 137 func (pm *Map[K, V]) Destroy() { 138 // The implementation of these two functions is the same, 139 // but their intent is different. 140 pm.Clear() 141 } 142 143 // Clear removes all entries from the map. 144 func (pm *Map[K, V]) Clear() { 145 pm.root.decref() 146 pm.root = nil 147 } 148 149 // Keys returns all keys present in the map. 150 func (pm *Map[K, V]) Keys() []K { 151 var keys []K 152 pm.root.forEach(func(k, _ any) { 153 keys = append(keys, k.(K)) 154 }) 155 return keys 156 } 157 158 // Range calls f sequentially in ascending key order for all entries in the map. 159 func (pm *Map[K, V]) Range(f func(key K, value V)) { 160 pm.root.forEach(func(k, v any) { 161 f(k.(K), v.(V)) 162 }) 163 } 164 165 func (node *mapNode) forEach(f func(key, value any)) { 166 if node == nil { 167 return 168 } 169 node.left.forEach(f) 170 f(node.key, node.value.value) 171 node.right.forEach(f) 172 } 173 174 // Get returns the map value associated with the specified key. 175 // The ok result indicates whether an entry was found in the map. 176 func (pm *Map[K, V]) Get(key K) (V, bool) { 177 node := pm.root 178 for node != nil { 179 if key < node.key.(K) { 180 node = node.left 181 } else if node.key.(K) < key { 182 node = node.right 183 } else { 184 return node.value.value.(V), true 185 } 186 } 187 var zero V 188 return zero, false 189 } 190 191 // SetAll updates the map with key/value pairs from the other map, overwriting existing keys. 192 // It is equivalent to calling Set for each entry in the other map but is more efficient. 193 func (pm *Map[K, V]) SetAll(other *Map[K, V]) { 194 root := pm.root 195 pm.root = union(root, other.root, pm.less, true) 196 root.decref() 197 } 198 199 // Set updates the value associated with the specified key. 200 // If release is non-nil, it will be called with entry's key and value once the 201 // key is no longer contained in the map or any clone. 202 func (pm *Map[K, V]) Set(key K, value V, release func(key, value any)) { 203 first := pm.root 204 second := newNodeWithRef(key, value, release) 205 pm.root = union(first, second, pm.less, true) 206 first.decref() 207 second.decref() 208 } 209 210 // union returns a new tree which is a union of first and second one. 211 // If overwrite is set to true, second one would override a value for any duplicate keys. 212 // 213 // union(first:-0, second:-0) (result:+1) 214 // Union borrows both subtrees without affecting their refcount and returns a 215 // new reference that the caller is expected to call decref. 216 func union(first, second *mapNode, less func(any, any) bool, overwrite bool) *mapNode { 217 if first == nil { 218 return second.incref() 219 } 220 if second == nil { 221 return first.incref() 222 } 223 224 if first.weight < second.weight { 225 second, first, overwrite = first, second, !overwrite 226 } 227 228 left, mid, right := split(second, first.key, less, false) 229 var result *mapNode 230 if overwrite && mid != nil { 231 result = mid.shallowCloneWithRef() 232 } else { 233 result = first.shallowCloneWithRef() 234 } 235 result.weight = first.weight 236 result.left = union(first.left, left, less, overwrite) 237 result.right = union(first.right, right, less, overwrite) 238 left.decref() 239 mid.decref() 240 right.decref() 241 return result 242 } 243 244 // split the tree midway by the key into three different ones. 245 // Return three new trees: left with all nodes with smaller than key, mid with 246 // the node matching the key, right with all nodes larger than key. 247 // If there are no nodes in one of trees, return nil instead of it. 248 // If requireMid is set (such as during deletion), then all return arguments 249 // are nil if mid is not found. 250 // 251 // split(n:-0) (left:+1, mid:+1, right:+1) 252 // Split borrows n without affecting its refcount, and returns three 253 // new references that the caller is expected to call decref. 254 func split(n *mapNode, key any, less func(any, any) bool, requireMid bool) (left, mid, right *mapNode) { 255 if n == nil { 256 return nil, nil, nil 257 } 258 259 if less(n.key, key) { 260 left, mid, right := split(n.right, key, less, requireMid) 261 if requireMid && mid == nil { 262 return nil, nil, nil 263 } 264 newN := n.shallowCloneWithRef() 265 newN.left = n.left.incref() 266 newN.right = left 267 return newN, mid, right 268 } else if less(key, n.key) { 269 left, mid, right := split(n.left, key, less, requireMid) 270 if requireMid && mid == nil { 271 return nil, nil, nil 272 } 273 newN := n.shallowCloneWithRef() 274 newN.left = right 275 newN.right = n.right.incref() 276 return left, mid, newN 277 } 278 mid = n.shallowCloneWithRef() 279 return n.left.incref(), mid, n.right.incref() 280 } 281 282 // Delete deletes the value for a key. 283 // 284 // The result reports whether the key was present in the map. 285 func (pm *Map[K, V]) Delete(key K) bool { 286 root := pm.root 287 left, mid, right := split(root, key, pm.less, true) 288 if mid == nil { 289 return false 290 } 291 pm.root = merge(left, right) 292 left.decref() 293 mid.decref() 294 right.decref() 295 root.decref() 296 return true 297 } 298 299 // merge two trees while preserving the weight invariant. 300 // All nodes in left must have smaller keys than any node in right. 301 // 302 // merge(left:-0, right:-0) (result:+1) 303 // Merge borrows its arguments without affecting their refcount 304 // and returns a new reference that the caller is expected to call decref. 305 func merge(left, right *mapNode) *mapNode { 306 switch { 307 case left == nil: 308 return right.incref() 309 case right == nil: 310 return left.incref() 311 case left.weight > right.weight: 312 root := left.shallowCloneWithRef() 313 root.left = left.left.incref() 314 root.right = merge(left.right, right) 315 return root 316 default: 317 root := right.shallowCloneWithRef() 318 root.left = merge(left, right.left) 319 root.right = right.right.incref() 320 return root 321 } 322 }