github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/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 "context" 22 "sync" 23 24 "github.com/cockroachdb/pebble/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, base.LazyValue) { 82 if flags.TrySeekUsingNext() { 83 if it.nd == it.list.tail { 84 // Iterator is done. 85 return nil, base.LazyValue{} 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, base.LazyValue{} 98 } 99 less = it.list.cmp(it.key.UserKey, key) < 0 100 } 101 if !less { 102 return &it.key, base.MakeInPlaceValue(it.value()) 103 } 104 } 105 _, it.nd, _ = it.seekForBaseSplice(key) 106 if it.nd == it.list.tail { 107 return nil, base.LazyValue{} 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, base.LazyValue{} 113 } 114 return &it.key, base.MakeInPlaceValue(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, base.LazyValue) { 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, base.LazyValue) { 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, base.LazyValue{} 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, base.LazyValue{} 142 } 143 return &it.key, base.MakeInPlaceValue(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, base.LazyValue) { 151 it.nd = it.list.getNext(it.list.head, 0) 152 if it.nd == it.list.tail { 153 return nil, base.LazyValue{} 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, base.LazyValue{} 159 } 160 return &it.key, base.MakeInPlaceValue(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, base.LazyValue) { 168 it.nd = it.list.getPrev(it.list.tail, 0) 169 if it.nd == it.list.head { 170 return nil, base.LazyValue{} 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, base.LazyValue{} 176 } 177 return &it.key, base.MakeInPlaceValue(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, base.LazyValue) { 185 it.nd = it.list.getNext(it.nd, 0) 186 if it.nd == it.list.tail { 187 return nil, base.LazyValue{} 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, base.LazyValue{} 193 } 194 return &it.key, base.MakeInPlaceValue(it.value()) 195 } 196 197 // NextPrefix advances to the next position with a new prefix. Returns the key 198 // and value if the iterator is pointing at a valid entry, and (nil, nil) 199 // otherwise. 200 func (it *Iterator) NextPrefix(succKey []byte) (*base.InternalKey, base.LazyValue) { 201 return it.SeekGE(succKey, base.SeekGEFlagsNone.EnableTrySeekUsingNext()) 202 } 203 204 // Prev moves to the previous position. Returns the key and value if the 205 // iterator is pointing at a valid entry, and (nil, nil) otherwise. 206 func (it *Iterator) Prev() (*base.InternalKey, base.LazyValue) { 207 it.nd = it.list.getPrev(it.nd, 0) 208 if it.nd == it.list.head { 209 return nil, base.LazyValue{} 210 } 211 it.decodeKey() 212 if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 { 213 it.nd = it.list.head 214 return nil, base.LazyValue{} 215 } 216 return &it.key, base.MakeInPlaceValue(it.value()) 217 } 218 219 // value returns the value at the current position. 220 func (it *Iterator) value() []byte { 221 return it.nd.getValue(it.list.arena) 222 } 223 224 // Head true iff the iterator is positioned at the sentinel head node. 225 func (it *Iterator) Head() bool { 226 return it.nd == it.list.head 227 } 228 229 // Tail true iff the iterator is positioned at the sentinel tail node. 230 func (it *Iterator) Tail() bool { 231 return it.nd == it.list.tail 232 } 233 234 // SetBounds sets the lower and upper bounds for the iterator. Note that the 235 // result of Next and Prev will be undefined until the iterator has been 236 // repositioned with SeekGE, SeekPrefixGE, SeekLT, First, or Last. 237 func (it *Iterator) SetBounds(lower, upper []byte) { 238 it.lower = lower 239 it.upper = upper 240 } 241 242 // SetContext implements base.InternalIterator. 243 func (it *Iterator) SetContext(_ context.Context) {} 244 245 func (it *Iterator) decodeKey() { 246 it.key.UserKey = it.list.arena.getBytes(it.nd.keyOffset, it.nd.keySize) 247 it.key.Trailer = it.nd.keyTrailer 248 } 249 250 func (it *Iterator) seekForBaseSplice(key []byte) (prev, next *node, found bool) { 251 ikey := base.MakeSearchKey(key) 252 level := int(it.list.Height() - 1) 253 254 prev = it.list.head 255 for { 256 prev, next, found = it.list.findSpliceForLevel(ikey, level, prev) 257 258 if found { 259 if level != 0 { 260 // next is pointing at the target node, but we need to find previous on 261 // the bottom level. 262 prev = it.list.getPrev(next, 0) 263 } 264 break 265 } 266 267 if level == 0 { 268 break 269 } 270 271 level-- 272 } 273 274 return 275 }