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