| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // Copyright 2018 The Cockroach Authors.
- // Copyright 2021 Andrew Werner.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- // implied. See the License for the specific language governing
- // permissions and limitations under the License.
- package abstract
- // Iterator is responsible for search and traversal within a AugBTree.
- type Iterator[K, V, A any] struct {
- r *Map[K, V, A]
- iterFrame[K, V, A]
- s iterStack[K, V, A]
- }
- func (i *Iterator[K, V, A]) lowLevel() *LowLevelIterator[K, V, A] {
- return (*LowLevelIterator[K, V, A])(i)
- }
- // Compare compares two keys using the same comparison function as the map.
- func (i *Iterator[K, V, A]) Compare(a, b K) int {
- return i.r.cfg.cmp(a, b)
- }
- // Reset marks the iterator as invalid and clears any state.
- func (i *Iterator[K, V, A]) Reset() {
- i.node = i.r.root
- i.pos = -1
- i.s.reset()
- }
- // SeekGE seeks to the first key greater-than or equal to the provided
- // key.
- func (i *Iterator[K, V, A]) SeekGE(key K) {
- i.Reset()
- if i.node == nil {
- return
- }
- ll := i.lowLevel()
- for {
- pos, found := i.node.find(i.r.cfg.cmp, key)
- i.pos = int16(pos)
- if found {
- return
- }
- if i.node.IsLeaf() {
- if i.pos == i.node.count {
- i.Next()
- }
- return
- }
- ll.Descend()
- }
- }
- // SeekLT seeks to the first key less-than the provided key.
- func (i *Iterator[K, V, A]) SeekLT(key K) {
- i.Reset()
- if i.node == nil {
- return
- }
- ll := i.lowLevel()
- for {
- pos, found := i.node.find(i.r.cfg.cmp, key)
- i.pos = int16(pos)
- if found || i.node.IsLeaf() {
- i.Prev()
- return
- }
- ll.Descend()
- }
- }
- // First seeks to the first key in the AugBTree.
- func (i *Iterator[K, V, A]) First() {
- i.Reset()
- i.pos = 0
- if i.node == nil {
- return
- }
- ll := i.lowLevel()
- for !i.node.IsLeaf() {
- ll.Descend()
- }
- i.pos = 0
- }
- // Last seeks to the last key in the AugBTree.
- func (i *Iterator[K, V, A]) Last() {
- i.Reset()
- if i.node == nil {
- return
- }
- ll := i.lowLevel()
- for !i.node.IsLeaf() {
- i.pos = i.node.count
- ll.Descend()
- }
- i.pos = i.node.count - 1
- }
- // Next positions the Iterator to the key immediately following
- // its current position.
- func (i *Iterator[K, V, A]) Next() {
- if i.node == nil {
- return
- }
- ll := i.lowLevel()
- if i.node.IsLeaf() {
- i.pos++
- if i.pos < i.node.count {
- return
- }
- for i.s.len() > 0 && i.pos >= i.node.count {
- ll.Ascend()
- }
- return
- }
- i.pos++
- ll.Descend()
- for !i.node.IsLeaf() {
- i.pos = 0
- ll.Descend()
- }
- i.pos = 0
- }
- // Prev positions the Iterator to the key immediately preceding
- // its current position.
- func (i *Iterator[K, V, A]) Prev() {
- if i.node == nil {
- return
- }
- ll := i.lowLevel()
- if i.node.IsLeaf() {
- i.pos--
- if i.pos >= 0 {
- return
- }
- for i.s.len() > 0 && i.pos < 0 {
- ll.Ascend()
- i.pos--
- }
- return
- }
- ll.Descend()
- for !i.node.IsLeaf() {
- i.pos = i.node.count
- ll.Descend()
- }
- i.pos = i.node.count - 1
- }
- // Valid returns whether the Iterator is positioned at a valid position.
- func (i *Iterator[K, V, A]) Valid() bool {
- return i.node != nil && i.pos >= 0 && i.pos < i.node.count
- }
- // Cur returns the key at the Iterator's current position. It is illegal
- // to call Key if the Iterator is not valid.
- func (i *Iterator[K, V, A]) Cur() K {
- return i.node.keys[i.pos]
- }
- // Value returns the value at the Iterator's current position. It is illegal
- // to call Value if the Iterator is not valid.
- func (i *Iterator[K, V, A]) Value() V {
- return i.node.values[i.pos]
- }
|