github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/batch_bitower.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 "encoding/binary" 19 "errors" 20 "sync" 21 "sync/atomic" 22 "unsafe" 23 24 "github.com/zuoyebang/bitalosdb/internal/rawalloc" 25 ) 26 27 const ( 28 batchCountOffset = 8 29 batchHeaderLen = 12 30 batchInitialSize = 1 << 10 31 batchMaxRetainedSize = 1 << 20 32 invalidBatchCount = 1<<32 - 1 33 maxVarintLen32 = 5 34 ) 35 36 var ErrInvalidBatch = errors.New("bitalosdb: invalid batch") 37 38 type DeferredBatchOp struct { 39 Key, Value []byte 40 offset uint32 41 } 42 43 func (d DeferredBatchOp) Finish() error { 44 return nil 45 } 46 47 type BatchBitower struct { 48 db *DB 49 data []byte 50 cmp Compare 51 memTableSize uint64 52 count uint64 53 deferredOp DeferredBatchOp 54 commit sync.WaitGroup 55 commitErr error 56 applied uint32 57 indexValid bool 58 index int 59 } 60 61 var batchBitowerPool = sync.Pool{ 62 New: func() interface{} { 63 return &BatchBitower{} 64 }, 65 } 66 67 func newBatchBitower(db *DB) *BatchBitower { 68 b := batchBitowerPool.Get().(*BatchBitower) 69 b.db = db 70 return b 71 } 72 73 func newBatchBitowerByIndex(db *DB, index int) *BatchBitower { 74 b := newBatchBitower(db) 75 b.index = index 76 b.indexValid = true 77 return b 78 } 79 80 func (b *BatchBitower) release() { 81 if b.db == nil { 82 return 83 } 84 85 b.db = nil 86 b.Reset() 87 b.cmp = nil 88 batchBitowerPool.Put(b) 89 } 90 91 func (b *BatchBitower) refreshMemTableSize() { 92 b.memTableSize = 0 93 if len(b.data) < batchHeaderLen { 94 return 95 } 96 97 for r := b.Reader(); ; { 98 _, key, value, ok := r.Next() 99 if !ok { 100 break 101 } 102 b.memTableSize += memTableEntrySize(len(key), len(value)) 103 } 104 } 105 106 func (b *BatchBitower) prepareDeferredKeyValueRecord(keyLen, valueLen int, kind InternalKeyKind) { 107 if len(b.data) == 0 { 108 b.init(keyLen + valueLen + 2*binary.MaxVarintLen64 + batchHeaderLen) 109 } 110 b.count++ 111 b.memTableSize += memTableEntrySize(keyLen, valueLen) 112 113 pos := len(b.data) 114 b.deferredOp.offset = uint32(pos) 115 b.grow(1 + 2*maxVarintLen32 + keyLen + valueLen) 116 b.data[pos] = byte(kind) 117 pos++ 118 119 { 120 x := uint32(keyLen) 121 for x >= 0x80 { 122 b.data[pos] = byte(x) | 0x80 123 x >>= 7 124 pos++ 125 } 126 b.data[pos] = byte(x) 127 pos++ 128 } 129 130 b.deferredOp.Key = b.data[pos : pos+keyLen] 131 pos += keyLen 132 133 { 134 x := uint32(valueLen) 135 for x >= 0x80 { 136 b.data[pos] = byte(x) | 0x80 137 x >>= 7 138 pos++ 139 } 140 b.data[pos] = byte(x) 141 pos++ 142 } 143 144 b.deferredOp.Value = b.data[pos : pos+valueLen] 145 b.data = b.data[:pos+valueLen] 146 } 147 148 func (b *BatchBitower) prepareDeferredKeyRecord(keyLen int, kind InternalKeyKind) { 149 if len(b.data) == 0 { 150 b.init(keyLen + binary.MaxVarintLen64 + batchHeaderLen) 151 } 152 b.count++ 153 b.memTableSize += memTableEntrySize(keyLen, 0) 154 155 pos := len(b.data) 156 b.deferredOp.offset = uint32(pos) 157 b.grow(1 + maxVarintLen32 + keyLen) 158 b.data[pos] = byte(kind) 159 pos++ 160 161 { 162 x := uint32(keyLen) 163 for x >= 0x80 { 164 b.data[pos] = byte(x) | 0x80 165 x >>= 7 166 pos++ 167 } 168 b.data[pos] = byte(x) 169 pos++ 170 } 171 172 b.deferredOp.Key = b.data[pos : pos+keyLen] 173 b.deferredOp.Value = nil 174 175 b.data = b.data[:pos+keyLen] 176 } 177 178 func (b *BatchBitower) setBitowerIndexByKey(key []byte) { 179 if !b.indexValid && b.db != nil { 180 b.index = b.db.getBitowerIndexByKey(key) 181 b.indexValid = true 182 } 183 } 184 185 func (b *BatchBitower) setBitowerIndex(index int) { 186 b.index = index 187 } 188 189 func (b *BatchBitower) Set(key, value []byte, _ *WriteOptions) error { 190 b.setBitowerIndexByKey(key) 191 deferredOp := b.SetDeferred(len(key), len(value)) 192 copy(deferredOp.Key, key) 193 copy(deferredOp.Value, value) 194 return deferredOp.Finish() 195 } 196 197 func (b *BatchBitower) SetMultiValue(key []byte, values ...[]byte) error { 198 b.setBitowerIndexByKey(key) 199 var valueLen int 200 for i := range values { 201 valueLen += len(values[i]) 202 } 203 deferredOp := b.SetDeferred(len(key), valueLen) 204 copy(deferredOp.Key, key) 205 pos := 0 206 for j := range values { 207 pos += copy(deferredOp.Value[pos:], values[j]) 208 } 209 return deferredOp.Finish() 210 } 211 212 func (b *BatchBitower) SetDeferred(keyLen, valueLen int) *DeferredBatchOp { 213 b.prepareDeferredKeyValueRecord(keyLen, valueLen, InternalKeyKindSet) 214 return &b.deferredOp 215 } 216 217 func (b *BatchBitower) PrefixDeleteKeySet(key []byte, _ *WriteOptions) error { 218 b.setBitowerIndexByKey(key) 219 b.prepareDeferredKeyRecord(len(key), InternalKeyKindPrefixDelete) 220 copy(b.deferredOp.Key, key) 221 return b.deferredOp.Finish() 222 } 223 224 func (b *BatchBitower) Delete(key []byte, _ *WriteOptions) error { 225 b.setBitowerIndexByKey(key) 226 deferredOp := b.DeleteDeferred(len(key)) 227 copy(deferredOp.Key, key) 228 return deferredOp.Finish() 229 } 230 231 func (b *BatchBitower) DeleteDeferred(keyLen int) *DeferredBatchOp { 232 b.prepareDeferredKeyRecord(keyLen, InternalKeyKindDelete) 233 return &b.deferredOp 234 } 235 236 func (b *BatchBitower) LogData(data []byte, _ *WriteOptions) error { 237 origCount, origMemTableSize := b.count, b.memTableSize 238 b.prepareDeferredKeyRecord(len(data), InternalKeyKindLogData) 239 copy(b.deferredOp.Key, data) 240 b.count, b.memTableSize = origCount, origMemTableSize 241 return nil 242 } 243 244 func (b *BatchBitower) Empty() bool { 245 return len(b.data) <= batchHeaderLen 246 } 247 248 func (b *BatchBitower) Repr() []byte { 249 if len(b.data) == 0 { 250 b.init(batchHeaderLen) 251 } 252 binary.LittleEndian.PutUint32(b.countData(), b.Count()) 253 return b.data 254 } 255 256 func (b *BatchBitower) SetRepr(data []byte) error { 257 if len(data) < batchHeaderLen { 258 return ErrInvalidBatch 259 } 260 b.data = data 261 b.count = uint64(binary.LittleEndian.Uint32(b.countData())) 262 if b.db != nil { 263 b.refreshMemTableSize() 264 } 265 return nil 266 } 267 268 func (b *BatchBitower) Commit(o *WriteOptions) error { 269 if b.Empty() { 270 return nil 271 } 272 return b.db.ApplyBitower(b, o) 273 } 274 275 func (b *BatchBitower) Close() error { 276 b.release() 277 return nil 278 } 279 280 func (b *BatchBitower) init(cap int) { 281 n := batchInitialSize 282 for n < cap { 283 n *= 2 284 } 285 b.data = rawalloc.New(batchHeaderLen, n) 286 b.setCount(0) 287 b.setSeqNum(0) 288 b.data = b.data[:batchHeaderLen] 289 } 290 291 func (b *BatchBitower) Reset() { 292 b.indexValid = false 293 b.index = 0 294 b.count = 0 295 b.memTableSize = 0 296 b.deferredOp = DeferredBatchOp{} 297 b.commit = sync.WaitGroup{} 298 b.commitErr = nil 299 atomic.StoreUint32(&b.applied, 0) 300 if b.data != nil { 301 if cap(b.data) > batchMaxRetainedSize { 302 b.data = nil 303 } else { 304 b.data = b.data[:batchHeaderLen] 305 b.setSeqNum(0) 306 } 307 } 308 } 309 310 func (b *BatchBitower) seqNumData() []byte { 311 return b.data[:8] 312 } 313 314 func (b *BatchBitower) countData() []byte { 315 return b.data[8:12] 316 } 317 318 func (b *BatchBitower) grow(n int) { 319 newSize := len(b.data) + n 320 if newSize > cap(b.data) { 321 newCap := 2 * cap(b.data) 322 for newCap < newSize { 323 newCap *= 2 324 } 325 newData := rawalloc.New(len(b.data), newCap) 326 copy(newData, b.data) 327 b.data = newData 328 } 329 b.data = b.data[:newSize] 330 } 331 332 func (b *BatchBitower) setSeqNum(seqNum uint64) { 333 binary.LittleEndian.PutUint64(b.seqNumData(), seqNum) 334 } 335 336 func (b *BatchBitower) SeqNum() uint64 { 337 if len(b.data) == 0 { 338 b.init(batchHeaderLen) 339 } 340 return binary.LittleEndian.Uint64(b.seqNumData()) 341 } 342 343 func (b *BatchBitower) setCount(v uint32) { 344 b.count = uint64(v) 345 } 346 347 func (b *BatchBitower) Count() uint32 { 348 return uint32(b.count) 349 } 350 351 func (b *BatchBitower) Reader() BatchBitowerReader { 352 if len(b.data) == 0 { 353 b.init(batchHeaderLen) 354 } 355 return b.data[batchHeaderLen:] 356 } 357 358 func batchDecodeStr(data []byte) (odata []byte, s []byte, ok bool) { 359 var v uint32 360 var n int 361 ptr := unsafe.Pointer(&data[0]) 362 if a := *((*uint8)(ptr)); a < 128 { 363 v = uint32(a) 364 n = 1 365 } else if a, b := a&0x7f, *((*uint8)(unsafe.Pointer(uintptr(ptr) + 1))); b < 128 { 366 v = uint32(b)<<7 | uint32(a) 367 n = 2 368 } else if b, c := b&0x7f, *((*uint8)(unsafe.Pointer(uintptr(ptr) + 2))); c < 128 { 369 v = uint32(c)<<14 | uint32(b)<<7 | uint32(a) 370 n = 3 371 } else if c, d := c&0x7f, *((*uint8)(unsafe.Pointer(uintptr(ptr) + 3))); d < 128 { 372 v = uint32(d)<<21 | uint32(c)<<14 | uint32(b)<<7 | uint32(a) 373 n = 4 374 } else { 375 d, e := d&0x7f, *((*uint8)(unsafe.Pointer(uintptr(ptr) + 4))) 376 v = uint32(e)<<28 | uint32(d)<<21 | uint32(c)<<14 | uint32(b)<<7 | uint32(a) 377 n = 5 378 } 379 380 data = data[n:] 381 if v > uint32(len(data)) { 382 return nil, nil, false 383 } 384 return data[v:], data[:v], true 385 } 386 387 type BatchBitowerReader []byte 388 389 func ReadBatchBitower(repr []byte) (r BatchBitowerReader, count uint32) { 390 if len(repr) <= batchHeaderLen { 391 return nil, count 392 } 393 count = binary.LittleEndian.Uint32(repr[batchCountOffset:batchHeaderLen]) 394 return repr[batchHeaderLen:], count 395 } 396 397 func (r *BatchBitowerReader) Next() (kind InternalKeyKind, ukey []byte, value []byte, ok bool) { 398 if len(*r) == 0 { 399 return 0, nil, nil, false 400 } 401 kind = InternalKeyKind((*r)[0]) 402 if kind > InternalKeyKindMax { 403 return 0, nil, nil, false 404 } 405 *r, ukey, ok = batchDecodeStr((*r)[1:]) 406 if !ok { 407 return 0, nil, nil, false 408 } 409 switch kind { 410 case InternalKeyKindSet: 411 *r, value, ok = batchDecodeStr(*r) 412 if !ok { 413 return 0, nil, nil, false 414 } 415 } 416 return kind, ukey, value, true 417 }