github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/batchskl/iterator.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package batchskl 16 17 import "github.com/zuoyebang/bitalosdb/internal/base" 18 19 type splice struct { 20 prev uint32 21 next uint32 22 } 23 24 type Iterator struct { 25 list *Skiplist 26 nd uint32 27 key base.InternalKey 28 lower []byte 29 upper []byte 30 } 31 32 func (it *Iterator) Close() error { 33 it.list = nil 34 it.nd = 0 35 return nil 36 } 37 38 func (it *Iterator) SeekGE(key []byte) *base.InternalKey { 39 _, it.nd = it.seekForBaseSplice(key, it.list.abbreviatedKey(key)) 40 if it.nd == it.list.tail { 41 return nil 42 } 43 nodeKey := it.list.getKey(it.nd) 44 if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 { 45 it.nd = it.list.tail 46 return nil 47 } 48 it.key = nodeKey 49 return &it.key 50 } 51 52 func (it *Iterator) SeekLT(key []byte) *base.InternalKey { 53 it.nd, _ = it.seekForBaseSplice(key, it.list.abbreviatedKey(key)) 54 if it.nd == it.list.head { 55 return nil 56 } 57 nodeKey := it.list.getKey(it.nd) 58 if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 { 59 it.nd = it.list.head 60 return nil 61 } 62 it.key = nodeKey 63 return &it.key 64 } 65 66 func (it *Iterator) First() *base.InternalKey { 67 it.nd = it.list.getNext(it.list.head, 0) 68 if it.nd == it.list.tail { 69 return nil 70 } 71 nodeKey := it.list.getKey(it.nd) 72 if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 { 73 it.nd = it.list.tail 74 return nil 75 } 76 it.key = nodeKey 77 return &it.key 78 } 79 80 func (it *Iterator) Last() *base.InternalKey { 81 it.nd = it.list.getPrev(it.list.tail, 0) 82 if it.nd == it.list.head { 83 return nil 84 } 85 nodeKey := it.list.getKey(it.nd) 86 if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 { 87 it.nd = it.list.head 88 return nil 89 } 90 it.key = nodeKey 91 return &it.key 92 } 93 94 func (it *Iterator) Next() *base.InternalKey { 95 it.nd = it.list.getNext(it.nd, 0) 96 if it.nd == it.list.tail { 97 return nil 98 } 99 nodeKey := it.list.getKey(it.nd) 100 if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 { 101 it.nd = it.list.tail 102 return nil 103 } 104 it.key = nodeKey 105 return &it.key 106 } 107 108 func (it *Iterator) Prev() *base.InternalKey { 109 it.nd = it.list.getPrev(it.nd, 0) 110 if it.nd == it.list.head { 111 return nil 112 } 113 nodeKey := it.list.getKey(it.nd) 114 if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 { 115 it.nd = it.list.head 116 return nil 117 } 118 it.key = nodeKey 119 return &it.key 120 } 121 122 func (it *Iterator) Key() *base.InternalKey { 123 return &it.key 124 } 125 126 func (it *Iterator) KeyInfo() (offset, keyStart, keyEnd uint32) { 127 n := it.list.node(it.nd) 128 return n.offset, n.keyStart, n.keyEnd 129 } 130 131 func (it *Iterator) Head() bool { 132 return it.nd == it.list.head 133 } 134 135 func (it *Iterator) Tail() bool { 136 return it.nd == it.list.tail 137 } 138 139 func (it *Iterator) Valid() bool { 140 return it.list != nil && it.nd != it.list.head && it.nd != it.list.tail 141 } 142 143 func (it *Iterator) String() string { 144 return "batch" 145 } 146 147 func (it *Iterator) SetBounds(lower, upper []byte) { 148 it.lower = lower 149 it.upper = upper 150 } 151 152 func (it *Iterator) seekForBaseSplice(key []byte, abbreviatedKey uint64) (prev, next uint32) { 153 prev = it.list.head 154 for level := it.list.height - 1; ; level-- { 155 prev, next = it.list.findSpliceForLevel(key, abbreviatedKey, level, prev) 156 if level == 0 { 157 break 158 } 159 } 160 161 return 162 }