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. import btree "github.com/tidwall/btree/internal"
  6. type BTree struct {
  7. base *btree.BTree
  8. }
  9. // PathHint is a utility type used with the *Hint() functions. Hints provide
  10. // faster operations for clustered keys.
  11. type PathHint = btree.PathHint
  12. // New returns a new BTree
  13. func New(less func(a, b interface{}) bool) *BTree {
  14. if less == nil {
  15. panic("nil less")
  16. }
  17. return &BTree{
  18. base: btree.NewOptions(btree.Options{
  19. Context: less,
  20. }),
  21. }
  22. }
  23. // NewNonConcurrent returns a new BTree which is not safe for concurrent
  24. // write operations by multiple goroutines.
  25. //
  26. // This is useful for when you do not need the BTree to manage the locking,
  27. // but would rather do it yourself.
  28. func NewNonConcurrent(less func(a, b interface{}) bool) *BTree {
  29. if less == nil {
  30. panic("nil less")
  31. }
  32. return &BTree{
  33. base: btree.NewOptions(btree.Options{
  34. Context: less,
  35. NoLocks: true,
  36. }),
  37. }
  38. }
  39. // Less is a convenience function that performs a comparison of two items
  40. // using the same "less" function provided to New.
  41. func (tr *BTree) Less(a, b interface{}) bool {
  42. return tr.base.Less(a, b)
  43. }
  44. // Set or replace a value for a key
  45. func (tr *BTree) Set(item interface{}) interface{} {
  46. return tr.SetHint(item, nil)
  47. }
  48. // SetHint sets or replace a value for a key using a path hint
  49. func (tr *BTree) SetHint(item interface{}, hint *PathHint) (prev interface{}) {
  50. if item == nil {
  51. panic("nil item")
  52. }
  53. v, ok := tr.base.SetHint(item, hint)
  54. if !ok {
  55. return nil
  56. }
  57. return v
  58. }
  59. // Get a value for key
  60. func (tr *BTree) Get(key interface{}) interface{} {
  61. return tr.GetHint(key, nil)
  62. }
  63. // GetHint gets a value for key using a path hint
  64. func (tr *BTree) GetHint(key interface{}, hint *PathHint) interface{} {
  65. if key == nil {
  66. return nil
  67. }
  68. v, ok := tr.base.GetHint(key, hint)
  69. if !ok {
  70. return nil
  71. }
  72. return v
  73. }
  74. // Len returns the number of items in the tree
  75. func (tr *BTree) Len() int {
  76. return tr.base.Len()
  77. }
  78. // Delete a value for a key
  79. func (tr *BTree) Delete(key interface{}) interface{} {
  80. return tr.DeleteHint(key, nil)
  81. }
  82. // DeleteHint deletes a value for a key using a path hint
  83. func (tr *BTree) DeleteHint(key interface{}, hint *PathHint) interface{} {
  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 interface{}, iter func(item interface{}) 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 interface{}, iter func(item interface{}) 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. func (tr *BTree) Load(item interface{}) interface{} {
  115. if item == nil {
  116. panic("nil item")
  117. }
  118. v, ok := tr.base.Load(item)
  119. if !ok {
  120. return nil
  121. }
  122. return v
  123. }
  124. // Min returns the minimum item in tree.
  125. // Returns nil if the tree has no items.
  126. func (tr *BTree) Min() interface{} {
  127. v, ok := tr.base.Min()
  128. if !ok {
  129. return nil
  130. }
  131. return v
  132. }
  133. // Max returns the maximum item in tree.
  134. // Returns nil if the tree has no items.
  135. func (tr *BTree) Max() interface{} {
  136. v, ok := tr.base.Max()
  137. if !ok {
  138. return nil
  139. }
  140. return v
  141. }
  142. // PopMin removes the minimum item in tree and returns it.
  143. // Returns nil if the tree has no items.
  144. func (tr *BTree) PopMin() interface{} {
  145. v, ok := tr.base.PopMin()
  146. if !ok {
  147. return nil
  148. }
  149. return v
  150. }
  151. // PopMax removes the minimum item in tree and returns it.
  152. // Returns nil if the tree has no items.
  153. func (tr *BTree) PopMax() interface{} {
  154. v, ok := tr.base.PopMax()
  155. if !ok {
  156. return nil
  157. }
  158. return v
  159. }
  160. // GetAt returns the value at index.
  161. // Return nil if the tree is empty or the index is out of bounds.
  162. func (tr *BTree) GetAt(index int) interface{} {
  163. v, ok := tr.base.GetAt(index)
  164. if !ok {
  165. return nil
  166. }
  167. return v
  168. }
  169. // DeleteAt deletes the item at index.
  170. // Return nil if the tree is empty or the index is out of bounds.
  171. func (tr *BTree) DeleteAt(index int) interface{} {
  172. v, ok := tr.base.DeleteAt(index)
  173. if !ok {
  174. return nil
  175. }
  176. return v
  177. }
  178. // Height returns the height of the tree.
  179. // Returns zero if tree has no items.
  180. func (tr *BTree) Height() int {
  181. return tr.base.Height()
  182. }
  183. // Walk iterates over all items in tree, in order.
  184. // The items param will contain one or more items.
  185. func (tr *BTree) Walk(iter func(items []interface{})) {
  186. tr.base.Walk(func(items []interface{}) bool {
  187. iter(items)
  188. return true
  189. })
  190. }
  191. // Copy the tree. This is a copy-on-write operation and is very fast because
  192. // it only performs a shadowed copy.
  193. func (tr *BTree) Copy() *BTree {
  194. return &BTree{base: tr.base.Copy()}
  195. }
  196. type Iter struct {
  197. base btree.Iter
  198. }
  199. // Iter returns a read-only iterator.
  200. // The Release method must be called finished with iterator.
  201. func (tr *BTree) Iter() Iter {
  202. return Iter{tr.base.Iter()}
  203. }
  204. // Seek to item greater-or-equal-to key.
  205. // Returns false if there was no item found.
  206. func (iter *Iter) Seek(key interface{}) bool {
  207. return iter.base.Seek(key)
  208. }
  209. // First moves iterator to first item in tree.
  210. // Returns false if the tree is empty.
  211. func (iter *Iter) First() bool {
  212. return iter.base.First()
  213. }
  214. // Last moves iterator to last item in tree.
  215. // Returns false if the tree is empty.
  216. func (iter *Iter) Last() bool {
  217. return iter.base.Last()
  218. }
  219. // First moves iterator to first item in tree.
  220. // Returns false if the tree is empty.
  221. func (iter *Iter) Release() {
  222. iter.base.Release()
  223. }
  224. // Next moves iterator to the next item in iterator.
  225. // Returns false if the tree is empty or the iterator is at the end of
  226. // the tree.
  227. func (iter *Iter) Next() bool {
  228. return iter.base.Next()
  229. }
  230. // Prev moves iterator to the previous item in iterator.
  231. // Returns false if the tree is empty or the iterator is at the beginning of
  232. // the tree.
  233. func (iter *Iter) Prev() bool {
  234. return iter.base.Prev()
  235. }
  236. // Item returns the current iterator item.
  237. func (iter *Iter) Item() interface{} {
  238. return iter.base.Item()
  239. }