github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/store/val/keyless_tuple.go (about) 1 // Copyright 2022 Dolthub, 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 // 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 val 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 21 "github.com/zeebo/xxh3" 22 23 "github.com/dolthub/dolt/go/store/pool" 24 ) 25 26 const ( 27 keylessCardSz = uint64Size 28 keylessHashSz = hash128Size 29 keylessTupleSz = keylessHashSz + 2 30 ) 31 32 func HashTupleFromValue(pool pool.BuffPool, value Tuple) (key Tuple) { 33 if len(value) < 2 || value.FieldIsNull(0) { 34 panic("invalid keyless value") 35 } 36 37 // omit the cardinality field from the hash id 38 fields := value[keylessCardSz:] 39 40 key = pool.Get(uint64(keylessTupleSz)) 41 h := xxh3.Hash128(fields) 42 binary.LittleEndian.PutUint64(key[0:8], h.Lo) 43 binary.LittleEndian.PutUint64(key[8:keylessHashSz], h.Hi) 44 copy(key[keylessHashSz:], keySuffix[:]) 45 return 46 } 47 48 func ReadHashFromTuple(keylessKey Tuple) []byte { 49 return keylessKey[keylessHashSz:] 50 } 51 52 func ReadKeylessCardinality(value Tuple) uint64 { 53 return readUint64(value[:keylessCardSz]) 54 } 55 56 func ModifyKeylessCardinality(pool pool.BuffPool, value Tuple, delta int64) (updated Tuple, after uint64) { 57 updated = cloneTuple(pool, value) 58 buf := updated[:keylessCardSz] 59 after = uint64(int64(readUint64(buf)) + delta) 60 writeUint64(buf, after) 61 return 62 } 63 64 // field count of 1, little endian encoded 65 var keySuffix = [...]byte{1, 0} 66 67 var KeylessTupleDesc = TupleDesc{ 68 Types: []Type{{Enc: Hash128Enc, Nullable: false}}, 69 cmp: keylessCompare{}, 70 } 71 72 var KeylessCardType = Type{ 73 Enc: Uint64Enc, 74 Nullable: false, 75 } 76 77 type keylessCompare struct{} 78 79 var _ TupleComparator = keylessCompare{} 80 81 // Compare implements TupleComparator 82 func (k keylessCompare) Compare(left, right Tuple, _ TupleDesc) int { 83 return bytes.Compare(left, right) 84 } 85 86 // CompareValues implements TupleComparator 87 func (k keylessCompare) CompareValues(_ int, left, right []byte, typ Type) int { 88 return compare(typ, left, right) 89 } 90 91 // Prefix implements TupleComparator 92 func (k keylessCompare) Prefix(n int) TupleComparator { 93 return k 94 } 95 96 // Suffix implements TupleComparator 97 func (k keylessCompare) Suffix(n int) TupleComparator { 98 return k 99 } 100 101 func (k keylessCompare) Validated(types []Type) TupleComparator { 102 return k 103 }