github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/sorter/basic_comparators.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package sorter
    13  
    14  import (
    15  	"strings"
    16  	"time"
    17  
    18  	"github.com/weaviate/weaviate/entities/schema"
    19  )
    20  
    21  type basicComparatorProvider struct{}
    22  
    23  func (bcp *basicComparatorProvider) provide(dataType schema.DataType, order string) basicComparator {
    24  	switch dataType {
    25  	case schema.DataTypeBlob:
    26  		return newStringComparator(order)
    27  	case schema.DataTypeText:
    28  		return newStringComparator(order)
    29  	case schema.DataTypeTextArray:
    30  		return newStringArrayComparator(order)
    31  	case schema.DataTypeNumber, schema.DataTypeInt:
    32  		return newFloat64Comparator(order)
    33  	case schema.DataTypeNumberArray, schema.DataTypeIntArray:
    34  		return newFloat64ArrayComparator(order)
    35  	case schema.DataTypeDate:
    36  		return newDateComparator(order)
    37  	case schema.DataTypeDateArray:
    38  		return newDateArrayComparator(order)
    39  	case schema.DataTypeBoolean:
    40  		return newBoolComparator(order)
    41  	case schema.DataTypeBooleanArray:
    42  		return newBoolArrayComparator(order)
    43  	case schema.DataTypePhoneNumber:
    44  		return newFloat64ArrayComparator(order)
    45  	case schema.DataTypeGeoCoordinates:
    46  		return newFloat64ArrayComparator(order)
    47  	default:
    48  		return newAnyComparator(order)
    49  	}
    50  }
    51  
    52  type basicComparator interface {
    53  	compare(a, b interface{}) int
    54  }
    55  
    56  type stringComparator struct {
    57  	lessValue int
    58  }
    59  
    60  func newStringComparator(order string) *stringComparator {
    61  	return &stringComparator{lessValue(order)}
    62  }
    63  
    64  func (sc *stringComparator) compare(a, b interface{}) int {
    65  	a, b = sc.untypedNil(a), sc.untypedNil(b)
    66  	if a != nil && b != nil {
    67  		return sc.compareStrings(*(a.(*string)), *(b.(*string)))
    68  	}
    69  	return handleNils(a == nil, b == nil, sc.lessValue)
    70  }
    71  
    72  func (sc *stringComparator) compareStrings(a, b string) int {
    73  	if strings.EqualFold(a, b) {
    74  		return 0
    75  	}
    76  	if strings.ToLower(a) < strings.ToLower(b) {
    77  		return sc.lessValue
    78  	}
    79  	return -sc.lessValue
    80  }
    81  
    82  func (sc *stringComparator) untypedNil(x interface{}) interface{} {
    83  	if x == (*string)(nil) {
    84  		return nil
    85  	}
    86  	return x
    87  }
    88  
    89  type stringArrayComparator struct {
    90  	sc *stringComparator
    91  	ic *intComparator
    92  }
    93  
    94  func newStringArrayComparator(order string) *stringArrayComparator {
    95  	return &stringArrayComparator{newStringComparator(order), newIntComparator(order)}
    96  }
    97  
    98  func (sac *stringArrayComparator) compare(a, b interface{}) int {
    99  	a, b = sac.untypedNil(a), sac.untypedNil(b)
   100  	if a != nil && b != nil {
   101  		aArr, bArr := *(a.(*[]string)), *(b.(*[]string))
   102  		aLen, bLen := len(aArr), len(bArr)
   103  
   104  		for i := 0; i < aLen && i < bLen; i++ {
   105  			if res := sac.sc.compareStrings(aArr[i], bArr[i]); res != 0 {
   106  				return res
   107  			}
   108  		}
   109  		return sac.ic.compareInts(aLen, bLen)
   110  	}
   111  	return handleNils(a == nil, b == nil, sac.sc.lessValue)
   112  }
   113  
   114  func (sac *stringArrayComparator) untypedNil(x interface{}) interface{} {
   115  	if x == (*[]string)(nil) {
   116  		return nil
   117  	}
   118  	return x
   119  }
   120  
   121  type float64Comparator struct {
   122  	lessValue int
   123  }
   124  
   125  func newFloat64Comparator(order string) *float64Comparator {
   126  	return &float64Comparator{lessValue(order)}
   127  }
   128  
   129  func (fc *float64Comparator) compare(a, b interface{}) int {
   130  	a, b = fc.untypedNil(a), fc.untypedNil(b)
   131  	if a != nil && b != nil {
   132  		return fc.compareFloats64(*(a.(*float64)), *(b.(*float64)))
   133  	}
   134  	return handleNils(a == nil, b == nil, fc.lessValue)
   135  }
   136  
   137  func (fc *float64Comparator) compareFloats64(a, b float64) int {
   138  	if a == b {
   139  		return 0
   140  	}
   141  	if a < b {
   142  		return fc.lessValue
   143  	}
   144  	return -fc.lessValue
   145  }
   146  
   147  func (fc *float64Comparator) untypedNil(x interface{}) interface{} {
   148  	if x == (*float64)(nil) {
   149  		return nil
   150  	}
   151  	return x
   152  }
   153  
   154  type float64ArrayComparator struct {
   155  	fc *float64Comparator
   156  	ic *intComparator
   157  }
   158  
   159  func newFloat64ArrayComparator(order string) *float64ArrayComparator {
   160  	return &float64ArrayComparator{newFloat64Comparator(order), newIntComparator(order)}
   161  }
   162  
   163  func (fac *float64ArrayComparator) compare(a, b interface{}) int {
   164  	a, b = fac.untypedNil(a), fac.untypedNil(b)
   165  	if a != nil && b != nil {
   166  		aArr, bArr := *(a.(*[]float64)), *(b.(*[]float64))
   167  		aLen, bLen := len(aArr), len(bArr)
   168  
   169  		for i := 0; i < aLen && i < bLen; i++ {
   170  			if res := fac.fc.compareFloats64(aArr[i], bArr[i]); res != 0 {
   171  				return res
   172  			}
   173  		}
   174  		return fac.ic.compareInts(aLen, bLen)
   175  	}
   176  	return handleNils(a == nil, b == nil, fac.fc.lessValue)
   177  }
   178  
   179  func (fac *float64ArrayComparator) untypedNil(x interface{}) interface{} {
   180  	if x == (*[]float64)(nil) {
   181  		return nil
   182  	}
   183  	return x
   184  }
   185  
   186  type dateComparator struct {
   187  	lessValue int
   188  }
   189  
   190  func newDateComparator(order string) *dateComparator {
   191  	return &dateComparator{lessValue(order)}
   192  }
   193  
   194  func (dc *dateComparator) compare(a, b interface{}) int {
   195  	a, b = dc.untypedNil(a), dc.untypedNil(b)
   196  	if a != nil && b != nil {
   197  		return dc.compareDates(*(a.(*time.Time)), *(b.(*time.Time)))
   198  	}
   199  	return handleNils(a == nil, b == nil, dc.lessValue)
   200  }
   201  
   202  func (dc *dateComparator) compareDates(a, b time.Time) int {
   203  	if a.Equal(b) {
   204  		return 0
   205  	}
   206  	if a.Before(b) {
   207  		return dc.lessValue
   208  	}
   209  	return -dc.lessValue
   210  }
   211  
   212  func (dc *dateComparator) untypedNil(x interface{}) interface{} {
   213  	if x == (*time.Time)(nil) {
   214  		return nil
   215  	}
   216  	return x
   217  }
   218  
   219  type dateArrayComparator struct {
   220  	dc *dateComparator
   221  	ic *intComparator
   222  }
   223  
   224  func newDateArrayComparator(order string) *dateArrayComparator {
   225  	return &dateArrayComparator{newDateComparator(order), newIntComparator(order)}
   226  }
   227  
   228  func (dac *dateArrayComparator) compare(a, b interface{}) int {
   229  	a, b = dac.untypedNil(a), dac.untypedNil(b)
   230  	if a != nil && b != nil {
   231  		aArr, bArr := *(a.(*[]time.Time)), *(b.(*[]time.Time))
   232  		aLen, bLen := len(aArr), len(bArr)
   233  
   234  		for i := 0; i < aLen && i < bLen; i++ {
   235  			if res := dac.dc.compareDates(aArr[i], bArr[i]); res != 0 {
   236  				return res
   237  			}
   238  		}
   239  		return dac.ic.compareInts(aLen, bLen)
   240  	}
   241  	return handleNils(a == nil, b == nil, dac.dc.lessValue)
   242  }
   243  
   244  func (dac *dateArrayComparator) untypedNil(x interface{}) interface{} {
   245  	if x == (*[]time.Time)(nil) {
   246  		return nil
   247  	}
   248  	return x
   249  }
   250  
   251  type boolComparator struct {
   252  	lessValue int
   253  }
   254  
   255  func newBoolComparator(order string) *boolComparator {
   256  	return &boolComparator{lessValue(order)}
   257  }
   258  
   259  func (bc *boolComparator) compare(a, b interface{}) int {
   260  	a, b = bc.untypedNil(a), bc.untypedNil(b)
   261  	if a != nil && b != nil {
   262  		return bc.compareBools(*(a.(*bool)), *(b.(*bool)))
   263  	}
   264  	return handleNils(a == nil, b == nil, bc.lessValue)
   265  }
   266  
   267  func (bc *boolComparator) compareBools(a, b bool) int {
   268  	if a && b {
   269  		return 0
   270  	}
   271  	if !a && !b {
   272  		return 0
   273  	}
   274  	if !a {
   275  		return bc.lessValue
   276  	}
   277  	return -bc.lessValue
   278  }
   279  
   280  func (bc *boolComparator) untypedNil(x interface{}) interface{} {
   281  	if x == (*bool)(nil) {
   282  		return nil
   283  	}
   284  	return x
   285  }
   286  
   287  type boolArrayComparator struct {
   288  	bc *boolComparator
   289  	ic *intComparator
   290  }
   291  
   292  func newBoolArrayComparator(order string) *boolArrayComparator {
   293  	return &boolArrayComparator{newBoolComparator(order), newIntComparator(order)}
   294  }
   295  
   296  func (bac *boolArrayComparator) compare(a, b interface{}) int {
   297  	a, b = bac.untypedNil(a), bac.untypedNil(b)
   298  	if a != nil && b != nil {
   299  		aArr, bArr := *(a.(*[]bool)), *(b.(*[]bool))
   300  		aLen, bLen := len(aArr), len(bArr)
   301  
   302  		for i := 0; i < aLen && i < bLen; i++ {
   303  			if res := bac.bc.compareBools(aArr[i], bArr[i]); res != 0 {
   304  				return res
   305  			}
   306  		}
   307  		return bac.ic.compareInts(aLen, bLen)
   308  	}
   309  	return handleNils(a == nil, b == nil, bac.bc.lessValue)
   310  }
   311  
   312  func (bac *boolArrayComparator) untypedNil(x interface{}) interface{} {
   313  	if x == (*[]bool)(nil) {
   314  		return nil
   315  	}
   316  	return x
   317  }
   318  
   319  type intComparator struct {
   320  	lessValue int
   321  }
   322  
   323  func newIntComparator(order string) *intComparator {
   324  	return &intComparator{lessValue(order)}
   325  }
   326  
   327  func (ic *intComparator) compare(a, b interface{}) int {
   328  	a, b = ic.untypedNil(a), ic.untypedNil(b)
   329  	if a != nil && b != nil {
   330  		return ic.compareInts(*(a.(*int)), *(b.(*int)))
   331  	}
   332  	return handleNils(a == nil, b == nil, ic.lessValue)
   333  }
   334  
   335  func (ic *intComparator) compareInts(a, b int) int {
   336  	if a == b {
   337  		return 0
   338  	}
   339  	if a < b {
   340  		return ic.lessValue
   341  	}
   342  	return -ic.lessValue
   343  }
   344  
   345  func (ic *intComparator) untypedNil(x interface{}) interface{} {
   346  	if x == (*int)(nil) {
   347  		return nil
   348  	}
   349  	return x
   350  }
   351  
   352  type anyComparator struct {
   353  	lessValue int
   354  }
   355  
   356  func newAnyComparator(order string) *anyComparator {
   357  	return &anyComparator{lessValue(order)}
   358  }
   359  
   360  func (ac *anyComparator) compare(a, b interface{}) int {
   361  	if a != nil && b != nil {
   362  		return 0
   363  	}
   364  	return handleNils(a == nil, b == nil, ac.lessValue)
   365  }
   366  
   367  func handleNils(aNil, bNil bool, lessValue int) int {
   368  	if aNil && bNil {
   369  		return 0
   370  	}
   371  	if aNil {
   372  		return lessValue
   373  	}
   374  	return -lessValue
   375  }
   376  
   377  func lessValue(order string) int {
   378  	if order == "desc" {
   379  		return 1
   380  	}
   381  	return -1
   382  }