github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/batchskl/iterator.go (about) 1 /* 2 * Copyright 2017 Dgraph Labs, Inc. and Contributors 3 * Modifications copyright (C) 2017 Andy Kimball and Contributors 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package batchskl 19 20 import "github.com/zuoyebang/bitalostable/internal/base" 21 22 type splice struct { 23 prev uint32 24 next uint32 25 } 26 27 // Iterator is an iterator over the skiplist object. Use Skiplist.NewIter 28 // to construct an iterator. The current state of the iterator can be cloned 29 // by simply value copying the struct. 30 type Iterator struct { 31 list *Skiplist 32 nd uint32 33 key base.InternalKey 34 lower []byte 35 upper []byte 36 } 37 38 // Close resets the iterator. 39 func (it *Iterator) Close() error { 40 it.list = nil 41 it.nd = 0 42 return nil 43 } 44 45 // SeekGE moves the iterator to the first entry whose key is greater than or 46 // equal to the given key. Returns true if the iterator is pointing at a valid 47 // entry and false otherwise. Note that SeekGE only checks the upper bound. It 48 // is up to the caller to ensure that key is greater than or equal to the lower 49 // bound. 50 func (it *Iterator) SeekGE(key []byte) *base.InternalKey { 51 _, it.nd = it.seekForBaseSplice(key, it.list.abbreviatedKey(key)) 52 if it.nd == it.list.tail { 53 return nil 54 } 55 nodeKey := it.list.getKey(it.nd) 56 if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 { 57 it.nd = it.list.tail 58 return nil 59 } 60 it.key = nodeKey 61 return &it.key 62 } 63 64 // SeekLT moves the iterator to the last entry whose key is less the given 65 // key. Returns true if the iterator is pointing at a valid entry and false 66 // otherwise. Note that SeekLT only checks the lower bound. It is up to the 67 // caller to ensure that key is less than the upper bound. 68 func (it *Iterator) SeekLT(key []byte) *base.InternalKey { 69 it.nd, _ = it.seekForBaseSplice(key, it.list.abbreviatedKey(key)) 70 if it.nd == it.list.head { 71 return nil 72 } 73 nodeKey := it.list.getKey(it.nd) 74 if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 { 75 it.nd = it.list.head 76 return nil 77 } 78 it.key = nodeKey 79 return &it.key 80 } 81 82 // First seeks position at the first entry in list. Final state of iterator is 83 // Valid() iff list is not empty. Note that First only checks the upper 84 // bound. It is up to the caller to ensure that key is greater than or equal to 85 // the lower bound (e.g. via a call to SeekGE(lower)). 86 func (it *Iterator) First() *base.InternalKey { 87 it.nd = it.list.getNext(it.list.head, 0) 88 if it.nd == it.list.tail { 89 return nil 90 } 91 nodeKey := it.list.getKey(it.nd) 92 if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 { 93 it.nd = it.list.tail 94 return nil 95 } 96 it.key = nodeKey 97 return &it.key 98 } 99 100 // Last seeks position at the last entry in list. Final state of iterator is 101 // Valid() iff list is not empty. Note that Last only checks the lower 102 // bound. It is up to the caller to ensure that key is less than the upper 103 // bound (e.g. via a call to SeekLT(upper)). 104 func (it *Iterator) Last() *base.InternalKey { 105 it.nd = it.list.getPrev(it.list.tail, 0) 106 if it.nd == it.list.head { 107 return nil 108 } 109 nodeKey := it.list.getKey(it.nd) 110 if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 { 111 it.nd = it.list.head 112 return nil 113 } 114 it.key = nodeKey 115 return &it.key 116 } 117 118 // Next advances to the next position. If there are no following nodes, then 119 // Valid() will be false after this call. 120 func (it *Iterator) Next() *base.InternalKey { 121 it.nd = it.list.getNext(it.nd, 0) 122 if it.nd == it.list.tail { 123 return nil 124 } 125 nodeKey := it.list.getKey(it.nd) 126 if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 { 127 it.nd = it.list.tail 128 return nil 129 } 130 it.key = nodeKey 131 return &it.key 132 } 133 134 // Prev moves to the previous position. If there are no previous nodes, then 135 // Valid() will be false after this call. 136 func (it *Iterator) Prev() *base.InternalKey { 137 it.nd = it.list.getPrev(it.nd, 0) 138 if it.nd == it.list.head { 139 return nil 140 } 141 nodeKey := it.list.getKey(it.nd) 142 if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 { 143 it.nd = it.list.head 144 return nil 145 } 146 it.key = nodeKey 147 return &it.key 148 } 149 150 // Key returns the key at the current position. 151 func (it *Iterator) Key() *base.InternalKey { 152 return &it.key 153 } 154 155 // KeyInfo returns the offset of the start of the record, the start of the key, 156 // and the end of the key. 157 func (it *Iterator) KeyInfo() (offset, keyStart, keyEnd uint32) { 158 n := it.list.node(it.nd) 159 return n.offset, n.keyStart, n.keyEnd 160 } 161 162 // Head true iff the iterator is positioned at the sentinel head node. 163 func (it *Iterator) Head() bool { 164 return it.nd == it.list.head 165 } 166 167 // Tail true iff the iterator is positioned at the sentinel tail node. 168 func (it *Iterator) Tail() bool { 169 return it.nd == it.list.tail 170 } 171 172 // Valid returns nil iff the iterator is positioned at a valid node. 173 func (it *Iterator) Valid() bool { 174 return it.list != nil && it.nd != it.list.head && it.nd != it.list.tail 175 } 176 177 func (it *Iterator) String() string { 178 return "batch" 179 } 180 181 // SetBounds sets the lower and upper bounds for the iterator. Note that the 182 // result of Next and Prev will be undefined until the iterator has been 183 // repositioned with SeekGE, SeekLT, First, or Last. 184 func (it *Iterator) SetBounds(lower, upper []byte) { 185 it.lower = lower 186 it.upper = upper 187 } 188 189 func (it *Iterator) seekForBaseSplice(key []byte, abbreviatedKey uint64) (prev, next uint32) { 190 prev = it.list.head 191 for level := it.list.height - 1; ; level-- { 192 prev, next = it.list.findSpliceForLevel(key, abbreviatedKey, level, prev) 193 if level == 0 { 194 break 195 } 196 } 197 198 return 199 }