github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/general/sorter.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package general 18 19 import ( 20 "sort" 21 ) 22 23 // CmpFunc compares object-1 and object-2 and returns: 24 // 25 // -1 if object-1 < object-2 26 // 0 if object-1 == object-2 27 // +1 if object-1 > object-2 28 // 29 30 type CmpFunc func(i1, i2 interface{}) int 31 32 type SourceList interface { 33 Len() int 34 GetSource(index int) interface{} 35 SetSource(index int, s interface{}) 36 } 37 38 // MultiSorter implements the Sort interface, sorting changes within. 39 type MultiSorter struct { 40 cmp []CmpFunc 41 } 42 43 // NewMultiSorter returns a Sorter that sorts using the cmp functions, in order. 44 // Call its Sort method to sort the data. 45 func NewMultiSorter(cmp ...CmpFunc) *MultiSorter { 46 return &MultiSorter{ 47 cmp: cmp, 48 } 49 } 50 51 // Sort sorts the argument slice according to the Less functions passed to NewMultiSorter. 52 func (ms *MultiSorter) Sort(sources SourceList) { 53 sort.Sort(&sortableSourceList{ 54 sources: sources, 55 cmp: ms.cmp, 56 }) 57 } 58 59 type sortableSourceList struct { 60 sources SourceList 61 cmp []CmpFunc 62 } 63 64 // Len is part of sort.Interface. 65 func (ms *sortableSourceList) Len() int { 66 return ms.sources.Len() 67 } 68 69 // Swap is part of sort.Interface. 70 func (ms *sortableSourceList) Swap(i, j int) { 71 si, sj := ms.sources.GetSource(i), ms.sources.GetSource(j) 72 ms.sources.SetSource(i, sj) 73 ms.sources.SetSource(j, si) 74 } 75 76 // Less is part of sort.Interface. 77 func (ms *sortableSourceList) Less(i, j int) bool { 78 s1, s2 := ms.sources.GetSource(i), ms.sources.GetSource(j) 79 var k int 80 for k = 0; k < len(ms.cmp)-1; k++ { 81 cmpResult := ms.cmp[k](s1, s2) 82 // p1 is less than p2 83 if cmpResult < 0 { 84 return true 85 } 86 // p1 is greater than p2 87 if cmpResult > 0 { 88 return false 89 } 90 // we don't know yet 91 } 92 // the last cmp func is the final decider 93 return ms.cmp[k](s1, s2) < 0 94 } 95 96 // CmpBool compares booleans, placing true before false 97 func CmpBool(a, b bool) int { 98 if a == b { 99 return 0 100 } 101 if !b { 102 return -1 103 } 104 return 1 105 } 106 107 // CmpError compares errors, placing not nil before nil 108 func CmpError(err1, err2 error) int { 109 if err1 != nil && err2 != nil { 110 return 0 111 } 112 if err1 != nil { 113 return -1 114 } 115 return 1 116 } 117 118 // CmpFloat64 compares float64s, placing greater before smaller 119 func CmpFloat64(a, b float64) int { 120 if a == b { 121 return 0 122 } 123 if a < b { 124 return 1 125 } 126 return -1 127 } 128 129 // CmpInt32 compares int32s, placing greater before smaller 130 func CmpInt32(a, b int32) int { 131 if a == b { 132 return 0 133 } 134 if a < b { 135 return 1 136 } 137 return -1 138 } 139 140 // CmpString compares strings, placing greater before smaller 141 func CmpString(a, b string) int { 142 if a == b { 143 return 0 144 } 145 146 if a < b { 147 return 1 148 } 149 150 return -1 151 } 152 153 func ReverseCmpFunc(cmpFunc CmpFunc) CmpFunc { 154 return func(i1, i2 interface{}) int { 155 return -cmpFunc(i1, i2) 156 } 157 }