github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/sorter/comparable_sorter.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 "sort" 16 ) 17 18 type comparabeSorter interface { 19 addComparable(el *comparable) (added bool) 20 getSorted() []*comparable 21 } 22 23 // sort elements while adding new one, no following sorting is needed 24 // if limit applied (>0), only that many elements is in the result 25 type insertSorter struct { 26 comparator *comparator 27 limit int 28 comparables []*comparable 29 } 30 31 func newInsertSorter(comparator *comparator, limit int) comparabeSorter { 32 comparables := make([]*comparable, 0, limit) 33 return &insertSorter{comparator, limit, comparables} 34 } 35 36 func (is *insertSorter) addComparable(el *comparable) bool { 37 count := len(is.comparables) 38 // insert if there is no limit or limit not reached yet 39 if is.limit == 0 || count < is.limit { 40 is.insert(el) 41 return true 42 } 43 // limit reached - compare with last element and insert if "smaller" 44 // last element can be removed 45 if is.comparator.compare(el, is.comparables[count-1]) == -1 { 46 is.comparables = is.comparables[:count-1] 47 is.insert(el) 48 return true 49 } 50 return false 51 } 52 53 func (is *insertSorter) insert(el *comparable) { 54 count := len(is.comparables) 55 pos := is.findPosition(el, 0, count) 56 if pos == count { 57 is.comparables = append(is.comparables, el) 58 return 59 } 60 is.comparables = append(is.comparables[:pos+1], is.comparables[pos:]...) 61 is.comparables[pos] = el 62 } 63 64 func (is *insertSorter) findPosition(el *comparable, startInc, endExc int) int { 65 if startInc == endExc { 66 return startInc 67 } 68 69 middle := startInc + (endExc-startInc)/2 70 if is.comparator.compare(el, is.comparables[middle]) != -1 { 71 return is.findPosition(el, middle+1, endExc) 72 } 73 return is.findPosition(el, startInc, middle) 74 } 75 76 func (is *insertSorter) getSorted() []*comparable { 77 return is.comparables 78 } 79 80 // implementation of sort.Interface 81 // sorting is performed in getSorted() method 82 type defaultSorter struct { 83 comparator *comparator 84 comparables []*comparable 85 } 86 87 func newDefaultSorter(comparator *comparator, cap int) comparabeSorter { 88 return &defaultSorter{comparator, make([]*comparable, 0, cap)} 89 } 90 91 func (ds *defaultSorter) addComparable(el *comparable) bool { 92 ds.comparables = append(ds.comparables, el) 93 return true 94 } 95 96 func (ds *defaultSorter) getSorted() []*comparable { 97 sort.Sort(ds) 98 return ds.comparables 99 } 100 101 func (ds *defaultSorter) Len() int { 102 return len(ds.comparables) 103 } 104 105 func (ds *defaultSorter) Swap(i, j int) { 106 ds.comparables[i], ds.comparables[j] = ds.comparables[j], ds.comparables[i] 107 } 108 109 func (ds *defaultSorter) Less(i, j int) bool { 110 return ds.comparator.compare(ds.comparables[i], ds.comparables[j]) == -1 111 }