github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/base/internal.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 base
    16  
    17  import (
    18  	"encoding/binary"
    19  	"fmt"
    20  
    21  	"github.com/zuoyebang/bitalosdb/internal/bytepools"
    22  )
    23  
    24  type InternalKeyKind uint8
    25  
    26  const (
    27  	InternalKeyKindDelete       InternalKeyKind = 0
    28  	InternalKeyKindSet          InternalKeyKind = 1
    29  	InternalKeyKindSetBithash   InternalKeyKind = 2
    30  	InternalKeyKindLogData      InternalKeyKind = 3
    31  	InternalKeyKindPrefixDelete InternalKeyKind = 4
    32  	InternalKeyKindMax          InternalKeyKind = 18
    33  	InternalKeyKindInvalid      InternalKeyKind = 255
    34  
    35  	InternalKeySeqNumBatch = uint64(1 << 55)
    36  	InternalKeySeqNumMax   = uint64(1<<56 - 1)
    37  )
    38  
    39  var internalKeyKindNames = []string{
    40  	InternalKeyKindDelete:       "DEL",
    41  	InternalKeyKindSet:          "SET",
    42  	InternalKeyKindSetBithash:   "SETBITHASH",
    43  	InternalKeyKindLogData:      "LOGDATA",
    44  	InternalKeyKindPrefixDelete: "PREFIXDELETE",
    45  	InternalKeyKindInvalid:      "INVALID",
    46  }
    47  
    48  func (k InternalKeyKind) String() string {
    49  	if int(k) < len(internalKeyKindNames) {
    50  		return internalKeyKindNames[k]
    51  	}
    52  	return fmt.Sprintf("UNKNOWN:%d", k)
    53  }
    54  
    55  type InternalKey struct {
    56  	UserKey []byte
    57  	Trailer uint64
    58  }
    59  
    60  func MakeInternalKey(userKey []byte, seqNum uint64, kind InternalKeyKind) InternalKey {
    61  	return InternalKey{
    62  		UserKey: userKey,
    63  		Trailer: (seqNum << 8) | uint64(kind),
    64  	}
    65  }
    66  
    67  func MakeInternalKey2(userKey []byte, trailer uint64) InternalKey {
    68  	return InternalKey{
    69  		UserKey: userKey,
    70  		Trailer: trailer,
    71  	}
    72  }
    73  
    74  func MakeInternalSetKey(userKey []byte) InternalKey {
    75  	return MakeInternalKey(userKey, 1, InternalKeyKindSet)
    76  }
    77  
    78  func MakeSearchKey(userKey []byte) InternalKey {
    79  	return InternalKey{
    80  		UserKey: userKey,
    81  		Trailer: (InternalKeySeqNumMax << 8) | uint64(InternalKeyKindMax),
    82  	}
    83  }
    84  
    85  func DecodeInternalKey(encodedKey []byte) InternalKey {
    86  	n := len(encodedKey) - 8
    87  	var trailer uint64
    88  	if n >= 0 {
    89  		trailer = binary.LittleEndian.Uint64(encodedKey[n:])
    90  		encodedKey = encodedKey[:n:n]
    91  	} else {
    92  		trailer = uint64(InternalKeyKindInvalid)
    93  		encodedKey = nil
    94  	}
    95  	return InternalKey{
    96  		UserKey: encodedKey,
    97  		Trailer: trailer,
    98  	}
    99  }
   100  
   101  func InternalCompare(userCmp Compare, a, b InternalKey) int {
   102  	if x := userCmp(a.UserKey, b.UserKey); x != 0 {
   103  		return x
   104  	}
   105  	if a.Trailer > b.Trailer {
   106  		return -1
   107  	}
   108  	if a.Trailer < b.Trailer {
   109  		return 1
   110  	}
   111  	return 0
   112  }
   113  
   114  func (k InternalKey) Encode(buf []byte) {
   115  	i := copy(buf, k.UserKey)
   116  	binary.LittleEndian.PutUint64(buf[i:], k.Trailer)
   117  }
   118  
   119  func (k InternalKey) EncodeTrailer() [8]byte {
   120  	var buf [8]byte
   121  	binary.LittleEndian.PutUint64(buf[:], k.Trailer)
   122  	return buf
   123  }
   124  
   125  func (k InternalKey) Size() int {
   126  	return len(k.UserKey) + 8
   127  }
   128  
   129  func (k *InternalKey) SetSeqNum(seqNum uint64) {
   130  	k.Trailer = (seqNum << 8) | (k.Trailer & 0xff)
   131  }
   132  
   133  func (k InternalKey) SeqNum() uint64 {
   134  	return k.Trailer >> 8
   135  }
   136  
   137  func (k InternalKey) Visible(snapshot uint64) bool {
   138  	seqNum := k.SeqNum()
   139  	return seqNum <= snapshot || (seqNum&InternalKeySeqNumBatch) != 0
   140  }
   141  
   142  func (k *InternalKey) SetKind(kind InternalKeyKind) {
   143  	k.Trailer = (k.Trailer &^ 0xff) | uint64(kind)
   144  }
   145  
   146  func (k InternalKey) Kind() InternalKeyKind {
   147  	return InternalKeyKind(k.Trailer & 0xff)
   148  }
   149  
   150  func (k InternalKey) Valid() bool {
   151  	return k.Kind() <= InternalKeyKindMax
   152  }
   153  
   154  func (k InternalKey) Clone() InternalKey {
   155  	if len(k.UserKey) == 0 {
   156  		return k
   157  	}
   158  	return InternalKey{
   159  		UserKey: append([]byte(nil), k.UserKey...),
   160  		Trailer: k.Trailer,
   161  	}
   162  }
   163  
   164  func (k InternalKey) String() string {
   165  	return fmt.Sprintf("%s#%d,%d", FormatBytes(k.UserKey), k.SeqNum(), k.Kind())
   166  }
   167  
   168  func (k InternalKey) Pretty(f FormatKey) fmt.Formatter {
   169  	return prettyInternalKey{k, f}
   170  }
   171  
   172  type prettyInternalKey struct {
   173  	InternalKey
   174  	formatKey FormatKey
   175  }
   176  
   177  func (k prettyInternalKey) Format(s fmt.State, c rune) {
   178  	fmt.Fprintf(s, "%s#%d,%s", k.formatKey(k.UserKey), k.SeqNum(), k.Kind())
   179  }
   180  
   181  type InternalValue struct {
   182  	Header    uint64
   183  	UserValue []byte
   184  }
   185  
   186  func (v InternalValue) Kind() InternalKeyKind {
   187  	return InternalKeyKind(v.Header & 0xff)
   188  }
   189  
   190  func (v *InternalValue) SetSeqNum(seqNum uint64) {
   191  	v.Header = (seqNum << 8) | (v.Header & 0xff)
   192  }
   193  
   194  func (v *InternalValue) SetKind(kind InternalKeyKind) {
   195  	v.Header = (v.Header &^ 0xff) | uint64(kind)
   196  }
   197  
   198  func (v InternalValue) SeqNum() uint64 {
   199  	return v.Header >> 8
   200  }
   201  
   202  func MakeInternalValue(value []byte, seqNum uint64, kind InternalKeyKind) InternalValue {
   203  	return InternalValue{
   204  		Header:    (seqNum << 8) | uint64(kind),
   205  		UserValue: value,
   206  	}
   207  }
   208  
   209  func EncodeInternalValue(value []byte, seqNum uint64, kind InternalKeyKind) ([]byte, func()) {
   210  	vLen := len(value) + 8
   211  	pool, closer := bytepools.ReaderBytePools.GetBytePool(vLen)
   212  	binary.LittleEndian.PutUint64(pool[0:8], (seqNum<<8)|uint64(kind))
   213  	if value != nil {
   214  		copy(pool[8:], value)
   215  	}
   216  	return pool[:vLen], closer
   217  }
   218  
   219  func DecodeInternalValue(encodedValue []byte) InternalValue {
   220  	n := len(encodedValue) - 8
   221  	var header uint64
   222  	if n >= 0 {
   223  		header = binary.LittleEndian.Uint64(encodedValue[0:8])
   224  		if n == 0 {
   225  			encodedValue = encodedValue[:0:0]
   226  		} else {
   227  			encodedValue = encodedValue[8 : n+8 : n+8]
   228  		}
   229  	} else {
   230  		header = uint64(InternalKeyKindInvalid)
   231  		encodedValue = nil
   232  	}
   233  
   234  	return InternalValue{
   235  		Header:    header,
   236  		UserValue: encodedValue,
   237  	}
   238  }
   239  
   240  func CheckValueValidByKeySetBithash(v []byte) bool {
   241  	length := len(v)
   242  	return length == 4 || length == 12
   243  }