github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/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/petermattis/pebble/internal/base" 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "fmt" 11 "strconv" 12 "strings" 13 ) 14 15 // InternalKeyKind enumerates the kind of key: a deletion tombstone, a set 16 // value, a merged value, etc. 17 type InternalKeyKind uint8 18 19 // These constants are part of the file format, and should not be changed. 20 const ( 21 InternalKeyKindDelete InternalKeyKind = 0 22 InternalKeyKindSet = 1 23 InternalKeyKindMerge = 2 24 InternalKeyKindLogData = 3 25 // InternalKeyKindColumnFamilyDeletion = 4 26 // InternalKeyKindColumnFamilyValue = 5 27 // InternalKeyKindColumnFamilyMerge = 6 28 // InternalKeyKindSingleDelete = 7 29 // InternalKeyKindColumnFamilySingleDelete = 8 30 // InternalKeyKindBeginPrepareXID = 9 31 // InternalKeyKindEndPrepareXID = 10 32 // InternalKeyKindCommitXID = 11 33 // InternalKeyKindRollbackXID = 12 34 // InternalKeyKindNoop = 13 35 // InternalKeyKindColumnFamilyRangeDelete = 14 36 InternalKeyKindRangeDelete = 15 37 // InternalKeyKindColumnFamilyBlobIndex = 16 38 // InternalKeyKindBlobIndex = 17 39 40 // This maximum value isn't part of the file format. It's unlikely, 41 // but future extensions may increase this value. 42 // 43 // When constructing an internal key to pass to DB.Seek{GE,LE}, 44 // internalKeyComparer sorts decreasing by kind (after sorting increasing by 45 // user key and decreasing by sequence number). Thus, use InternalKeyKindMax, 46 // which sorts 'less than or equal to' any other valid internalKeyKind, when 47 // searching for any kind of internal key formed by a certain user key and 48 // seqNum. 49 InternalKeyKindMax InternalKeyKind = 17 50 51 // A marker for an invalid key. 52 InternalKeyKindInvalid InternalKeyKind = 255 53 54 // InternalKeySeqNumBatch is a bit that is set on batch sequence numbers 55 // which prevents those entries from being excluded from iteration. 56 InternalKeySeqNumBatch = uint64(1 << 55) 57 58 // InternalKeySeqNumMax is the largest valid sequence number. 59 InternalKeySeqNumMax = uint64(1<<56 - 1) 60 61 // InternalKeyRangeDeleteSentinel is the marker for a range delete sentinel 62 // key. This sequence number and kind are used for the upper stable boundary 63 // when a range deletion tombstone is the largest key in an sstable. This is 64 // necessary because sstable boundaries are inclusive, while the end key of a 65 // range deletion tombstone is exclusive. 66 InternalKeyRangeDeleteSentinel = (InternalKeySeqNumMax << 8) | InternalKeyKindRangeDelete 67 ) 68 69 var internalKeyKindNames = []string{ 70 InternalKeyKindDelete: "DEL", 71 InternalKeyKindSet: "SET", 72 InternalKeyKindMerge: "MERGE", 73 InternalKeyKindLogData: "LOGDATA", 74 InternalKeyKindRangeDelete: "RANGEDEL", 75 InternalKeyKindMax: "MAX", 76 InternalKeyKindInvalid: "INVALID", 77 } 78 79 func (k InternalKeyKind) String() string { 80 if int(k) < len(internalKeyKindNames) { 81 return internalKeyKindNames[k] 82 } 83 return fmt.Sprintf("UNKNOWN:%d", k) 84 } 85 86 // InternalKey is a key used for the in-memory and on-disk partial DBs that 87 // make up a pebble DB. 88 // 89 // It consists of the user key (as given by the code that uses package pebble) 90 // followed by 8-bytes of metadata: 91 // - 1 byte for the type of internal key: delete or set, 92 // - 7 bytes for a uint56 sequence number, in little-endian format. 93 type InternalKey struct { 94 UserKey []byte 95 Trailer uint64 96 } 97 98 // InvalidInternalKey is an invalid internal key for which Valid() will return 99 // false. 100 var InvalidInternalKey = MakeInternalKey(nil, 0, InternalKeyKindInvalid) 101 102 // MakeInternalKey constructs an internal key from a specified user key, 103 // sequence number and kind. 104 func MakeInternalKey(userKey []byte, seqNum uint64, kind InternalKeyKind) InternalKey { 105 return InternalKey{ 106 UserKey: userKey, 107 Trailer: (seqNum << 8) | uint64(kind), 108 } 109 } 110 111 // MakeSearchKey constructs an internal key that is appropriate for searching 112 // for a the specified user key. The search key contain the maximual sequence 113 // number and kind ensuring that it sorts before any other internal keys for 114 // the same user key. 115 func MakeSearchKey(userKey []byte) InternalKey { 116 return InternalKey{ 117 UserKey: userKey, 118 Trailer: (InternalKeySeqNumMax << 8) | uint64(InternalKeyKindMax), 119 } 120 } 121 122 // MakeRangeDeleteSentinelKey constructs an internal key that is a range 123 // deletion sentinel key, used as the upper boundary for an sstable when a 124 // range deletion is the largest key in an sstable. 125 func MakeRangeDeleteSentinelKey(userKey []byte) InternalKey { 126 return InternalKey{ 127 UserKey: userKey, 128 Trailer: InternalKeyRangeDeleteSentinel, 129 } 130 } 131 132 var kindsMap = map[string]InternalKeyKind{ 133 "DEL": InternalKeyKindDelete, 134 "RANGEDEL": InternalKeyKindRangeDelete, 135 "SET": InternalKeyKindSet, 136 "MERGE": InternalKeyKindMerge, 137 "INVALID": InternalKeyKindInvalid, 138 "MAX": InternalKeyKindMax, 139 } 140 141 // ParseInternalKey parses the string representation of an internal key. The 142 // format is <user-key>.<kind>.<seq-num>. If the seq-num starts with a "b" it 143 // is marked as a batch-seq-num (i.e. the InternalKeySeqNumBatch bit is set). 144 func ParseInternalKey(s string) InternalKey { 145 x := strings.Split(s, ".") 146 ukey := x[0] 147 kind := kindsMap[x[1]] 148 j := 0 149 if x[2][0] == 'b' { 150 j = 1 151 } 152 seqNum, _ := strconv.ParseUint(x[2][j:], 10, 64) 153 if x[2][0] == 'b' { 154 seqNum |= InternalKeySeqNumBatch 155 } 156 return MakeInternalKey([]byte(ukey), seqNum, kind) 157 } 158 159 // DecodeInternalKey decodes an encoded internal key. See InternalKey.Encode(). 160 func DecodeInternalKey(encodedKey []byte) InternalKey { 161 n := len(encodedKey) - 8 162 var trailer uint64 163 if n >= 0 { 164 trailer = binary.LittleEndian.Uint64(encodedKey[n:]) 165 encodedKey = encodedKey[:n:n] 166 } else { 167 trailer = uint64(InternalKeyKindInvalid) 168 } 169 return InternalKey{ 170 UserKey: encodedKey, 171 Trailer: trailer, 172 } 173 } 174 175 // InternalCompare compares two internal keys using the specified comparison 176 // function. For equal user keys, internal keys compare in descending sequence 177 // number order. For equal user keys and sequence numbers, internal keys 178 // compare in descending kind order (though this should never happen in 179 // practice). 180 func InternalCompare(userCmp Compare, a, b InternalKey) int { 181 if !a.Valid() { 182 if b.Valid() { 183 return -1 184 } 185 return bytes.Compare(a.UserKey, b.UserKey) 186 } 187 if !b.Valid() { 188 return 1 189 } 190 if x := userCmp(a.UserKey, b.UserKey); x != 0 { 191 return x 192 } 193 if a.Trailer < b.Trailer { 194 return 1 195 } 196 if a.Trailer > b.Trailer { 197 return -1 198 } 199 return 0 200 } 201 202 // Encode encodes the receiver into the buffer. The buffer must be large enough 203 // to hold the encoded data. See InternalKey.Size(). 204 func (k InternalKey) Encode(buf []byte) { 205 i := copy(buf, k.UserKey) 206 binary.LittleEndian.PutUint64(buf[i:], k.Trailer) 207 } 208 209 // EncodeTrailer returns the trailer encoded to an 8-byte array. 210 func (k InternalKey) EncodeTrailer() [8]byte { 211 var buf [8]byte 212 binary.LittleEndian.PutUint64(buf[:], k.Trailer) 213 return buf 214 } 215 216 // Separator returns a separator key such that k <= x && x < other, where less 217 // than is consistent with the Compare function. The buf parameter may be used 218 // to store the returned InternalKey.UserKey, though it is valid to pass a 219 // nil. See the Separator type for details on separator keys. 220 func (k InternalKey) Separator( 221 cmp Compare, sep Separator, buf []byte, other InternalKey, 222 ) InternalKey { 223 buf = sep(buf, k.UserKey, other.UserKey) 224 if len(buf) <= len(k.UserKey) && cmp(k.UserKey, buf) < 0 { 225 // The separator user key is physically shorter than k.UserKey (if it is 226 // longer, we'll continue to use "k"), but logically after. Tack on the max 227 // sequence number to the shortened user key. Note that we could tack on 228 // any sequence number and kind here to create a valid separator key. We 229 // use the max sequence number to match the behavior of LevelDB and 230 // RocksDB. 231 return MakeInternalKey(buf, InternalKeySeqNumMax, InternalKeyKindMax) 232 } 233 return k 234 } 235 236 // Successor returns a successor key such that k <= x. A simple implementation 237 // may return k unchanged. The buf parameter may be used to store the returned 238 // InternalKey.UserKey, though it is valid to pass a nil. 239 func (k InternalKey) Successor(cmp Compare, succ Successor, buf []byte) InternalKey { 240 buf = succ(buf, k.UserKey) 241 if len(buf) <= len(k.UserKey) && cmp(k.UserKey, buf) < 0 { 242 // The successor user key is physically shorter that k.UserKey (if it is 243 // longer, we'll continue to use "k"), but logically after. Tack on the max 244 // sequence number to the shortened user key. Note that we could tack on 245 // any sequence number and kind here to create a valid separator key. We 246 // use the max sequence number to match the behavior of LevelDB and 247 // RocksDB. 248 return MakeInternalKey(buf, InternalKeySeqNumMax, InternalKeyKindMax) 249 } 250 return k 251 } 252 253 // Size returns the encoded size of the key. 254 func (k InternalKey) Size() int { 255 return len(k.UserKey) + 8 256 } 257 258 // SetSeqNum sets the sequence number component of the key. 259 func (k *InternalKey) SetSeqNum(seqNum uint64) { 260 k.Trailer = (seqNum << 8) | (k.Trailer & 0xff) 261 } 262 263 // SeqNum returns the sequence number component of the key. 264 func (k InternalKey) SeqNum() uint64 { 265 return k.Trailer >> 8 266 } 267 268 // Visible returns true if the key is visible at the specified snapshot 269 // sequence number. 270 func (k InternalKey) Visible(snapshot uint64) bool { 271 seqNum := k.SeqNum() 272 return seqNum < snapshot || (seqNum&InternalKeySeqNumBatch) != 0 273 } 274 275 // SetKind sets the kind component of the key. 276 func (k *InternalKey) SetKind(kind InternalKeyKind) { 277 k.Trailer = (k.Trailer &^ 0xff) | uint64(kind) 278 } 279 280 // Kind returns the kind compoment of the key. 281 func (k InternalKey) Kind() InternalKeyKind { 282 return InternalKeyKind(k.Trailer & 0xff) 283 } 284 285 // Valid returns true if the key has a valid kind. 286 func (k InternalKey) Valid() bool { 287 return k.Kind() <= InternalKeyKindMax 288 } 289 290 // Clone clones the storage for the UserKey component of the key. 291 func (k InternalKey) Clone() InternalKey { 292 if k.UserKey == nil { 293 return k 294 } 295 return InternalKey{ 296 UserKey: append([]byte(nil), k.UserKey...), 297 Trailer: k.Trailer, 298 } 299 } 300 301 // String returns a string representation of the key. 302 func (k InternalKey) String() string { 303 return fmt.Sprintf("%s#%d,%d", k.UserKey, k.SeqNum(), k.Kind()) 304 } 305 306 // Pretty returns a pretty-printed string representation of the key. 307 func (k InternalKey) Pretty(f func([]byte) string) string { 308 return fmt.Sprintf("%s#%d,%d", f(k.UserKey), k.SeqNum(), k.Kind()) 309 }