github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/super_table_index.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 "io" 20 "time" 21 22 "github.com/cockroachdb/errors" 23 "github.com/zuoyebang/bitalosdb/internal/base" 24 "github.com/zuoyebang/bitalosdb/internal/utils" 25 ) 26 27 func (s *superTable) rebuildIndexes() (err error) { 28 var its []internalIterator 29 var sstIter *sstIterator 30 var keySize uint16 31 var valueSize uint32 32 var offset, keyOffset, n int 33 var prevKey []byte 34 var newIndexes stIndexes 35 var readCost, compactCost float64 36 37 file := s.tbl.file 38 fileSize := int(s.tbl.Size()) 39 readBuf := s.p.bp.getStArenaBuf(fileSize) 40 readBuf = readBuf[:fileSize] 41 42 startTime := time.Now() 43 s.p.bp.opts.Logger.Infof("superTable rebuild indexes start file:%s fileSize:%d", s.filename, fileSize) 44 defer func() { 45 prevKey = nil 46 readBuf = nil 47 its = nil 48 sstIter = nil 49 s.p.bp.opts.Logger.Infof("superTable rebuild indexes finish its:%d idx:%d offset:%d keyOffset:%d readCost:%.3fs compactCost:%.3fs", 50 len(its), len(newIndexes), offset, keyOffset, readCost, compactCost) 51 }() 52 53 n, err = file.ReadAt(readBuf, 0) 54 if err != nil { 55 return err 56 } 57 if n != fileSize { 58 return errors.Errorf("bitpage: superTable rebuild indexes readAt return not eq %d != %d", n, fileSize) 59 } 60 61 sstIter = &sstIterator{} 62 offset = stDataOffset 63 for { 64 keyOffset = offset 65 66 if len(readBuf[offset:]) < stItemHeaderSize { 67 break 68 } 69 keySize, valueSize = s.writer.decodeHeader(readBuf[offset : offset+stItemHeaderSize]) 70 if keySize == 0 { 71 break 72 } 73 offset += stItemHeaderSize 74 kvSize := int(keySize) + int(valueSize) 75 if len(readBuf[offset:]) < kvSize { 76 break 77 } 78 79 key := readBuf[offset : offset+int(keySize)] 80 ikey := base.DecodeInternalKey(key) 81 offset += kvSize 82 83 if prevKey != nil && bytes.Compare(prevKey, ikey.UserKey) >= 0 { 84 its = append(its, sstIter) 85 sstIter = &sstIterator{} 86 } 87 sstIter.data = append(sstIter.data, sstItem{ 88 key: ikey, 89 offset: uint32(keyOffset), 90 }) 91 sstIter.num += 1 92 prevKey = ikey.UserKey 93 } 94 readCost = time.Since(startTime).Seconds() 95 if err != nil && err != io.EOF { 96 return err 97 } 98 if len(sstIter.data) > 0 { 99 its = append(its, sstIter) 100 } 101 if len(its) == 0 { 102 return nil 103 } 104 105 if err = s.writer.reset(keyOffset); err != nil { 106 return err 107 } 108 109 iiter := newMergingIter(s.p.bp.opts.Logger, s.p.bp.opts.Cmp, its...) 110 iter := newCompactionIter(s.p.bp, iiter) 111 defer func() { 112 _ = iter.Close() 113 }() 114 115 for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() { 116 newIndexes = append(newIndexes, utils.BytesToUint32(iv)) 117 } 118 119 compactCost = time.Since(startTime).Seconds() - readCost 120 s.reading.Store(&newIndexes) 121 s.indexModified = true 122 123 return nil 124 } 125 126 type sstItem struct { 127 key internalKey 128 offset uint32 129 } 130 131 type sstIterator struct { 132 data []sstItem 133 num int 134 iterPos int 135 iterItem *sstItem 136 } 137 138 func (i *sstIterator) findItem() (*internalKey, []byte) { 139 if i.iterPos < 0 || i.iterPos >= i.num { 140 return nil, nil 141 } 142 143 item := i.data[i.iterPos] 144 return &(item.key), utils.Uint32ToBytes(item.offset) 145 } 146 147 func (i *sstIterator) First() (*internalKey, []byte) { 148 i.iterPos = 0 149 return i.findItem() 150 } 151 152 func (i *sstIterator) Next() (*internalKey, []byte) { 153 i.iterPos++ 154 return i.findItem() 155 } 156 157 func (i *sstIterator) Prev() (*internalKey, []byte) { 158 i.iterPos-- 159 return i.findItem() 160 } 161 162 func (i *sstIterator) Last() (*internalKey, []byte) { 163 i.iterPos = i.num - 1 164 return i.findItem() 165 } 166 167 func (i *sstIterator) SeekGE(key []byte) (*internalKey, []byte) { 168 return nil, nil 169 } 170 171 func (i *sstIterator) SeekLT(key []byte) (*internalKey, []byte) { 172 return nil, nil 173 } 174 175 func (i *sstIterator) SeekPrefixGE( 176 prefix, key []byte, trySeekUsingNext bool, 177 ) (ikey *internalKey, value []byte) { 178 return i.SeekGE(key) 179 } 180 181 func (i *sstIterator) SetBounds(lower, upper []byte) { 182 } 183 184 func (i *sstIterator) Error() error { 185 return nil 186 } 187 188 func (i *sstIterator) Close() error { 189 i.data = nil 190 i.iterItem = nil 191 return nil 192 } 193 194 func (i *sstIterator) String() string { 195 return "sstIterator" 196 }