github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/page_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 bitpage 16 17 import ( 18 "sync" 19 20 "github.com/cockroachdb/errors" 21 "github.com/zuoyebang/bitalosdb/internal/base" 22 "github.com/zuoyebang/bitalosdb/internal/utils" 23 ) 24 25 type iterPos int8 26 27 const ( 28 iterPosCurForward iterPos = 0 29 iterPosNext iterPos = 1 30 iterPosPrev iterPos = -1 31 iterPosCurReverse iterPos = -2 32 ) 33 34 const maxKeyBufCacheSize = 4 << 10 35 36 type pageIterAlloc struct { 37 dbi PageIterator 38 key internalKey 39 keyBuf []byte 40 prefixOrFullSeekKey []byte 41 merging mergingIter 42 mlevels [3]mergingIterLevel 43 } 44 45 var pageIterAllocPool = sync.Pool{ 46 New: func() interface{} { 47 return &pageIterAlloc{} 48 }, 49 } 50 51 type PageIterator struct { 52 opts iterOptions 53 cmp base.Compare 54 equal base.Equal 55 iter internalIterator 56 readState *readState 57 readStateCloser func() 58 err error 59 key *internalKey 60 keyBuf []byte 61 value []byte 62 iterKey *internalKey 63 iterValue []byte 64 alloc *pageIterAlloc 65 prefixOrFullSeekKey []byte 66 iterValidityState IterValidityState 67 pos iterPos 68 lastPositioningOp lastPositioningOpKind 69 } 70 71 type lastPositioningOpKind int8 72 73 const ( 74 unknownLastPositionOp lastPositioningOpKind = iota 75 seekGELastPositioningOp 76 seekLTLastPositioningOp 77 ) 78 79 type IterValidityState int8 80 81 const ( 82 IterExhausted IterValidityState = iota 83 IterValid 84 ) 85 86 func (i *PageIterator) getKV() (*base.InternalKey, []byte) { 87 if i.iterValidityState == IterValid { 88 return i.key, i.value 89 } 90 91 return nil, nil 92 } 93 94 func (i *PageIterator) findNextEntry() { 95 i.iterValidityState = IterExhausted 96 i.pos = iterPosCurForward 97 98 for i.iterKey != nil { 99 key := *i.iterKey 100 101 switch key.Kind() { 102 case internalKeyKindSet: 103 i.keyBuf = append(i.keyBuf[:0], key.UserKey...) 104 *i.key = base.MakeInternalKey2(i.keyBuf, key.Trailer) 105 i.value = i.iterValue 106 i.iterValidityState = IterValid 107 return 108 109 case internalKeyKindDelete, internalKeyKindPrefixDelete: 110 i.keyBuf = append(i.keyBuf[:0], key.UserKey...) 111 *i.key = base.MakeInternalKey2(i.keyBuf, key.Trailer) 112 i.value = nil 113 i.iterValidityState = IterValid 114 return 115 116 default: 117 i.err = errors.Errorf("bitpage: invalid internal key kind %s", key.Kind()) 118 i.iterValidityState = IterExhausted 119 return 120 } 121 } 122 } 123 124 func (i *PageIterator) nextUserKey() { 125 if i.iterKey == nil { 126 return 127 } 128 129 if i.iterValidityState != IterValid { 130 i.keyBuf = append(i.keyBuf[:0], i.iterKey.UserKey...) 131 *i.key = base.MakeInternalKey2(i.keyBuf, i.iterKey.Trailer) 132 } 133 134 for { 135 i.iterKey, i.iterValue = i.iter.Next() 136 if i.iterKey == nil || !i.equal(i.key.UserKey, i.iterKey.UserKey) { 137 break 138 } 139 } 140 } 141 142 func (i *PageIterator) findPrevEntry() { 143 i.iterValidityState = IterExhausted 144 i.pos = iterPosCurReverse 145 146 for i.iterKey != nil { 147 key := *i.iterKey 148 149 if i.iterValidityState == IterValid { 150 if !i.equal(key.UserKey, i.key.UserKey) { 151 i.pos = iterPosPrev 152 if i.err != nil { 153 i.iterValidityState = IterExhausted 154 } 155 return 156 } 157 } 158 159 switch key.Kind() { 160 case internalKeyKindSet: 161 i.keyBuf = append(i.keyBuf[:0], key.UserKey...) 162 *i.key = base.MakeInternalKey2(i.keyBuf, key.Trailer) 163 i.value = i.iterValue 164 i.iterValidityState = IterValid 165 i.iterKey, i.iterValue = i.iter.Prev() 166 case internalKeyKindDelete, internalKeyKindPrefixDelete: 167 i.keyBuf = append(i.keyBuf[:0], key.UserKey...) 168 *i.key = base.MakeInternalKey2(i.keyBuf, key.Trailer) 169 i.value = nil 170 i.iterValidityState = IterValid 171 i.iterKey, i.iterValue = i.iter.Prev() 172 default: 173 i.err = errors.Errorf("bitpage: invalid internal key kind %s", key.Kind()) 174 i.iterValidityState = IterExhausted 175 return 176 } 177 } 178 179 if i.iterValidityState == IterValid { 180 i.pos = iterPosPrev 181 if i.err != nil { 182 i.iterValidityState = IterExhausted 183 } 184 } 185 } 186 187 func (i *PageIterator) prevUserKey() { 188 if i.iterKey == nil { 189 return 190 } 191 if i.iterValidityState != IterValid { 192 i.keyBuf = append(i.keyBuf[:0], i.iterKey.UserKey...) 193 *i.key = base.MakeInternalKey2(i.keyBuf, i.iterKey.Trailer) 194 } 195 for { 196 i.iterKey, i.iterValue = i.iter.Prev() 197 if i.iterKey == nil { 198 break 199 } 200 if !i.equal(i.key.UserKey, i.iterKey.UserKey) { 201 break 202 } 203 } 204 } 205 206 func (i *PageIterator) SeekGE(key []byte) (*internalKey, []byte) { 207 lastPositioningOp := i.lastPositioningOp 208 209 i.lastPositioningOp = unknownLastPositionOp 210 i.err = nil 211 if lowerBound := i.opts.GetLowerBound(); lowerBound != nil && i.cmp(key, lowerBound) < 0 { 212 key = lowerBound 213 } else if upperBound := i.opts.GetUpperBound(); upperBound != nil && i.cmp(key, upperBound) > 0 { 214 key = upperBound 215 } 216 217 if lastPositioningOp == seekGELastPositioningOp { 218 if i.cmp(i.prefixOrFullSeekKey, key) <= 0 { 219 if i.iterValidityState == IterExhausted || (i.iterValidityState == IterValid && i.cmp(key, i.key.UserKey) <= 0) { 220 return i.getKV() 221 } 222 } 223 } 224 225 i.iterKey, i.iterValue = i.iter.SeekGE(key) 226 i.findNextEntry() 227 if i.Error() == nil { 228 i.prefixOrFullSeekKey = append(i.prefixOrFullSeekKey[:0], key...) 229 i.lastPositioningOp = seekGELastPositioningOp 230 } 231 return i.getKV() 232 } 233 234 func (i *PageIterator) SeekPrefixGE(prefix, key []byte, trySeekUsingNext bool) (*internalKey, []byte) { 235 return nil, nil 236 } 237 238 func (i *PageIterator) SeekLT(key []byte) (*internalKey, []byte) { 239 lastPositioningOp := i.lastPositioningOp 240 i.lastPositioningOp = unknownLastPositionOp 241 i.err = nil 242 if upperBound := i.opts.GetUpperBound(); upperBound != nil && i.cmp(key, upperBound) > 0 { 243 key = upperBound 244 } else if lowerBound := i.opts.GetLowerBound(); lowerBound != nil && i.cmp(key, lowerBound) < 0 { 245 key = lowerBound 246 } 247 248 if lastPositioningOp == seekLTLastPositioningOp { 249 if i.cmp(key, i.prefixOrFullSeekKey) <= 0 { 250 if i.iterValidityState == IterExhausted || (i.iterValidityState == IterValid && i.cmp(i.key.UserKey, key) < 0) { 251 return i.getKV() 252 } 253 } 254 } 255 256 i.iterKey, i.iterValue = i.iter.SeekLT(key) 257 i.findPrevEntry() 258 if i.Error() == nil { 259 i.prefixOrFullSeekKey = append(i.prefixOrFullSeekKey[:0], key...) 260 i.lastPositioningOp = seekLTLastPositioningOp 261 } 262 return i.getKV() 263 } 264 265 func (i *PageIterator) First() (*internalKey, []byte) { 266 i.err = nil 267 i.lastPositioningOp = unknownLastPositionOp 268 if lowerBound := i.opts.GetLowerBound(); lowerBound != nil { 269 i.iterKey, i.iterValue = i.iter.SeekGE(lowerBound) 270 } else { 271 i.iterKey, i.iterValue = i.iter.First() 272 } 273 i.findNextEntry() 274 return i.getKV() 275 } 276 277 func (i *PageIterator) Last() (*internalKey, []byte) { 278 i.err = nil 279 i.lastPositioningOp = unknownLastPositionOp 280 if upperBound := i.opts.GetUpperBound(); upperBound != nil { 281 i.iterKey, i.iterValue = i.iter.SeekLT(upperBound) 282 } else { 283 i.iterKey, i.iterValue = i.iter.Last() 284 } 285 i.findPrevEntry() 286 return i.getKV() 287 } 288 289 func (i *PageIterator) Next() (*internalKey, []byte) { 290 if i.err != nil { 291 return i.getKV() 292 } 293 i.lastPositioningOp = unknownLastPositionOp 294 switch i.pos { 295 case iterPosCurForward: 296 i.nextUserKey() 297 case iterPosCurReverse: 298 if i.iterKey != nil { 299 i.err = errors.New("switching from reverse to forward but iter is not at prev") 300 i.iterValidityState = IterExhausted 301 break 302 } 303 if lowerBound := i.opts.GetLowerBound(); lowerBound != nil { 304 i.iterKey, i.iterValue = i.iter.SeekGE(lowerBound) 305 } else { 306 i.iterKey, i.iterValue = i.iter.First() 307 } 308 case iterPosPrev: 309 i.iterValidityState = IterExhausted 310 if i.iterKey == nil { 311 if lowerBound := i.opts.GetLowerBound(); lowerBound != nil { 312 i.iterKey, i.iterValue = i.iter.SeekGE(lowerBound) 313 } else { 314 i.iterKey, i.iterValue = i.iter.First() 315 } 316 } else { 317 i.nextUserKey() 318 } 319 i.nextUserKey() 320 } 321 i.findNextEntry() 322 return i.getKV() 323 } 324 325 func (i *PageIterator) Prev() (*internalKey, []byte) { 326 if i.err != nil { 327 return i.getKV() 328 } 329 i.lastPositioningOp = unknownLastPositionOp 330 switch i.pos { 331 case iterPosCurForward: 332 case iterPosCurReverse: 333 i.prevUserKey() 334 case iterPosPrev: 335 } 336 if i.pos == iterPosCurForward { 337 i.iterValidityState = IterExhausted 338 if i.iterKey == nil { 339 if upperBound := i.opts.GetUpperBound(); upperBound != nil { 340 i.iterKey, i.iterValue = i.iter.SeekLT(upperBound) 341 } else { 342 i.iterKey, i.iterValue = i.iter.Last() 343 } 344 } else { 345 i.prevUserKey() 346 } 347 } 348 i.findPrevEntry() 349 return i.getKV() 350 } 351 352 func (i *PageIterator) String() string { 353 return "PageIterator" 354 } 355 356 func (i *PageIterator) Error() error { 357 err := i.err 358 if i.iter != nil { 359 err = utils.FirstError(i.err, i.iter.Error()) 360 } 361 return err 362 } 363 364 func (i *PageIterator) Close() error { 365 if i.iter != nil { 366 i.err = utils.FirstError(i.err, i.iter.Close()) 367 } 368 err := i.err 369 370 if i.readStateCloser != nil { 371 i.readStateCloser() 372 i.readStateCloser = nil 373 } 374 375 if alloc := i.alloc; alloc != nil { 376 if cap(i.keyBuf) >= maxKeyBufCacheSize { 377 alloc.keyBuf = nil 378 } else { 379 alloc.keyBuf = i.keyBuf 380 } 381 if cap(i.prefixOrFullSeekKey) >= maxKeyBufCacheSize { 382 alloc.prefixOrFullSeekKey = nil 383 } else { 384 alloc.prefixOrFullSeekKey = i.prefixOrFullSeekKey 385 } 386 *i = PageIterator{} 387 pageIterAllocPool.Put(alloc) 388 } 389 return err 390 } 391 392 func (i *PageIterator) SetBounds(lower, upper []byte) { 393 i.lastPositioningOp = unknownLastPositionOp 394 i.iterKey = nil 395 i.iterValue = nil 396 397 switch i.pos { 398 case iterPosCurForward: 399 i.pos = iterPosCurForward 400 case iterPosCurReverse, iterPosPrev: 401 i.pos = iterPosCurReverse 402 } 403 i.iterValidityState = IterExhausted 404 405 i.opts.LowerBound = lower 406 i.opts.UpperBound = upper 407 i.iter.SetBounds(lower, upper) 408 }