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 }