github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/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 bitalosdb 16 17 import ( 18 "github.com/cockroachdb/errors" 19 "github.com/zuoyebang/bitalosdb/internal/base" 20 ) 21 22 type compactionIter struct { 23 cmp Compare 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 first bool 35 end bool 36 } 37 38 func (i *compactionIter) IsVisitFirst() bool { 39 return i.first == true 40 } 41 42 func (i *compactionIter) SetVisitEnd() { 43 i.end = true 44 } 45 46 func (i *compactionIter) IsVisitEnd() bool { 47 return i.end == true 48 } 49 50 func (i *compactionIter) First() (*InternalKey, []byte) { 51 i.first = true 52 if i.err != nil { 53 return nil, nil 54 } 55 i.iterKey, i.iterValue = i.iter.First() 56 i.pos = iterPosNext 57 return i.Next() 58 } 59 60 func (i *compactionIter) Next() (*InternalKey, []byte) { 61 if i.err != nil { 62 return nil, nil 63 } 64 65 if i.pos == iterPosCurForward { 66 if i.skip { 67 i.skipInStripe() 68 } else { 69 i.nextInStripe() 70 } 71 } 72 73 i.pos = iterPosCurForward 74 i.valid = false 75 for i.iterKey != nil { 76 switch i.iterKey.Kind() { 77 case InternalKeyKindSet, InternalKeyKindDelete, InternalKeyKindPrefixDelete: 78 i.saveKey() 79 i.value = i.iterValue 80 i.valid = true 81 i.skip = true 82 return &i.key, i.value 83 default: 84 i.err = errors.Errorf("bitalosdb: invalid internal key kind %d", i.iterKey.Kind()) 85 i.valid = false 86 return nil, nil 87 } 88 } 89 90 return nil, nil 91 } 92 93 func (i *compactionIter) skipInStripe() { 94 i.skip = true 95 var change stripeChangeType 96 for { 97 change = i.nextInStripe() 98 if change == sameStripeNonSkippable || change == newStripe { 99 break 100 } 101 } 102 if change == newStripe { 103 i.skip = false 104 } 105 } 106 107 func (i *compactionIter) iterNext() bool { 108 i.iterKey, i.iterValue = i.iter.Next() 109 return i.iterKey != nil 110 } 111 112 type stripeChangeType int 113 114 const ( 115 newStripe stripeChangeType = iota 116 sameStripeSkippable 117 sameStripeNonSkippable 118 ) 119 120 func (i *compactionIter) nextInStripe() stripeChangeType { 121 if !i.iterNext() { 122 return newStripe 123 } 124 125 key := i.iterKey 126 if i.cmp(i.key.UserKey, key.UserKey) != 0 { 127 return newStripe 128 } 129 130 if key.Kind() == base.InternalKeyKindInvalid { 131 return sameStripeNonSkippable 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 return i.err 164 }