github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/refertable/query.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the MIT License. 3 // This product includes software developed at Guance Cloud (https://www.guance.com/). 4 // Copyright 2021-present Guance, Inc. 5 6 package refertable 7 8 import ( 9 "math" 10 ) 11 12 func query(index map[string]map[any][]int, 13 keys []string, values []any, count int, 14 ) ([]int, bool) { 15 if len(keys) != len(values) { 16 return nil, false 17 } 18 19 // index 数据索引递增排序 20 tmp := [][]int{} 21 22 // key 中结果数量最少的 23 var startDataIdxs []int 24 25 headerDataIdx := 0 26 tailDataIdx := math.MaxInt 27 28 for kIdx, key := range keys { 29 // value map 30 m, ok := index[key] 31 if !ok { 32 return nil, false 33 } 34 // value -> index 35 dIdxs := m[values[kIdx]] 36 lenDIdxs := len(dIdxs) 37 switch lenDIdxs { 38 case 0: 39 return nil, false 40 default: 41 // max header 42 if dIdxs[0] > headerDataIdx { 43 headerDataIdx = dIdxs[0] 44 } 45 // min tail 46 if dIdxs[lenDIdxs-1] < tailDataIdx { 47 tailDataIdx = dIdxs[lenDIdxs-1] 48 } 49 50 if len(startDataIdxs) == 0 { 51 startDataIdxs = dIdxs 52 break 53 } 54 if len(dIdxs) < len(startDataIdxs) { 55 tmp = append(tmp, startDataIdxs) 56 startDataIdxs = dIdxs 57 } else { 58 tmp = append(tmp, dIdxs) 59 } 60 } 61 } 62 63 var ret []int 64 for _, idx := range startDataIdxs { 65 // 取相交段 66 if idx < headerDataIdx { 67 continue 68 } 69 if idx > tailDataIdx { 70 break 71 } 72 73 flag := true 74 // 取相交项 75 for _, idxs := range tmp { 76 if _, ok := binSearch(idxs, idx); !ok { 77 flag = false 78 break 79 } 80 } 81 if flag { 82 ret = append(ret, idx) 83 // count = 0, 取全部结果 84 if len(ret) == count { 85 break 86 } 87 } 88 } 89 if len(ret) > 0 { 90 return ret, true 91 } 92 return nil, false 93 } 94 95 func binSearch(li []int, s int) (int, bool) { 96 start := 0 97 end := len(li) - 1 98 for start <= end { 99 mid := (start + end) / 2 100 v := li[mid] 101 switch { 102 case s == v: 103 return mid, true 104 case s > v: 105 start = mid + 1 106 case s < v: 107 end = mid - 1 108 } 109 } 110 return 0, false 111 }