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  }