aug_btree.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2018 The Cockroach Authors.
  2. // Copyright 2021 Andrew Werner.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  13. // implied. See the License for the specific language governing
  14. // permissions and limitations under the License.
  15. package abstract
  16. import (
  17. "strings"
  18. )
  19. // TODO(ajwerner): It'd be amazing to find a way to make this not a single
  20. // compile-time constant.
  21. const (
  22. Degree = 64
  23. MaxEntries = 2*Degree - 1
  24. MinEntries = Degree - 1
  25. )
  26. // TODO(ajwerner): Probably we want comparison to occur on pointers to the
  27. // objects rather than the objects themselves, at least in some cases. For very
  28. // large objects, probably it's better to just store the objects as pointers
  29. // in the abstract itself and to use a sync.Pool to pool allocations. For very
  30. // small objects, directly calling less on the object is probably ideal. The
  31. // question is mid-sized objects.
  32. // Map is an implementation of an augmented B-Tree.
  33. //
  34. // Write operations are not safe for concurrent mutation by multiple
  35. // goroutines, but Read operations are.
  36. type Map[K, V, A any] struct {
  37. root *Node[K, V, A]
  38. length int
  39. cfg config[K, V, A]
  40. }
  41. // MakeMap constructs a new Map.
  42. func MakeMap[K, V, A any](cmp func(K, K) int, up Updater[K, V, A]) Map[K, V, A] {
  43. return Map[K, V, A]{
  44. cfg: makeConfig(cmp, up),
  45. }
  46. }
  47. // Reset removes all items from the AugBTree. In doing so, it allows memory
  48. // held by the AugBTree to be recycled. Failure to call this method before
  49. // letting a AugBTree be GCed is safe in that it won't cause a memory leak,
  50. // but it will prevent AugBTree nodes from being efficiently re-used.
  51. func (t *Map[K, V, A]) Reset() {
  52. if t.root != nil {
  53. t.root.decRef(t.cfg.np, true /* recursive */)
  54. t.root = nil
  55. }
  56. t.length = 0
  57. }
  58. // Clone clones the AugBTree, lazily. It does so in constant time.
  59. func (t *Map[K, V, A]) Clone() Map[K, V, A] {
  60. if t.root != nil {
  61. // Incrementing the reference count on the root node is sufficient to
  62. // ensure that no node in the cloned tree can be mutated by an actor
  63. // holding a reference to the original tree and vice versa. This
  64. // property is upheld because the root node in the receiver AugBTree and
  65. // the returned AugBTree will both necessarily have a reference count of at
  66. // least 2 when this method returns. All tree mutations recursively
  67. // acquire mutable node references (see mut) as they traverse down the
  68. // tree. The act of acquiring a mutable node reference performs a clone
  69. // if a node's reference count is greater than one. Cloning a node (see
  70. // clone) increases the reference count on each of its children,
  71. // ensuring that they have a reference count of at least 2. This, in
  72. // turn, ensures that any of the child nodes that are modified will also
  73. // be copied-on-write, recursively ensuring the immutability property
  74. // over the entire tree.
  75. t.root.incRef()
  76. }
  77. return *t
  78. }
  79. // Delete removes an item equal to the passed in item from the tree.
  80. func (t *Map[K, V, A]) Delete(k K) (removedK K, v V, found bool) {
  81. if t.root == nil || t.root.count == 0 {
  82. return removedK, v, false
  83. }
  84. if removedK, v, found, _ = mut(t.cfg.np, &t.root).remove(&t.cfg, k); found {
  85. t.length--
  86. }
  87. if t.root.count == 0 {
  88. old := t.root
  89. if t.root.IsLeaf() {
  90. t.root = nil
  91. } else {
  92. t.root = t.root.children[0]
  93. }
  94. old.decRef(t.cfg.np, false /* recursive */)
  95. }
  96. return removedK, v, found
  97. }
  98. // Upsert adds the given item to the tree. If an item in the tree already equals
  99. // the given one, it is replaced with the new item.
  100. func (t *Map[K, V, A]) Upsert(item K, value V) (replacedK K, replacedV V, replaced bool) {
  101. if t.root == nil {
  102. t.root = t.cfg.np.getLeafNode()
  103. } else if t.root.count >= MaxEntries {
  104. splitLaK, splitLaV, splitNode := mut(t.cfg.np, &t.root).
  105. split(&t.cfg, MaxEntries/2)
  106. newRoot := t.cfg.np.getInteriorNode()
  107. newRoot.count = 1
  108. newRoot.keys[0] = splitLaK
  109. newRoot.values[0] = splitLaV
  110. newRoot.children[0] = t.root
  111. newRoot.children[1] = splitNode
  112. newRoot.update(&t.cfg.Config)
  113. t.root = newRoot
  114. }
  115. replacedK, replacedV, replaced, _ = mut(t.cfg.np, &t.root).
  116. insert(&t.cfg, item, value)
  117. if !replaced {
  118. t.length++
  119. }
  120. return replacedK, replacedV, replaced
  121. }
  122. // MakeIter returns a new Iterator object. It is not safe to continue using an
  123. // Iterator after modifications are made to the tree. If modifications are made,
  124. // create a new Iterator.
  125. func (t *Map[K, V, A]) Iterator() Iterator[K, V, A] {
  126. it := Iterator[K, V, A]{r: t}
  127. it.Reset()
  128. return it
  129. }
  130. // Height returns the height of the tree.
  131. func (t *Map[K, V, A]) Height() int {
  132. if t.root == nil {
  133. return 0
  134. }
  135. h := 1
  136. n := t.root
  137. for !n.IsLeaf() {
  138. n = n.children[0]
  139. h++
  140. }
  141. return h
  142. }
  143. // Len returns the number of items currently in the tree.
  144. func (t *Map[K, V, A]) Len() int {
  145. return t.length
  146. }
  147. // Get returns the value associated with the requested key, if it exists.
  148. func (t *Map[K, V, A]) Get(k K) (v V, ok bool) {
  149. it := t.Iterator()
  150. it.SeekGE(k)
  151. if it.Valid() && it.Compare(it.Cur(), k) == 0 {
  152. return it.Value(), true
  153. }
  154. return v, false
  155. }
  156. // String returns a string description of the tree. The format is
  157. // similar to the https://en.wikipedia.org/wiki/Newick_format.
  158. func (t *Map[K, V, A]) String() string {
  159. if t.length == 0 {
  160. return ";"
  161. }
  162. var b strings.Builder
  163. t.root.writeString(&b)
  164. return b.String()
  165. }