github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/ekv/key.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ekv 15 16 import ( 17 "bytes" 18 "encoding/hex" 19 "fmt" 20 "strconv" 21 "strings" 22 23 "github.com/whtcorpsinc/milevadb/soliton/codec" 24 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 25 "github.com/whtcorpsinc/milevadb/types" 26 ) 27 28 // Key represents high-level Key type. 29 type Key []byte 30 31 // Next returns the next key in byte-order. 32 func (k Key) Next() Key { 33 // add 0x0 to the end of key 34 buf := make([]byte, len(k)+1) 35 copy(buf, k) 36 return buf 37 } 38 39 // PrefixNext returns the next prefix key. 40 // 41 // Assume there are keys like: 42 // 43 // rowkey1 44 // rowkey1_column1 45 // rowkey1_column2 46 // rowKey2 47 // 48 // If we seek 'rowkey1' Next, we will get 'rowkey1_column1'. 49 // If we seek 'rowkey1' PrefixNext, we will get 'rowkey2'. 50 func (k Key) PrefixNext() Key { 51 buf := make([]byte, len(k)) 52 copy(buf, k) 53 var i int 54 for i = len(k) - 1; i >= 0; i-- { 55 buf[i]++ 56 if buf[i] != 0 { 57 break 58 } 59 } 60 if i == -1 { 61 copy(buf, k) 62 buf = append(buf, 0) 63 } 64 return buf 65 } 66 67 // Cmp returns the comparison result of two key. 68 // The result will be 0 if a==b, -1 if a < b, and +1 if a > b. 69 func (k Key) Cmp(another Key) int { 70 return bytes.Compare(k, another) 71 } 72 73 // HasPrefix tests whether the Key begins with prefix. 74 func (k Key) HasPrefix(prefix Key) bool { 75 return bytes.HasPrefix(k, prefix) 76 } 77 78 // Clone returns a deep copy of the Key. 79 func (k Key) Clone() Key { 80 ck := make([]byte, len(k)) 81 copy(ck, k) 82 return ck 83 } 84 85 // String implements fmt.Stringer interface. 86 func (k Key) String() string { 87 return hex.EncodeToString(k) 88 } 89 90 // KeyRange represents a range where StartKey <= key < EndKey. 91 type KeyRange struct { 92 StartKey Key 93 EndKey Key 94 } 95 96 // IsPoint checks if the key range represents a point. 97 func (r *KeyRange) IsPoint() bool { 98 if len(r.StartKey) != len(r.EndKey) { 99 // Works like 100 // return bytes.Equal(r.StartKey.Next(), r.EndKey) 101 102 startLen := len(r.StartKey) 103 return startLen+1 == len(r.EndKey) && 104 r.EndKey[startLen] == 0 && 105 bytes.Equal(r.StartKey, r.EndKey[:startLen]) 106 } 107 // Works like 108 // return bytes.Equal(r.StartKey.PrefixNext(), r.EndKey) 109 110 i := len(r.StartKey) - 1 111 for ; i >= 0; i-- { 112 if r.StartKey[i] != 255 { 113 break 114 } 115 if r.EndKey[i] != 0 { 116 return false 117 } 118 } 119 if i < 0 { 120 // In case all bytes in StartKey are 255. 121 return false 122 } 123 // The byte at diffIdx in StartKey should be one less than the byte at diffIdx in EndKey. 124 // And bytes in StartKey and EndKey before diffIdx should be equal. 125 diffOneIdx := i 126 return r.StartKey[diffOneIdx]+1 == r.EndKey[diffOneIdx] && 127 bytes.Equal(r.StartKey[:diffOneIdx], r.EndKey[:diffOneIdx]) 128 } 129 130 // Handle is the ID of a event. 131 type Handle interface { 132 // IsInt returns if the handle type is int64. 133 IsInt() bool 134 // IntValue returns the int64 value if IsInt is true, it panics if IsInt returns false. 135 IntValue() int64 136 // Next returns the minimum handle that is greater than this handle. 137 Next() Handle 138 // Equal returns if the handle equals to another handle, it panics if the types are different. 139 Equal(h Handle) bool 140 // Compare returns the comparison result of the two handles, it panics if the types are different. 141 Compare(h Handle) int 142 // Encoded returns the encoded bytes. 143 Encoded() []byte 144 // Len returns the length of the encoded bytes. 145 Len() int 146 // NumDefCauss returns the number of columns of the handle, 147 NumDefCauss() int 148 // EncodedDefCaus returns the encoded column value at the given column index. 149 EncodedDefCaus(idx int) []byte 150 // Data returns the data of all columns of a handle. 151 Data() ([]types.Causet, error) 152 // String implements the fmt.Stringer interface. 153 String() string 154 } 155 156 // IntHandle implement the Handle interface for int64 type handle. 157 type IntHandle int64 158 159 // IsInt implements the Handle interface. 160 func (ih IntHandle) IsInt() bool { 161 return true 162 } 163 164 // IntValue implements the Handle interface. 165 func (ih IntHandle) IntValue() int64 { 166 return int64(ih) 167 } 168 169 // Next implements the Handle interface. 170 func (ih IntHandle) Next() Handle { 171 return IntHandle(int64(ih) + 1) 172 } 173 174 // Equal implements the Handle interface. 175 func (ih IntHandle) Equal(h Handle) bool { 176 return h.IsInt() && int64(ih) == h.IntValue() 177 } 178 179 // Compare implements the Handle interface. 180 func (ih IntHandle) Compare(h Handle) int { 181 if !h.IsInt() { 182 panic("IntHandle compares to CommonHandle") 183 } 184 ihVal := ih.IntValue() 185 hVal := h.IntValue() 186 if ihVal > hVal { 187 return 1 188 } 189 if ihVal < hVal { 190 return -1 191 } 192 return 0 193 } 194 195 // Encoded implements the Handle interface. 196 func (ih IntHandle) Encoded() []byte { 197 return codec.EncodeInt(nil, int64(ih)) 198 } 199 200 // Len implements the Handle interface. 201 func (ih IntHandle) Len() int { 202 return 8 203 } 204 205 // NumDefCauss implements the Handle interface, not supported for IntHandle type. 206 func (ih IntHandle) NumDefCauss() int { 207 panic("not supported in IntHandle") 208 } 209 210 // EncodedDefCaus implements the Handle interface., not supported for IntHandle type. 211 func (ih IntHandle) EncodedDefCaus(idx int) []byte { 212 panic("not supported in IntHandle") 213 } 214 215 // Data implements the Handle interface. 216 func (ih IntHandle) Data() ([]types.Causet, error) { 217 return []types.Causet{types.NewIntCauset(int64(ih))}, nil 218 } 219 220 // String implements the Handle interface. 221 func (ih IntHandle) String() string { 222 return strconv.FormatInt(int64(ih), 10) 223 } 224 225 // CommonHandle implements the Handle interface for non-int64 type handle. 226 type CommonHandle struct { 227 encoded []byte 228 colEndOffsets []uint16 229 } 230 231 // NewCommonHandle creates a CommonHandle from a encoded bytes which is encoded by code.EncodeKey. 232 func NewCommonHandle(encoded []byte) (*CommonHandle, error) { 233 ch := &CommonHandle{encoded: encoded} 234 if len(encoded) < 9 { 235 padded := make([]byte, 9) 236 copy(padded, encoded) 237 ch.encoded = padded 238 } 239 remain := encoded 240 endOff := uint16(0) 241 for len(remain) > 0 { 242 if remain[0] == 0 { 243 // padded data 244 break 245 } 246 var err error 247 var col []byte 248 col, remain, err = codec.CutOne(remain) 249 if err != nil { 250 return nil, err 251 } 252 endOff += uint16(len(col)) 253 ch.colEndOffsets = append(ch.colEndOffsets, endOff) 254 } 255 return ch, nil 256 } 257 258 // IsInt implements the Handle interface. 259 func (ch *CommonHandle) IsInt() bool { 260 return false 261 } 262 263 // IntValue implements the Handle interface, not supported for CommonHandle type. 264 func (ch *CommonHandle) IntValue() int64 { 265 panic("not supported in CommonHandle") 266 } 267 268 // Next implements the Handle interface. 269 func (ch *CommonHandle) Next() Handle { 270 return &CommonHandle{ 271 encoded: Key(ch.encoded).PrefixNext(), 272 colEndOffsets: ch.colEndOffsets, 273 } 274 } 275 276 // Equal implements the Handle interface. 277 func (ch *CommonHandle) Equal(h Handle) bool { 278 return !h.IsInt() && bytes.Equal(ch.encoded, h.Encoded()) 279 } 280 281 // Compare implements the Handle interface. 282 func (ch *CommonHandle) Compare(h Handle) int { 283 if h.IsInt() { 284 panic("CommonHandle compares to IntHandle") 285 } 286 return bytes.Compare(ch.encoded, h.Encoded()) 287 } 288 289 // Encoded implements the Handle interface. 290 func (ch *CommonHandle) Encoded() []byte { 291 return ch.encoded 292 } 293 294 // Len implements the Handle interface. 295 func (ch *CommonHandle) Len() int { 296 return len(ch.encoded) 297 } 298 299 // NumDefCauss implements the Handle interface. 300 func (ch *CommonHandle) NumDefCauss() int { 301 return len(ch.colEndOffsets) 302 } 303 304 // EncodedDefCaus implements the Handle interface. 305 func (ch *CommonHandle) EncodedDefCaus(idx int) []byte { 306 colStartOffset := uint16(0) 307 if idx > 0 { 308 colStartOffset = ch.colEndOffsets[idx-1] 309 } 310 return ch.encoded[colStartOffset:ch.colEndOffsets[idx]] 311 } 312 313 // Data implements the Handle interface. 314 func (ch *CommonHandle) Data() ([]types.Causet, error) { 315 data := make([]types.Causet, 0, ch.NumDefCauss()) 316 for i := 0; i < ch.NumDefCauss(); i++ { 317 encodedDefCaus := ch.EncodedDefCaus(i) 318 _, d, err := codec.DecodeOne(encodedDefCaus) 319 if err != nil { 320 return nil, err 321 } 322 data = append(data, d) 323 } 324 return data, nil 325 } 326 327 // String implements the Handle interface. 328 func (ch *CommonHandle) String() string { 329 data, err := ch.Data() 330 if err != nil { 331 return err.Error() 332 } 333 strs := make([]string, 0, ch.NumDefCauss()) 334 for _, causet := range data { 335 str, err := causet.ToString() 336 if err != nil { 337 return err.Error() 338 } 339 strs = append(strs, str) 340 } 341 return fmt.Sprintf("{%s}", strings.Join(strs, ", ")) 342 } 343 344 // HandleMap is the map for Handle. 345 type HandleMap struct { 346 ints map[int64]interface{} 347 strs map[string]strHandleVal 348 } 349 350 type strHandleVal struct { 351 h Handle 352 val interface{} 353 } 354 355 // NewHandleMap creates a new map for handle. 356 func NewHandleMap() *HandleMap { 357 // Initialize the two maps to avoid checking nil. 358 return &HandleMap{ 359 ints: map[int64]interface{}{}, 360 strs: map[string]strHandleVal{}, 361 } 362 } 363 364 // Get gets a value by a Handle. 365 func (m *HandleMap) Get(h Handle) (v interface{}, ok bool) { 366 if h.IsInt() { 367 v, ok = m.ints[h.IntValue()] 368 } else { 369 var strVal strHandleVal 370 strVal, ok = m.strs[string(h.Encoded())] 371 v = strVal.val 372 } 373 return 374 } 375 376 // Set sets a value with a Handle. 377 func (m *HandleMap) Set(h Handle, val interface{}) { 378 if h.IsInt() { 379 m.ints[h.IntValue()] = val 380 } else { 381 m.strs[string(h.Encoded())] = strHandleVal{ 382 h: h, 383 val: val, 384 } 385 } 386 } 387 388 // Delete deletes a entry from the map. 389 func (m *HandleMap) Delete(h Handle) { 390 if h.IsInt() { 391 delete(m.ints, h.IntValue()) 392 } else { 393 delete(m.strs, string(h.Encoded())) 394 } 395 } 396 397 // Len returns the length of the map. 398 func (m *HandleMap) Len() int { 399 return len(m.ints) + len(m.strs) 400 } 401 402 // Range iterates the HandleMap with fn, the fn returns true to continue, returns false to stop. 403 func (m *HandleMap) Range(fn func(h Handle, val interface{}) bool) { 404 for h, val := range m.ints { 405 if !fn(IntHandle(h), val) { 406 return 407 } 408 } 409 for _, strVal := range m.strs { 410 if !fn(strVal.h, strVal.val) { 411 return 412 } 413 } 414 } 415 416 // BuildHandleFromCausetRow builds ekv.Handle from defcaus in event. 417 func BuildHandleFromCausetRow(sctx *stmtctx.StatementContext, event []types.Causet, handleOrdinals []int) (Handle, error) { 418 pkDts := make([]types.Causet, 0, len(handleOrdinals)) 419 for _, ordinal := range handleOrdinals { 420 pkDts = append(pkDts, event[ordinal]) 421 } 422 handleBytes, err := codec.EncodeKey(sctx, nil, pkDts...) 423 if err != nil { 424 return nil, err 425 } 426 handle, err := NewCommonHandle(handleBytes) 427 if err != nil { 428 return nil, err 429 } 430 return handle, nil 431 }