github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/page_block_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 "bytes" 19 "sync" 20 21 "github.com/zuoyebang/bitalosdb/internal/base" 22 ) 23 24 var _ base.InternalIterator = (*pageBlockIterator)(nil) 25 26 type pageBlockIterator struct { 27 pb *pageBlock 28 intIndexPos int 29 iterKey internalKey 30 keyBuf []byte 31 iterValue []byte 32 sharedCache *sharedInfo 33 } 34 35 var pbIterPool = sync.Pool{ 36 New: func() interface{} { 37 return &pageBlockIterator{} 38 }, 39 } 40 41 func (pi *pageBlockIterator) findItem() (*internalKey, []byte) { 42 sharedKey1, sharedKey2, value := pi.pb.getSharedKV(pi.intIndexPos, pi.sharedCache) 43 if sharedKey1 == nil { 44 return nil, nil 45 } 46 47 var key []byte 48 if sharedKey2 == nil { 49 key = sharedKey1 50 } else { 51 pi.keyBuf = append(pi.keyBuf[:0], sharedKey1...) 52 key = append(pi.keyBuf, sharedKey2...) 53 } 54 55 pi.iterKey = base.MakeInternalSetKey(key) 56 pi.iterValue = value 57 return &pi.iterKey, pi.iterValue 58 } 59 60 func (pi *pageBlockIterator) First() (*internalKey, []byte) { 61 pi.intIndexPos = 0 62 return pi.findItem() 63 } 64 65 func (pi *pageBlockIterator) Next() (*internalKey, []byte) { 66 pi.intIndexPos++ 67 return pi.findItem() 68 } 69 70 func (pi *pageBlockIterator) Prev() (*internalKey, []byte) { 71 pi.intIndexPos-- 72 return pi.findItem() 73 } 74 75 func (pi *pageBlockIterator) Last() (*internalKey, []byte) { 76 pi.intIndexPos = pi.pb.num - 1 77 return pi.findItem() 78 } 79 80 func (pi *pageBlockIterator) SeekGE(key []byte) (*internalKey, []byte) { 81 pi.intIndexPos = pi.pb.findKeyByIntIndex(key) 82 return pi.findItem() 83 } 84 85 func (pi *pageBlockIterator) SeekLT(key []byte) (*internalKey, []byte) { 86 pi.intIndexPos = pi.pb.findKeyByIntIndex(key) 87 poskey, _ := pi.findItem() 88 if poskey != nil { 89 return pi.Prev() 90 } 91 92 lastKey, lastValue := pi.Last() 93 if lastKey != nil && bytes.Compare(lastKey.UserKey, key) < 0 { 94 return lastKey, lastValue 95 } 96 97 return nil, nil 98 } 99 100 func (pi *pageBlockIterator) SeekPrefixGE( 101 prefix, key []byte, trySeekUsingNext bool, 102 ) (ikey *internalKey, value []byte) { 103 return pi.SeekGE(key) 104 } 105 106 func (pi *pageBlockIterator) SetBounds(lower, upper []byte) { 107 } 108 109 func (pi *pageBlockIterator) Error() error { 110 return nil 111 } 112 113 func (pi *pageBlockIterator) Close() error { 114 pi.pb = nil 115 pi.intIndexPos = 0 116 pi.iterValue = nil 117 if pi.keyBuf != nil { 118 pi.keyBuf = pi.keyBuf[:0] 119 } 120 if pi.sharedCache != nil { 121 pi.sharedCache.idx = -1 122 pi.sharedCache.key = nil 123 } 124 pbIterPool.Put(pi) 125 return nil 126 } 127 128 func (pi *pageBlockIterator) String() string { 129 return "pageBlockIterator" 130 }