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 }