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 }