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.

158 lines
3.4 KiB

  1. package bptree
  2. // started by copying from https://sourcegraph.com/github.com/timtadh/data-structures@master/-/tree/tree/bptree
  3. /* A BpTree is a B+Tree with support for duplicate keys. This makes it behave as
  4. * a MultiMap. Additionally you can use the Range operator to select k/v in a
  5. * range. If from > to it will iterate backwards.
  6. */
  7. type BpTree struct {
  8. root *BpNode
  9. }
  10. type loc_iterator func() (i int, leaf *BpNode, li loc_iterator)
  11. func NewBpTree(node_size int) *BpTree {
  12. return &BpTree{
  13. root: NewLeaf(node_size),
  14. }
  15. }
  16. func (self *BpTree) Has(key ItemKey) bool {
  17. if len(self.getRoot().keys) == 0 {
  18. return false
  19. }
  20. j, l := self.getRoot().get_start(key)
  21. return l.keys[j].Equals(key)
  22. }
  23. func (self *BpTree) Count(key ItemKey) int {
  24. if len(self.root.keys) == 0 {
  25. return 0
  26. }
  27. j, l := self.root.get_start(key)
  28. count := 0
  29. end := false
  30. for !end && l.keys[j].Equals(key) {
  31. count++
  32. j, l, end = next_location(j, l)
  33. }
  34. return count
  35. }
  36. func (self *BpTree) Add(key ItemKey, value ItemValue) (err error) {
  37. new_root, err := self.getRoot().put(key, value)
  38. if err != nil {
  39. return err
  40. }
  41. self.setRoot(new_root)
  42. return nil
  43. }
  44. func (self *BpTree) Replace(key ItemKey, where WhereFunc, value ItemValue) (err error) {
  45. li := self.getRoot().forward(key, key)
  46. for i, leaf, next := li(); next != nil; i, leaf, next = next() {
  47. if where(leaf.values[i]) {
  48. leaf.values[i] = value
  49. if persistErr := leaf.persist(); persistErr != nil && err == nil {
  50. err = persistErr
  51. break
  52. }
  53. }
  54. }
  55. return err
  56. }
  57. func (self *BpTree) Find(key ItemKey) (kvi KVIterator) {
  58. return self.Range(key, key)
  59. }
  60. func (self *BpTree) Range(from, to ItemKey) (kvi KVIterator) {
  61. var li loc_iterator
  62. if !to.Less(from) {
  63. li = self.getRoot().forward(from, to)
  64. } else {
  65. li = self.getRoot().backward(from, to)
  66. }
  67. kvi = func() (key ItemKey, value ItemValue, next KVIterator) {
  68. var i int
  69. var leaf *BpNode
  70. i, leaf, li = li()
  71. if li == nil {
  72. return nil, nil, nil
  73. }
  74. return leaf.keys[i], leaf.values[i], kvi
  75. }
  76. return kvi
  77. }
  78. func (self *BpTree) RemoveWhere(key ItemKey, where WhereFunc) (err error) {
  79. ns := self.getRoot().Capacity()
  80. new_root, err := self.getRoot().remove(key, where)
  81. if err != nil {
  82. return err
  83. }
  84. if new_root == nil {
  85. new_root = NewLeaf(ns)
  86. err = new_root.persist()
  87. self.setRoot(new_root)
  88. } else {
  89. self.setRoot(new_root)
  90. }
  91. return err
  92. }
  93. func (self *BpTree) Keys() (ki KIterator) {
  94. li := self.getRoot().all()
  95. var prev Equatable
  96. ki = func() (key ItemKey, next KIterator) {
  97. var i int
  98. var leaf *BpNode
  99. i, leaf, li = li()
  100. if li == nil {
  101. return nil, nil
  102. }
  103. if leaf.keys[i].Equals(prev) {
  104. return ki()
  105. }
  106. prev = leaf.keys[i]
  107. return leaf.keys[i], ki
  108. }
  109. return ki
  110. }
  111. func (self *BpTree) Values() (vi Iterator) {
  112. return MakeValuesIterator(self)
  113. }
  114. func (self *BpTree) Items() (vi KIterator) {
  115. return MakeItemsIterator(self)
  116. }
  117. func (self *BpTree) Iterate() (kvi KVIterator) {
  118. li := self.getRoot().all()
  119. kvi = func() (key ItemKey, value ItemValue, next KVIterator) {
  120. var i int
  121. var leaf *BpNode
  122. i, leaf, li = li()
  123. if li == nil {
  124. return nil, nil, nil
  125. }
  126. return leaf.keys[i], leaf.values[i], kvi
  127. }
  128. return kvi
  129. }
  130. func (self *BpTree) Backward() (kvi KVIterator) {
  131. li := self.getRoot().all_backward()
  132. kvi = func() (key ItemKey, value ItemValue, next KVIterator) {
  133. var i int
  134. var leaf *BpNode
  135. i, leaf, li = li()
  136. if li == nil {
  137. return nil, nil, nil
  138. }
  139. return leaf.keys[i], leaf.values[i], kvi
  140. }
  141. return kvi
  142. }