You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

btree.go 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Copyright 2020 Joshua J Baker. All rights reserved.
  2. // Use of this source code is governed by an MIT-style
  3. // license that can be found in the LICENSE file.
  4. package btree
  5. type BTree struct {
  6. base *BTreeG[any]
  7. }
  8. // New returns a new BTree
  9. func New(less func(a, b any) bool) *BTree {
  10. if less == nil {
  11. panic("nil less")
  12. }
  13. return &BTree{
  14. base: NewBTreeG(less),
  15. }
  16. }
  17. // NewNonConcurrent returns a new BTree which is not safe for concurrent
  18. // write operations by multiple goroutines.
  19. //
  20. // This is useful for when you do not need the BTree to manage the locking,
  21. // but would rather do it yourself.
  22. func NewNonConcurrent(less func(a, b any) bool) *BTree {
  23. if less == nil {
  24. panic("nil less")
  25. }
  26. return &BTree{
  27. base: NewBTreeGOptions(less,
  28. Options{
  29. NoLocks: true,
  30. }),
  31. }
  32. }
  33. // Less is a convenience function that performs a comparison of two items
  34. // using the same "less" function provided to New.
  35. func (tr *BTree) Less(a, b any) bool {
  36. return tr.base.Less(a, b)
  37. }
  38. // Set or replace a value for a key
  39. // Returns the value for the replaced item or nil if the key was not found.
  40. func (tr *BTree) Set(item any) (prev any) {
  41. return tr.SetHint(item, nil)
  42. }
  43. // SetHint sets or replace a value for a key using a path hint
  44. // Returns the value for the replaced item or nil if the key was not found.
  45. func (tr *BTree) SetHint(item any, hint *PathHint) (prev any) {
  46. if item == nil {
  47. panic("nil item")
  48. }
  49. v, ok := tr.base.SetHint(item, hint)
  50. if !ok {
  51. return nil
  52. }
  53. return v
  54. }
  55. // Get a value for key.
  56. // Returns nil if the key was not found.
  57. func (tr *BTree) Get(key any) any {
  58. return tr.GetHint(key, nil)
  59. }
  60. // GetHint gets a value for key using a path hint.
  61. // Returns nil if the item was not found.
  62. func (tr *BTree) GetHint(key any, hint *PathHint) (value any) {
  63. if key == nil {
  64. return nil
  65. }
  66. v, ok := tr.base.GetHint(key, hint)
  67. if !ok {
  68. return nil
  69. }
  70. return v
  71. }
  72. // Len returns the number of items in the tree
  73. func (tr *BTree) Len() int {
  74. return tr.base.Len()
  75. }
  76. // Delete an item for a key.
  77. // Returns the deleted value or nil if the key was not found.
  78. func (tr *BTree) Delete(key any) (prev any) {
  79. return tr.DeleteHint(key, nil)
  80. }
  81. // DeleteHint deletes a value for a key using a path hint
  82. // Returns the deleted value or nil if the key was not found.
  83. func (tr *BTree) DeleteHint(key any, hint *PathHint) (prev any) {
  84. if key == nil {
  85. return nil
  86. }
  87. v, ok := tr.base.DeleteHint(key, nil)
  88. if !ok {
  89. return nil
  90. }
  91. return v
  92. }
  93. // Ascend the tree within the range [pivot, last]
  94. // Pass nil for pivot to scan all item in ascending order
  95. // Return false to stop iterating
  96. func (tr *BTree) Ascend(pivot any, iter func(item any) bool) {
  97. if pivot == nil {
  98. tr.base.Scan(iter)
  99. } else {
  100. tr.base.Ascend(pivot, iter)
  101. }
  102. }
  103. // Descend the tree within the range [pivot, first]
  104. // Pass nil for pivot to scan all item in descending order
  105. // Return false to stop iterating
  106. func (tr *BTree) Descend(pivot any, iter func(item any) bool) {
  107. if pivot == nil {
  108. tr.base.Reverse(iter)
  109. } else {
  110. tr.base.Descend(pivot, iter)
  111. }
  112. }
  113. // Load is for bulk loading pre-sorted items
  114. // If the load replaces and existing item then the value for the replaced item
  115. // is returned.
  116. func (tr *BTree) Load(item any) (prev any) {
  117. if item == nil {
  118. panic("nil item")
  119. }
  120. v, ok := tr.base.Load(item)
  121. if !ok {
  122. return nil
  123. }
  124. return v
  125. }
  126. // Min returns the minimum item in tree.
  127. // Returns nil if the tree has no items.
  128. func (tr *BTree) Min() any {
  129. v, ok := tr.base.Min()
  130. if !ok {
  131. return nil
  132. }
  133. return v
  134. }
  135. // Max returns the maximum item in tree.
  136. // Returns nil if the tree has no items.
  137. func (tr *BTree) Max() any {
  138. v, ok := tr.base.Max()
  139. if !ok {
  140. return nil
  141. }
  142. return v
  143. }
  144. // PopMin removes the minimum item in tree and returns it.
  145. // Returns nil if the tree has no items.
  146. func (tr *BTree) PopMin() any {
  147. v, ok := tr.base.PopMin()
  148. if !ok {
  149. return nil
  150. }
  151. return v
  152. }
  153. // PopMax removes the maximum item in tree and returns it.
  154. // Returns nil if the tree has no items.
  155. func (tr *BTree) PopMax() any {
  156. v, ok := tr.base.PopMax()
  157. if !ok {
  158. return nil
  159. }
  160. return v
  161. }
  162. // GetAt returns the value at index.
  163. // Return nil if the tree is empty or the index is out of bounds.
  164. func (tr *BTree) GetAt(index int) any {
  165. v, ok := tr.base.GetAt(index)
  166. if !ok {
  167. return nil
  168. }
  169. return v
  170. }
  171. // DeleteAt deletes the item at index.
  172. // Return nil if the tree is empty or the index is out of bounds.
  173. func (tr *BTree) DeleteAt(index int) any {
  174. v, ok := tr.base.DeleteAt(index)
  175. if !ok {
  176. return nil
  177. }
  178. return v
  179. }
  180. // Height returns the height of the tree.
  181. // Returns zero if tree has no items.
  182. func (tr *BTree) Height() int {
  183. return tr.base.Height()
  184. }
  185. // Walk iterates over all items in tree, in order.
  186. // The items param will contain one or more items.
  187. func (tr *BTree) Walk(iter func(items []any)) {
  188. tr.base.Walk(func(items []any) bool {
  189. iter(items)
  190. return true
  191. })
  192. }
  193. // Copy the tree. This is a copy-on-write operation and is very fast because
  194. // it only performs a shadowed copy.
  195. func (tr *BTree) Copy() *BTree {
  196. return &BTree{base: tr.base.Copy()}
  197. }
  198. type Iter struct {
  199. base GenericIter[any]
  200. }
  201. // Iter returns a read-only iterator.
  202. // The Release method must be called finished with iterator.
  203. func (tr *BTree) Iter() Iter {
  204. return Iter{tr.base.Iter()}
  205. }
  206. // Seek to item greater-or-equal-to key.
  207. // Returns false if there was no item found.
  208. func (iter *Iter) Seek(key any) bool {
  209. return iter.base.Seek(key)
  210. }
  211. // First moves iterator to first item in tree.
  212. // Returns false if the tree is empty.
  213. func (iter *Iter) First() bool {
  214. return iter.base.First()
  215. }
  216. // Last moves iterator to last item in tree.
  217. // Returns false if the tree is empty.
  218. func (iter *Iter) Last() bool {
  219. return iter.base.Last()
  220. }
  221. // First moves iterator to first item in tree.
  222. // Returns false if the tree is empty.
  223. func (iter *Iter) Release() {
  224. iter.base.Release()
  225. }
  226. // Next moves iterator to the next item in iterator.
  227. // Returns false if the tree is empty or the iterator is at the end of
  228. // the tree.
  229. func (iter *Iter) Next() bool {
  230. return iter.base.Next()
  231. }
  232. // Prev moves iterator to the previous item in iterator.
  233. // Returns false if the tree is empty or the iterator is at the beginning of
  234. // the tree.
  235. func (iter *Iter) Prev() bool {
  236. return iter.base.Prev()
  237. }
  238. // Item returns the current iterator item.
  239. func (iter *Iter) Item() any {
  240. return iter.base.Item()
  241. }