github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/compaction_iter.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 "errors" 20 ) 21 22 type compactionIter struct { 23 bp *Bitpage 24 iter internalIterator 25 err error 26 key internalKey 27 value []byte 28 keyBuf []byte 29 valid bool 30 iterKey *internalKey 31 iterValue []byte 32 skip bool 33 pos iterPos 34 } 35 36 func newCompactionIter(bp *Bitpage, iter internalIterator) *compactionIter { 37 i := &compactionIter{ 38 bp: bp, 39 iter: iter, 40 } 41 return i 42 } 43 44 func (i *compactionIter) First() (*internalKey, []byte) { 45 if i.err != nil { 46 return nil, nil 47 } 48 i.iterKey, i.iterValue = i.iter.First() 49 i.pos = iterPosNext 50 return i.Next() 51 } 52 53 func (i *compactionIter) Next() (*internalKey, []byte) { 54 if i.err != nil { 55 return nil, nil 56 } 57 58 if i.pos == iterPosCurForward { 59 if i.skip { 60 i.skipInStripe() 61 } else { 62 i.nextInStripe() 63 } 64 } 65 66 i.pos = iterPosCurForward 67 i.valid = false 68 for i.iterKey != nil { 69 switch i.iterKey.Kind() { 70 case internalKeyKindSet, internalKeyKindDelete, internalKeyKindPrefixDelete: 71 i.saveKey() 72 i.value = i.iterValue 73 i.valid = true 74 i.skip = true 75 return &i.key, i.value 76 77 default: 78 i.err = errors.New("invalid internal key kind") 79 i.valid = false 80 return nil, nil 81 } 82 } 83 84 return nil, nil 85 } 86 87 func (i *compactionIter) skipInStripe() { 88 i.skip = true 89 var change stripeChangeType 90 for { 91 change = i.nextInStripe() 92 if change == sameStripeNonSkippable || change == newStripe { 93 break 94 } 95 } 96 97 if change == newStripe { 98 i.skip = false 99 } 100 } 101 102 func (i *compactionIter) iterNext() bool { 103 i.iterKey, i.iterValue = i.iter.Next() 104 return i.iterKey != nil 105 } 106 107 type stripeChangeType int 108 109 const ( 110 newStripe stripeChangeType = iota 111 sameStripeSkippable 112 sameStripeNonSkippable 113 ) 114 115 func (i *compactionIter) nextInStripe() stripeChangeType { 116 if !i.iterNext() { 117 return newStripe 118 } 119 120 key := i.iterKey 121 if !bytes.Equal(i.key.UserKey, key.UserKey) { 122 return newStripe 123 } 124 125 if key.Kind() == internalKeyKindInvalid { 126 return sameStripeNonSkippable 127 } 128 129 if i.bp != nil && key.SeqNum() == 1 { 130 i.bp.deleteBithashKey(i.iterValue) 131 } 132 133 return sameStripeSkippable 134 } 135 136 func (i *compactionIter) saveKey() { 137 i.keyBuf = append(i.keyBuf[:0], i.iterKey.UserKey...) 138 i.key.UserKey = i.keyBuf 139 i.key.Trailer = i.iterKey.Trailer 140 } 141 142 func (i *compactionIter) Key() internalKey { 143 return i.key 144 } 145 146 func (i *compactionIter) Value() []byte { 147 return i.value 148 } 149 150 func (i *compactionIter) Valid() bool { 151 return i.valid 152 } 153 154 func (i *compactionIter) Error() error { 155 return i.err 156 } 157 158 func (i *compactionIter) Close() error { 159 err := i.iter.Close() 160 if i.err == nil { 161 i.err = err 162 } 163 164 return i.err 165 }