github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/base/internal.go (about)

     1  // Copyright 2011 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  package base // import "github.com/zuoyebang/bitalostable/internal/base"
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  // InternalKeyKind enumerates the kind of key: a deletion tombstone, a set
    15  // value, a merged value, etc.
    16  type InternalKeyKind uint8
    17  
    18  // These constants are part of the file format, and should not be changed.
    19  const (
    20  	InternalKeyKindDelete  InternalKeyKind = 0
    21  	InternalKeyKindSet     InternalKeyKind = 1
    22  	InternalKeyKindMerge   InternalKeyKind = 2
    23  	InternalKeyKindLogData InternalKeyKind = 3
    24  	//InternalKeyKindColumnFamilyDeletion     InternalKeyKind = 4
    25  	//InternalKeyKindColumnFamilyValue        InternalKeyKind = 5
    26  	//InternalKeyKindColumnFamilyMerge        InternalKeyKind = 6
    27  	InternalKeyKindSingleDelete InternalKeyKind = 7
    28  	//InternalKeyKindColumnFamilySingleDelete InternalKeyKind = 8
    29  	//InternalKeyKindBeginPrepareXID          InternalKeyKind = 9
    30  	//InternalKeyKindEndPrepareXID            InternalKeyKind = 10
    31  	//InternalKeyKindCommitXID                InternalKeyKind = 11
    32  	//InternalKeyKindRollbackXID              InternalKeyKind = 12
    33  	//InternalKeyKindNoop                     InternalKeyKind = 13
    34  	//InternalKeyKindColumnFamilyRangeDelete  InternalKeyKind = 14
    35  	InternalKeyKindRangeDelete InternalKeyKind = 15
    36  	//InternalKeyKindColumnFamilyBlobIndex    InternalKeyKind = 16
    37  	//InternalKeyKindBlobIndex                InternalKeyKind = 17
    38  
    39  	// InternalKeyKindSeparator is a key used for separator / successor keys
    40  	// written to sstable block indexes.
    41  	//
    42  	// NOTE: the RocksDB value has been repurposed. This was done to ensure that
    43  	// keys written to block indexes with value "17" (when 17 happened to be the
    44  	// max value, and InternalKeyKindMax was therefore set to 17), remain stable
    45  	// when new key kinds are supported in Pebble.
    46  	InternalKeyKindSeparator InternalKeyKind = 17
    47  
    48  	// InternalKeyKindSetWithDelete keys are SET keys that have met with a
    49  	// DELETE or SINGLEDEL key in a prior compaction. This key kind is
    50  	// specific to Pebble. See
    51  	// https://github.com/zuoyebang/bitalostable/issues/1255.
    52  	InternalKeyKindSetWithDelete InternalKeyKind = 18
    53  
    54  	// InternalKeyKindRangeKeyDelete removes all range keys within a key range.
    55  	// See the internal/rangekey package for more details.
    56  	InternalKeyKindRangeKeyDelete InternalKeyKind = 19
    57  	// InternalKeyKindRangeKeySet and InternalKeyKindRangeUnset represent
    58  	// keys that set and unset values associated with ranges of key
    59  	// space. See the internal/rangekey package for more details.
    60  	InternalKeyKindRangeKeyUnset InternalKeyKind = 20
    61  	InternalKeyKindRangeKeySet   InternalKeyKind = 21
    62  
    63  	// This maximum value isn't part of the file format. It's unlikely,
    64  	// but future extensions may increase this value.
    65  	//
    66  	// When constructing an internal key to pass to DB.Seek{GE,LE},
    67  	// internalKeyComparer sorts decreasing by kind (after sorting increasing by
    68  	// user key and decreasing by sequence number). Thus, use InternalKeyKindMax,
    69  	// which sorts 'less than or equal to' any other valid internalKeyKind, when
    70  	// searching for any kind of internal key formed by a certain user key and
    71  	// seqNum.
    72  	InternalKeyKindMax InternalKeyKind = 21
    73  
    74  	// InternalKeyZeroSeqnumMaxTrailer is the largest trailer with a
    75  	// zero sequence number.
    76  	InternalKeyZeroSeqnumMaxTrailer = uint64(InternalKeyKindInvalid)
    77  
    78  	// A marker for an invalid key.
    79  	InternalKeyKindInvalid InternalKeyKind = 255
    80  
    81  	// InternalKeySeqNumBatch is a bit that is set on batch sequence numbers
    82  	// which prevents those entries from being excluded from iteration.
    83  	InternalKeySeqNumBatch = uint64(1 << 55)
    84  
    85  	// InternalKeySeqNumMax is the largest valid sequence number.
    86  	InternalKeySeqNumMax = uint64(1<<56 - 1)
    87  
    88  	// InternalKeyRangeDeleteSentinel is the marker for a range delete sentinel
    89  	// key. This sequence number and kind are used for the upper stable boundary
    90  	// when a range deletion tombstone is the largest key in an sstable. This is
    91  	// necessary because sstable boundaries are inclusive, while the end key of a
    92  	// range deletion tombstone is exclusive.
    93  	InternalKeyRangeDeleteSentinel = (InternalKeySeqNumMax << 8) | uint64(InternalKeyKindRangeDelete)
    94  
    95  	// InternalKeyBoundaryRangeKey is the marker for a range key boundary. This
    96  	// sequence number and kind are used during interleaved range key and point
    97  	// iteration to allow an iterator to stop at range key start keys where
    98  	// there exists no point key.
    99  	InternalKeyBoundaryRangeKey = (InternalKeySeqNumMax << 8) | uint64(InternalKeyKindRangeKeySet)
   100  )
   101  
   102  var internalKeyKindNames = []string{
   103  	InternalKeyKindDelete:         "DEL",
   104  	InternalKeyKindSet:            "SET",
   105  	InternalKeyKindMerge:          "MERGE",
   106  	InternalKeyKindLogData:        "LOGDATA",
   107  	InternalKeyKindSingleDelete:   "SINGLEDEL",
   108  	InternalKeyKindRangeDelete:    "RANGEDEL",
   109  	InternalKeyKindSeparator:      "SEPARATOR",
   110  	InternalKeyKindSetWithDelete:  "SETWITHDEL",
   111  	InternalKeyKindRangeKeySet:    "RANGEKEYSET",
   112  	InternalKeyKindRangeKeyUnset:  "RANGEKEYUNSET",
   113  	InternalKeyKindRangeKeyDelete: "RANGEKEYDEL",
   114  	InternalKeyKindInvalid:        "INVALID",
   115  }
   116  
   117  func (k InternalKeyKind) String() string {
   118  	if int(k) < len(internalKeyKindNames) {
   119  		return internalKeyKindNames[k]
   120  	}
   121  	return fmt.Sprintf("UNKNOWN:%d", k)
   122  }
   123  
   124  // InternalKey is a key used for the in-memory and on-disk partial DBs that
   125  // make up a bitalostable DB.
   126  //
   127  // It consists of the user key (as given by the code that uses package bitalostable)
   128  // followed by 8-bytes of metadata:
   129  //   - 1 byte for the type of internal key: delete or set,
   130  //   - 7 bytes for a uint56 sequence number, in little-endian format.
   131  type InternalKey struct {
   132  	UserKey []byte
   133  	Trailer uint64
   134  }
   135  
   136  // InvalidInternalKey is an invalid internal key for which Valid() will return
   137  // false.
   138  var InvalidInternalKey = MakeInternalKey(nil, 0, InternalKeyKindInvalid)
   139  
   140  // MakeInternalKey constructs an internal key from a specified user key,
   141  // sequence number and kind.
   142  func MakeInternalKey(userKey []byte, seqNum uint64, kind InternalKeyKind) InternalKey {
   143  	return InternalKey{
   144  		UserKey: userKey,
   145  		Trailer: (seqNum << 8) | uint64(kind),
   146  	}
   147  }
   148  
   149  // MakeTrailer constructs an internal key trailer from the specified sequence
   150  // number and kind.
   151  func MakeTrailer(seqNum uint64, kind InternalKeyKind) uint64 {
   152  	return (seqNum << 8) | uint64(kind)
   153  }
   154  
   155  // MakeSearchKey constructs an internal key that is appropriate for searching
   156  // for a the specified user key. The search key contain the maximal sequence
   157  // number and kind ensuring that it sorts before any other internal keys for
   158  // the same user key.
   159  func MakeSearchKey(userKey []byte) InternalKey {
   160  	return InternalKey{
   161  		UserKey: userKey,
   162  		Trailer: (InternalKeySeqNumMax << 8) | uint64(InternalKeyKindMax),
   163  	}
   164  }
   165  
   166  // MakeRangeDeleteSentinelKey constructs an internal key that is a range
   167  // deletion sentinel key, used as the upper boundary for an sstable when a
   168  // range deletion is the largest key in an sstable.
   169  func MakeRangeDeleteSentinelKey(userKey []byte) InternalKey {
   170  	return InternalKey{
   171  		UserKey: userKey,
   172  		Trailer: InternalKeyRangeDeleteSentinel,
   173  	}
   174  }
   175  
   176  // MakeExclusiveSentinelKey constructs an internal key that is an
   177  // exclusive sentinel key, used as the upper boundary for an sstable
   178  // when a ranged key is the largest key in an sstable.
   179  func MakeExclusiveSentinelKey(kind InternalKeyKind, userKey []byte) InternalKey {
   180  	return InternalKey{
   181  		UserKey: userKey,
   182  		Trailer: (InternalKeySeqNumMax << 8) | uint64(kind),
   183  	}
   184  }
   185  
   186  var kindsMap = map[string]InternalKeyKind{
   187  	"DEL":           InternalKeyKindDelete,
   188  	"SINGLEDEL":     InternalKeyKindSingleDelete,
   189  	"RANGEDEL":      InternalKeyKindRangeDelete,
   190  	"SET":           InternalKeyKindSet,
   191  	"MERGE":         InternalKeyKindMerge,
   192  	"INVALID":       InternalKeyKindInvalid,
   193  	"SEPARATOR":     InternalKeyKindSeparator,
   194  	"SETWITHDEL":    InternalKeyKindSetWithDelete,
   195  	"RANGEKEYSET":   InternalKeyKindRangeKeySet,
   196  	"RANGEKEYUNSET": InternalKeyKindRangeKeyUnset,
   197  	"RANGEKEYDEL":   InternalKeyKindRangeKeyDelete,
   198  }
   199  
   200  // ParseInternalKey parses the string representation of an internal key. The
   201  // format is <user-key>.<kind>.<seq-num>. If the seq-num starts with a "b" it
   202  // is marked as a batch-seq-num (i.e. the InternalKeySeqNumBatch bit is set).
   203  func ParseInternalKey(s string) InternalKey {
   204  	x := strings.Split(s, ".")
   205  	ukey := x[0]
   206  	kind, ok := kindsMap[x[1]]
   207  	if !ok {
   208  		panic(fmt.Sprintf("unknown kind: %q", x[1]))
   209  	}
   210  	j := 0
   211  	if x[2][0] == 'b' {
   212  		j = 1
   213  	}
   214  	seqNum, _ := strconv.ParseUint(x[2][j:], 10, 64)
   215  	if x[2][0] == 'b' {
   216  		seqNum |= InternalKeySeqNumBatch
   217  	}
   218  	return MakeInternalKey([]byte(ukey), seqNum, kind)
   219  }
   220  
   221  // ParseKind parses the string representation of an internal key kind.
   222  func ParseKind(s string) InternalKeyKind {
   223  	kind, ok := kindsMap[s]
   224  	if !ok {
   225  		panic(fmt.Sprintf("unknown kind: %q", s))
   226  	}
   227  	return kind
   228  }
   229  
   230  // InternalTrailerLen is the number of bytes used to encode InternalKey.Trailer.
   231  const InternalTrailerLen = 8
   232  
   233  // DecodeInternalKey decodes an encoded internal key. See InternalKey.Encode().
   234  func DecodeInternalKey(encodedKey []byte) InternalKey {
   235  	n := len(encodedKey) - InternalTrailerLen
   236  	var trailer uint64
   237  	if n >= 0 {
   238  		trailer = binary.LittleEndian.Uint64(encodedKey[n:])
   239  		encodedKey = encodedKey[:n:n]
   240  	} else {
   241  		trailer = uint64(InternalKeyKindInvalid)
   242  		encodedKey = nil
   243  	}
   244  	return InternalKey{
   245  		UserKey: encodedKey,
   246  		Trailer: trailer,
   247  	}
   248  }
   249  
   250  // InternalCompare compares two internal keys using the specified comparison
   251  // function. For equal user keys, internal keys compare in descending sequence
   252  // number order. For equal user keys and sequence numbers, internal keys
   253  // compare in descending kind order (this may happen in practice among range
   254  // keys).
   255  func InternalCompare(userCmp Compare, a, b InternalKey) int {
   256  	if x := userCmp(a.UserKey, b.UserKey); x != 0 {
   257  		return x
   258  	}
   259  	if a.Trailer > b.Trailer {
   260  		return -1
   261  	}
   262  	if a.Trailer < b.Trailer {
   263  		return 1
   264  	}
   265  	return 0
   266  }
   267  
   268  // Encode encodes the receiver into the buffer. The buffer must be large enough
   269  // to hold the encoded data. See InternalKey.Size().
   270  func (k InternalKey) Encode(buf []byte) {
   271  	i := copy(buf, k.UserKey)
   272  	binary.LittleEndian.PutUint64(buf[i:], k.Trailer)
   273  }
   274  
   275  // EncodeTrailer returns the trailer encoded to an 8-byte array.
   276  func (k InternalKey) EncodeTrailer() [8]byte {
   277  	var buf [8]byte
   278  	binary.LittleEndian.PutUint64(buf[:], k.Trailer)
   279  	return buf
   280  }
   281  
   282  // Separator returns a separator key such that k <= x && x < other, where less
   283  // than is consistent with the Compare function. The buf parameter may be used
   284  // to store the returned InternalKey.UserKey, though it is valid to pass a
   285  // nil. See the Separator type for details on separator keys.
   286  func (k InternalKey) Separator(
   287  	cmp Compare, sep Separator, buf []byte, other InternalKey,
   288  ) InternalKey {
   289  	buf = sep(buf, k.UserKey, other.UserKey)
   290  	if len(buf) <= len(k.UserKey) && cmp(k.UserKey, buf) < 0 {
   291  		// The separator user key is physically shorter than k.UserKey (if it is
   292  		// longer, we'll continue to use "k"), but logically after. Tack on the max
   293  		// sequence number to the shortened user key. Note that we could tack on
   294  		// any sequence number and kind here to create a valid separator key. We
   295  		// use the max sequence number to match the behavior of LevelDB and
   296  		// RocksDB.
   297  		return MakeInternalKey(buf, InternalKeySeqNumMax, InternalKeyKindSeparator)
   298  	}
   299  	return k
   300  }
   301  
   302  // Successor returns a successor key such that k <= x. A simple implementation
   303  // may return k unchanged. The buf parameter may be used to store the returned
   304  // InternalKey.UserKey, though it is valid to pass a nil.
   305  func (k InternalKey) Successor(cmp Compare, succ Successor, buf []byte) InternalKey {
   306  	buf = succ(buf, k.UserKey)
   307  	if len(buf) <= len(k.UserKey) && cmp(k.UserKey, buf) < 0 {
   308  		// The successor user key is physically shorter that k.UserKey (if it is
   309  		// longer, we'll continue to use "k"), but logically after. Tack on the max
   310  		// sequence number to the shortened user key. Note that we could tack on
   311  		// any sequence number and kind here to create a valid separator key. We
   312  		// use the max sequence number to match the behavior of LevelDB and
   313  		// RocksDB.
   314  		return MakeInternalKey(buf, InternalKeySeqNumMax, InternalKeyKindSeparator)
   315  	}
   316  	return k
   317  }
   318  
   319  // Size returns the encoded size of the key.
   320  func (k InternalKey) Size() int {
   321  	return len(k.UserKey) + 8
   322  }
   323  
   324  // SetSeqNum sets the sequence number component of the key.
   325  func (k *InternalKey) SetSeqNum(seqNum uint64) {
   326  	k.Trailer = (seqNum << 8) | (k.Trailer & 0xff)
   327  }
   328  
   329  // SeqNum returns the sequence number component of the key.
   330  func (k InternalKey) SeqNum() uint64 {
   331  	return k.Trailer >> 8
   332  }
   333  
   334  // Visible returns true if the key is visible at the specified snapshot
   335  // sequence number.
   336  func (k InternalKey) Visible(snapshot uint64) bool {
   337  	return Visible(k.SeqNum(), snapshot)
   338  }
   339  
   340  // Visible returns true if a key with the provided sequence number is visible at
   341  // the specified snapshot sequence number.
   342  func Visible(seqNum uint64, snapshot uint64) bool {
   343  	return seqNum < snapshot || (seqNum&InternalKeySeqNumBatch) != 0
   344  }
   345  
   346  func (k InternalKey) Visible1(snapshot uint64) bool {
   347  	return Visible1(k.SeqNum(), snapshot)
   348  }
   349  
   350  func Visible1(seqNum uint64, snapshot uint64) bool {
   351  	return seqNum <= snapshot || (seqNum&InternalKeySeqNumBatch) != 0
   352  }
   353  
   354  // SetKind sets the kind component of the key.
   355  func (k *InternalKey) SetKind(kind InternalKeyKind) {
   356  	k.Trailer = (k.Trailer &^ 0xff) | uint64(kind)
   357  }
   358  
   359  // Kind returns the kind compoment of the key.
   360  func (k InternalKey) Kind() InternalKeyKind {
   361  	return InternalKeyKind(k.Trailer & 0xff)
   362  }
   363  
   364  // Valid returns true if the key has a valid kind.
   365  func (k InternalKey) Valid() bool {
   366  	return k.Kind() <= InternalKeyKindMax
   367  }
   368  
   369  // Clone clones the storage for the UserKey component of the key.
   370  func (k InternalKey) Clone() InternalKey {
   371  	if len(k.UserKey) == 0 {
   372  		return k
   373  	}
   374  	return InternalKey{
   375  		UserKey: append([]byte(nil), k.UserKey...),
   376  		Trailer: k.Trailer,
   377  	}
   378  }
   379  
   380  // String returns a string representation of the key.
   381  func (k InternalKey) String() string {
   382  	return fmt.Sprintf("%s#%d,%d", FormatBytes(k.UserKey), k.SeqNum(), k.Kind())
   383  }
   384  
   385  // Pretty returns a formatter for the key.
   386  func (k InternalKey) Pretty(f FormatKey) fmt.Formatter {
   387  	return prettyInternalKey{k, f}
   388  }
   389  
   390  // IsExclusiveSentinel returns whether this internal key excludes point keys
   391  // with the same user key if used as an end boundary. See the comment on
   392  // InternalKeyRangeDeletionSentinel.
   393  func (k InternalKey) IsExclusiveSentinel() bool {
   394  	switch kind := k.Kind(); kind {
   395  	case InternalKeyKindRangeDelete:
   396  		return k.Trailer == InternalKeyRangeDeleteSentinel
   397  	case InternalKeyKindRangeKeyDelete, InternalKeyKindRangeKeyUnset, InternalKeyKindRangeKeySet:
   398  		return (k.Trailer >> 8) == InternalKeySeqNumMax
   399  	default:
   400  		return false
   401  	}
   402  }
   403  
   404  type prettyInternalKey struct {
   405  	InternalKey
   406  	formatKey FormatKey
   407  }
   408  
   409  func (k prettyInternalKey) Format(s fmt.State, c rune) {
   410  	fmt.Fprintf(s, "%s#%d,%s", k.formatKey(k.UserKey), k.SeqNum(), k.Kind())
   411  }
   412  
   413  // ParsePrettyInternalKey parses the pretty string representation of an
   414  // internal key. The format is <user-key>#<seq-num>,<kind>.
   415  func ParsePrettyInternalKey(s string) InternalKey {
   416  	x := strings.FieldsFunc(s, func(c rune) bool { return c == '#' || c == ',' })
   417  	ukey := x[0]
   418  	kind, ok := kindsMap[x[2]]
   419  	if !ok {
   420  		panic(fmt.Sprintf("unknown kind: %q", x[2]))
   421  	}
   422  	seqNum, _ := strconv.ParseUint(x[1], 10, 64)
   423  	return MakeInternalKey([]byte(ukey), seqNum, kind)
   424  }