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  }