github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/store/val/tuple_compare.go (about) 1 // Copyright 2021 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 "bytes" 18 19 // TupleComparator compares Tuples. 20 type TupleComparator interface { 21 // Compare compares pairs of Tuples. 22 Compare(left, right Tuple, desc TupleDesc) int 23 24 // CompareValues compares pairs of values. The index should match the index used to retrieve the type. 25 CompareValues(index int, left, right []byte, typ Type) int 26 27 // Prefix returns a TupleComparator for the first n types. 28 Prefix(n int) TupleComparator 29 30 // Suffix returns a TupleComparator for the last n types. 31 Suffix(n int) TupleComparator 32 33 // Validated returns a new TupleComparator that is valid against the given slice of types. Panics f a valid 34 // TupleComparator cannot be returned. 35 Validated(types []Type) TupleComparator 36 } 37 38 type DefaultTupleComparator struct{} 39 40 var _ TupleComparator = DefaultTupleComparator{} 41 42 // Compare implements TupleComparator 43 func (d DefaultTupleComparator) Compare(left, right Tuple, desc TupleDesc) (cmp int) { 44 for i := range desc.fast { 45 start, stop := desc.fast[i][0], desc.fast[i][1] 46 cmp = compare(desc.Types[i], left[start:stop], right[start:stop]) 47 if cmp != 0 { 48 return cmp 49 } 50 } 51 52 off := len(desc.fast) 53 for i, typ := range desc.Types[off:] { 54 j := i + off 55 cmp = compare(typ, left.GetField(j), right.GetField(j)) 56 if cmp != 0 { 57 return cmp 58 } 59 } 60 return 61 } 62 63 // CompareValues implements TupleComparator 64 func (d DefaultTupleComparator) CompareValues(_ int, left, right []byte, typ Type) (cmp int) { 65 return compare(typ, left, right) 66 } 67 68 // Prefix implements TupleComparator 69 func (d DefaultTupleComparator) Prefix(n int) TupleComparator { 70 return d 71 } 72 73 // Suffix implements TupleComparator 74 func (d DefaultTupleComparator) Suffix(n int) TupleComparator { 75 return d 76 } 77 78 // Validated implements TupleComparator 79 func (d DefaultTupleComparator) Validated(types []Type) TupleComparator { 80 return d 81 } 82 83 func compare(typ Type, left, right []byte) int { 84 // order NULLs first 85 if left == nil || right == nil { 86 if bytes.Equal(left, right) { 87 return 0 88 } else if left == nil { 89 return -1 90 } else { 91 return 1 92 } 93 } 94 95 switch typ.Enc { 96 case Int8Enc: 97 return compareInt8(readInt8(left), readInt8(right)) 98 case Uint8Enc: 99 return compareUint8(readUint8(left), readUint8(right)) 100 case Int16Enc: 101 return compareInt16(readInt16(left), readInt16(right)) 102 case Uint16Enc: 103 return compareUint16(ReadUint16(left), ReadUint16(right)) 104 case Int32Enc: 105 return compareInt32(readInt32(left), readInt32(right)) 106 case Uint32Enc: 107 return compareUint32(readUint32(left), readUint32(right)) 108 case Int64Enc: 109 return compareInt64(readInt64(left), readInt64(right)) 110 case Uint64Enc: 111 return compareUint64(readUint64(left), readUint64(right)) 112 case Float32Enc: 113 return compareFloat32(readFloat32(left), readFloat32(right)) 114 case Float64Enc: 115 return compareFloat64(readFloat64(left), readFloat64(right)) 116 case Bit64Enc: 117 return compareBit64(readBit64(left), readBit64(right)) 118 case DecimalEnc: 119 return compareDecimal(readDecimal(left), readDecimal(right)) 120 case YearEnc: 121 return compareYear(readYear(left), readYear(right)) 122 case DateEnc: 123 return compareDate(readDate(left), readDate(right)) 124 case TimeEnc: 125 return compareTime(readTime(left), readTime(right)) 126 case DatetimeEnc: 127 return compareDatetime(readDatetime(left), readDatetime(right)) 128 case EnumEnc: 129 return compareEnum(readEnum(left), readEnum(right)) 130 case SetEnc: 131 return compareSet(readSet(left), readSet(right)) 132 case StringEnc: 133 return compareString(readString(left), readString(right)) 134 case ByteStringEnc: 135 return compareByteString(readByteString(left), readByteString(right)) 136 case Hash128Enc: 137 return compareHash128(readHash128(left), readHash128(right)) 138 case GeomAddrEnc: 139 return compareAddr(readAddr(left), readAddr(right)) 140 case BytesAddrEnc: 141 return compareAddr(readAddr(left), readAddr(right)) 142 case CommitAddrEnc: 143 return compareAddr(readAddr(left), readAddr(right)) 144 case JSONAddrEnc: 145 return compareAddr(readAddr(left), readAddr(right)) 146 case StringAddrEnc: 147 return compareAddr(readAddr(left), readAddr(right)) 148 case CellEnc: 149 return compareCell(readCell(left), readCell(right)) 150 default: 151 panic("unknown encoding") 152 } 153 }