iterator.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. // Iterator is responsible for search and traversal within a AugBTree.
  17. type Iterator[K, V, A any] struct {
  18. r *Map[K, V, A]
  19. iterFrame[K, V, A]
  20. s iterStack[K, V, A]
  21. }
  22. func (i *Iterator[K, V, A]) lowLevel() *LowLevelIterator[K, V, A] {
  23. return (*LowLevelIterator[K, V, A])(i)
  24. }
  25. // Compare compares two keys using the same comparison function as the map.
  26. func (i *Iterator[K, V, A]) Compare(a, b K) int {
  27. return i.r.cfg.cmp(a, b)
  28. }
  29. // Reset marks the iterator as invalid and clears any state.
  30. func (i *Iterator[K, V, A]) Reset() {
  31. i.node = i.r.root
  32. i.pos = -1
  33. i.s.reset()
  34. }
  35. // SeekGE seeks to the first key greater-than or equal to the provided
  36. // key.
  37. func (i *Iterator[K, V, A]) SeekGE(key K) {
  38. i.Reset()
  39. if i.node == nil {
  40. return
  41. }
  42. ll := i.lowLevel()
  43. for {
  44. pos, found := i.node.find(i.r.cfg.cmp, key)
  45. i.pos = int16(pos)
  46. if found {
  47. return
  48. }
  49. if i.node.IsLeaf() {
  50. if i.pos == i.node.count {
  51. i.Next()
  52. }
  53. return
  54. }
  55. ll.Descend()
  56. }
  57. }
  58. // SeekLT seeks to the first key less-than the provided key.
  59. func (i *Iterator[K, V, A]) SeekLT(key K) {
  60. i.Reset()
  61. if i.node == nil {
  62. return
  63. }
  64. ll := i.lowLevel()
  65. for {
  66. pos, found := i.node.find(i.r.cfg.cmp, key)
  67. i.pos = int16(pos)
  68. if found || i.node.IsLeaf() {
  69. i.Prev()
  70. return
  71. }
  72. ll.Descend()
  73. }
  74. }
  75. // First seeks to the first key in the AugBTree.
  76. func (i *Iterator[K, V, A]) First() {
  77. i.Reset()
  78. i.pos = 0
  79. if i.node == nil {
  80. return
  81. }
  82. ll := i.lowLevel()
  83. for !i.node.IsLeaf() {
  84. ll.Descend()
  85. }
  86. i.pos = 0
  87. }
  88. // Last seeks to the last key in the AugBTree.
  89. func (i *Iterator[K, V, A]) Last() {
  90. i.Reset()
  91. if i.node == nil {
  92. return
  93. }
  94. ll := i.lowLevel()
  95. for !i.node.IsLeaf() {
  96. i.pos = i.node.count
  97. ll.Descend()
  98. }
  99. i.pos = i.node.count - 1
  100. }
  101. // Next positions the Iterator to the key immediately following
  102. // its current position.
  103. func (i *Iterator[K, V, A]) Next() {
  104. if i.node == nil {
  105. return
  106. }
  107. ll := i.lowLevel()
  108. if i.node.IsLeaf() {
  109. i.pos++
  110. if i.pos < i.node.count {
  111. return
  112. }
  113. for i.s.len() > 0 && i.pos >= i.node.count {
  114. ll.Ascend()
  115. }
  116. return
  117. }
  118. i.pos++
  119. ll.Descend()
  120. for !i.node.IsLeaf() {
  121. i.pos = 0
  122. ll.Descend()
  123. }
  124. i.pos = 0
  125. }
  126. // Prev positions the Iterator to the key immediately preceding
  127. // its current position.
  128. func (i *Iterator[K, V, A]) Prev() {
  129. if i.node == nil {
  130. return
  131. }
  132. ll := i.lowLevel()
  133. if i.node.IsLeaf() {
  134. i.pos--
  135. if i.pos >= 0 {
  136. return
  137. }
  138. for i.s.len() > 0 && i.pos < 0 {
  139. ll.Ascend()
  140. i.pos--
  141. }
  142. return
  143. }
  144. ll.Descend()
  145. for !i.node.IsLeaf() {
  146. i.pos = i.node.count
  147. ll.Descend()
  148. }
  149. i.pos = i.node.count - 1
  150. }
  151. // Valid returns whether the Iterator is positioned at a valid position.
  152. func (i *Iterator[K, V, A]) Valid() bool {
  153. return i.node != nil && i.pos >= 0 && i.pos < i.node.count
  154. }
  155. // Cur returns the key at the Iterator's current position. It is illegal
  156. // to call Key if the Iterator is not valid.
  157. func (i *Iterator[K, V, A]) Cur() K {
  158. return i.node.keys[i.pos]
  159. }
  160. // Value returns the value at the Iterator's current position. It is illegal
  161. // to call Value if the Iterator is not valid.
  162. func (i *Iterator[K, V, A]) Value() V {
  163. return i.node.values[i.pos]
  164. }