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  }