github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/arenaskl/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 arenaskl 19 20 import ( 21 "encoding/binary" 22 "sync" 23 24 "github.com/zuoyebang/bitalostable/internal/base" 25 ) 26 27 type splice struct { 28 prev *node 29 next *node 30 } 31 32 func (s *splice) init(prev, next *node) { 33 s.prev = prev 34 s.next = next 35 } 36 37 // Iterator is an iterator over the skiplist object. Use Skiplist.NewIter 38 // to construct an iterator. The current state of the iterator can be cloned by 39 // simply value copying the struct. All iterator methods are thread-safe. 40 type Iterator struct { 41 list *Skiplist 42 nd *node 43 key base.InternalKey 44 lower []byte 45 upper []byte 46 } 47 48 // Iterator implements the base.InternalIterator interface. 49 var _ base.InternalIterator = (*Iterator)(nil) 50 51 var iterPool = sync.Pool{ 52 New: func() interface{} { 53 return &Iterator{} 54 }, 55 } 56 57 // Close resets the iterator. 58 func (it *Iterator) Close() error { 59 it.list = nil 60 it.nd = nil 61 it.lower = nil 62 it.upper = nil 63 iterPool.Put(it) 64 return nil 65 } 66 67 func (it *Iterator) String() string { 68 return "memtable" 69 } 70 71 // Error returns any accumulated error. 72 func (it *Iterator) Error() error { 73 return nil 74 } 75 76 // SeekGE moves the iterator to the first entry whose key is greater than or 77 // equal to the given key. Returns the key and value if the iterator is 78 // pointing at a valid entry, and (nil, nil) otherwise. Note that SeekGE only 79 // checks the upper bound. It is up to the caller to ensure that key is greater 80 // than or equal to the lower bound. 81 func (it *Iterator) SeekGE(key []byte, flags base.SeekGEFlags) (*base.InternalKey, []byte) { 82 if flags.TrySeekUsingNext() { 83 if it.nd == it.list.tail { 84 // Iterator is done. 85 return nil, nil 86 } 87 less := it.list.cmp(it.key.UserKey, key) < 0 88 // Arbitrary constant. By measuring the seek cost as a function of the 89 // number of elements in the skip list, and fitting to a model, we 90 // could adjust the number of nexts based on the current size of the 91 // skip list. 92 const numNexts = 5 93 for i := 0; less && i < numNexts; i++ { 94 k, _ := it.Next() 95 if k == nil { 96 // Iterator is done. 97 return nil, nil 98 } 99 less = it.list.cmp(it.key.UserKey, key) < 0 100 } 101 if !less { 102 return &it.key, it.value() 103 } 104 } 105 _, it.nd, _ = it.seekForBaseSplice(key) 106 if it.nd == it.list.tail { 107 return nil, nil 108 } 109 it.decodeKey() 110 if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 { 111 it.nd = it.list.tail 112 return nil, nil 113 } 114 return &it.key, it.value() 115 } 116 117 // SeekPrefixGE moves the iterator to the first entry whose key is greater than 118 // or equal to the given key. This method is equivalent to SeekGE and is 119 // provided so that an arenaskl.Iterator implements the 120 // internal/base.InternalIterator interface. 121 func (it *Iterator) SeekPrefixGE( 122 prefix, key []byte, flags base.SeekGEFlags, 123 ) (*base.InternalKey, []byte) { 124 return it.SeekGE(key, flags) 125 } 126 127 // SeekLT moves the iterator to the last entry whose key is less than the given 128 // key. Returns the key and value if the iterator is pointing at a valid entry, 129 // and (nil, nil) otherwise. Note that SeekLT only checks the lower bound. It 130 // is up to the caller to ensure that key is less than the upper bound. 131 func (it *Iterator) SeekLT(key []byte, flags base.SeekLTFlags) (*base.InternalKey, []byte) { 132 // NB: the top-level Iterator has already adjusted key based on 133 // the upper-bound. 134 it.nd, _, _ = it.seekForBaseSplice(key) 135 if it.nd == it.list.head { 136 return nil, nil 137 } 138 it.decodeKey() 139 if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 { 140 it.nd = it.list.head 141 return nil, nil 142 } 143 return &it.key, it.value() 144 } 145 146 // First seeks position at the first entry in list. Returns the key and value 147 // if the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note 148 // that First only checks the upper bound. It is up to the caller to ensure 149 // that key is greater than or equal to the lower bound (e.g. via a call to SeekGE(lower)). 150 func (it *Iterator) First() (*base.InternalKey, []byte) { 151 it.nd = it.list.getNext(it.list.head, 0) 152 if it.nd == it.list.tail { 153 return nil, nil 154 } 155 it.decodeKey() 156 if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 { 157 it.nd = it.list.tail 158 return nil, nil 159 } 160 return &it.key, it.value() 161 } 162 163 // Last seeks position at the last entry in list. Returns the key and value if 164 // the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note 165 // that Last only checks the lower bound. It is up to the caller to ensure that 166 // key is less than the upper bound (e.g. via a call to SeekLT(upper)). 167 func (it *Iterator) Last() (*base.InternalKey, []byte) { 168 it.nd = it.list.getPrev(it.list.tail, 0) 169 if it.nd == it.list.head { 170 return nil, nil 171 } 172 it.decodeKey() 173 if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 { 174 it.nd = it.list.head 175 return nil, nil 176 } 177 return &it.key, it.value() 178 } 179 180 // Next advances to the next position. Returns the key and value if the 181 // iterator is pointing at a valid entry, and (nil, nil) otherwise. 182 // Note: flushIterator.Next mirrors the implementation of Iterator.Next 183 // due to performance. Keep the two in sync. 184 func (it *Iterator) Next() (*base.InternalKey, []byte) { 185 it.nd = it.list.getSkipNext(it.nd) 186 if it.nd == it.list.tail { 187 return nil, nil 188 } 189 it.decodeKey() 190 if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 { 191 it.nd = it.list.tail 192 return nil, nil 193 } 194 return &it.key, it.value() 195 } 196 197 // Prev moves to the previous position. Returns the key and value if the 198 // iterator is pointing at a valid entry, and (nil, nil) otherwise. 199 func (it *Iterator) Prev() (*base.InternalKey, []byte) { 200 it.nd = it.list.getSkipPrev(it.nd) 201 if it.nd == it.list.head { 202 return nil, nil 203 } 204 it.decodeKey() 205 if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 { 206 it.nd = it.list.head 207 return nil, nil 208 } 209 return &it.key, it.value() 210 } 211 212 // value returns the value at the current position. 213 func (it *Iterator) value() []byte { 214 return it.nd.getValue(it.list.arena) 215 } 216 217 // Head true iff the iterator is positioned at the sentinel head node. 218 func (it *Iterator) Head() bool { 219 return it.nd == it.list.head 220 } 221 222 // Tail true iff the iterator is positioned at the sentinel tail node. 223 func (it *Iterator) Tail() bool { 224 return it.nd == it.list.tail 225 } 226 227 // SetBounds sets the lower and upper bounds for the iterator. Note that the 228 // result of Next and Prev will be undefined until the iterator has been 229 // repositioned with SeekGE, SeekPrefixGE, SeekLT, First, or Last. 230 func (it *Iterator) SetBounds(lower, upper []byte) { 231 it.lower = lower 232 it.upper = upper 233 } 234 235 func (it *Iterator) decodeKey() { 236 b := it.list.arena.getBytes(it.nd.keyOffset, it.nd.keySize) 237 // This is a manual inline of base.DecodeInternalKey, because the Go compiler 238 // seems to refuse to automatically inline it currently. 239 l := len(b) - 8 240 if l >= 0 { 241 it.key.Trailer = binary.LittleEndian.Uint64(b[l:]) 242 it.key.UserKey = b[:l:l] 243 } else { 244 it.key.Trailer = uint64(base.InternalKeyKindInvalid) 245 it.key.UserKey = nil 246 } 247 } 248 249 func (it *Iterator) seekForBaseSplice(key []byte) (prev, next *node, found bool) { 250 ikey := base.MakeSearchKey(key) 251 level := int(it.list.Height() - 1) 252 253 prev = it.list.head 254 for { 255 prev, next, found = it.list.findSpliceForLevel(ikey, level, prev) 256 257 if found { 258 if level != 0 { 259 // next is pointing at the target node, but we need to find previous on 260 // the bottom level. 261 prev = it.list.getPrev(next, 0) 262 } 263 break 264 } 265 266 if level == 0 { 267 break 268 } 269 270 level-- 271 } 272 273 return 274 }