merge_iterator.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright 2019 Dgraph Labs, Inc. and Contributors
  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 implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package table
  17. import (
  18. "bytes"
  19. "github.com/dgraph-io/badger/v4/y"
  20. )
  21. // MergeIterator merges multiple iterators.
  22. // NOTE: MergeIterator owns the array of iterators and is responsible for closing them.
  23. type MergeIterator struct {
  24. left node
  25. right node
  26. small *node
  27. curKey []byte
  28. reverse bool
  29. }
  30. type node struct {
  31. valid bool
  32. key []byte
  33. iter y.Iterator
  34. // The two iterators are type asserted from `y.Iterator`, used to inline more function calls.
  35. // Calling functions on concrete types is much faster (about 25-30%) than calling the
  36. // interface's function.
  37. merge *MergeIterator
  38. concat *ConcatIterator
  39. }
  40. func (n *node) setIterator(iter y.Iterator) {
  41. n.iter = iter
  42. // It's okay if the type assertion below fails and n.merge/n.concat are set to nil.
  43. // We handle the nil values of merge and concat in all the methods.
  44. n.merge, _ = iter.(*MergeIterator)
  45. n.concat, _ = iter.(*ConcatIterator)
  46. }
  47. func (n *node) setKey() {
  48. switch {
  49. case n.merge != nil:
  50. n.valid = n.merge.small.valid
  51. if n.valid {
  52. n.key = n.merge.small.key
  53. }
  54. case n.concat != nil:
  55. n.valid = n.concat.Valid()
  56. if n.valid {
  57. n.key = n.concat.Key()
  58. }
  59. default:
  60. n.valid = n.iter.Valid()
  61. if n.valid {
  62. n.key = n.iter.Key()
  63. }
  64. }
  65. }
  66. func (n *node) next() {
  67. switch {
  68. case n.merge != nil:
  69. n.merge.Next()
  70. case n.concat != nil:
  71. n.concat.Next()
  72. default:
  73. n.iter.Next()
  74. }
  75. n.setKey()
  76. }
  77. func (n *node) rewind() {
  78. n.iter.Rewind()
  79. n.setKey()
  80. }
  81. func (n *node) seek(key []byte) {
  82. n.iter.Seek(key)
  83. n.setKey()
  84. }
  85. func (mi *MergeIterator) fix() {
  86. if !mi.bigger().valid {
  87. return
  88. }
  89. if !mi.small.valid {
  90. mi.swapSmall()
  91. return
  92. }
  93. cmp := y.CompareKeys(mi.small.key, mi.bigger().key)
  94. switch {
  95. case cmp == 0: // Both the keys are equal.
  96. // In case of same keys, move the right iterator ahead.
  97. mi.right.next()
  98. if &mi.right == mi.small {
  99. mi.swapSmall()
  100. }
  101. return
  102. case cmp < 0: // Small is less than bigger().
  103. if mi.reverse {
  104. mi.swapSmall()
  105. } else { //nolint:staticcheck
  106. // we don't need to do anything. Small already points to the smallest.
  107. }
  108. return
  109. default: // bigger() is less than small.
  110. if mi.reverse {
  111. // Do nothing since we're iterating in reverse. Small currently points to
  112. // the bigger key and that's okay in reverse iteration.
  113. } else {
  114. mi.swapSmall()
  115. }
  116. return
  117. }
  118. }
  119. func (mi *MergeIterator) bigger() *node {
  120. if mi.small == &mi.left {
  121. return &mi.right
  122. }
  123. return &mi.left
  124. }
  125. func (mi *MergeIterator) swapSmall() {
  126. if mi.small == &mi.left {
  127. mi.small = &mi.right
  128. return
  129. }
  130. if mi.small == &mi.right {
  131. mi.small = &mi.left
  132. return
  133. }
  134. }
  135. // Next returns the next element. If it is the same as the current key, ignore it.
  136. func (mi *MergeIterator) Next() {
  137. for mi.Valid() {
  138. if !bytes.Equal(mi.small.key, mi.curKey) {
  139. break
  140. }
  141. mi.small.next()
  142. mi.fix()
  143. }
  144. mi.setCurrent()
  145. }
  146. func (mi *MergeIterator) setCurrent() {
  147. mi.curKey = append(mi.curKey[:0], mi.small.key...)
  148. }
  149. // Rewind seeks to first element (or last element for reverse iterator).
  150. func (mi *MergeIterator) Rewind() {
  151. mi.left.rewind()
  152. mi.right.rewind()
  153. mi.fix()
  154. mi.setCurrent()
  155. }
  156. // Seek brings us to element with key >= given key.
  157. func (mi *MergeIterator) Seek(key []byte) {
  158. mi.left.seek(key)
  159. mi.right.seek(key)
  160. mi.fix()
  161. mi.setCurrent()
  162. }
  163. // Valid returns whether the MergeIterator is at a valid element.
  164. func (mi *MergeIterator) Valid() bool {
  165. return mi.small.valid
  166. }
  167. // Key returns the key associated with the current iterator.
  168. func (mi *MergeIterator) Key() []byte {
  169. return mi.small.key
  170. }
  171. // Value returns the value associated with the iterator.
  172. func (mi *MergeIterator) Value() y.ValueStruct {
  173. return mi.small.iter.Value()
  174. }
  175. // Close implements y.Iterator.
  176. func (mi *MergeIterator) Close() error {
  177. err1 := mi.left.iter.Close()
  178. err2 := mi.right.iter.Close()
  179. if err1 != nil {
  180. return y.Wrap(err1, "MergeIterator")
  181. }
  182. return y.Wrap(err2, "MergeIterator")
  183. }
  184. // NewMergeIterator creates a merge iterator.
  185. func NewMergeIterator(iters []y.Iterator, reverse bool) y.Iterator {
  186. switch len(iters) {
  187. case 0:
  188. return nil
  189. case 1:
  190. return iters[0]
  191. case 2:
  192. mi := &MergeIterator{
  193. reverse: reverse,
  194. }
  195. mi.left.setIterator(iters[0])
  196. mi.right.setIterator(iters[1])
  197. // Assign left iterator randomly. This will be fixed when user calls rewind/seek.
  198. mi.small = &mi.left
  199. return mi
  200. }
  201. mid := len(iters) / 2
  202. return NewMergeIterator(
  203. []y.Iterator{
  204. NewMergeIterator(iters[:mid], reverse),
  205. NewMergeIterator(iters[mid:], reverse),
  206. }, reverse)
  207. }