go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/common/i64.go (about) 1 // Copyright 2020 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package common 16 17 import "sort" 18 19 // UniqueSorted sorts & removes duplicates in place. 20 // 21 // Returns the potentially shorter slice. 22 func UniqueSorted(v []int64) []int64 { 23 if len(v) <= 1 { 24 return v 25 } 26 27 sort.Slice(v, func(i, j int) bool { return v[i] < v[j] }) 28 n, prev, skipped := 0, v[0], false 29 for _, id := range v[1:] { 30 if id == prev { 31 skipped = true 32 continue 33 } 34 n++ 35 if skipped { 36 v[n] = id 37 } 38 prev = id 39 } 40 return v[:n+1] 41 } 42 43 // DifferenceSorted returns all int64s in the first slice and not the second. 44 // 45 // Both slices must be sorted. Doesn't modify input slices. 46 func DifferenceSorted(a, b []int64) []int64 { 47 var diff []int64 48 for { 49 if len(b) == 0 { 50 return append(diff, a...) 51 } 52 if len(a) == 0 { 53 return diff 54 } 55 x, y := a[0], b[0] 56 switch { 57 case x == y: 58 a, b = a[1:], b[1:] 59 case x < y: 60 diff = append(diff, x) 61 a = a[1:] 62 default: 63 b = b[1:] 64 } 65 } 66 } 67 68 // UnionSorted returns sorted unique int64s from two slices. 69 // 70 // Both slices must be sorted and unique. Doesn't modify input slices. 71 func UnionSorted(a, b []int64) []int64 { 72 u := make([]int64, 0, len(a)+len(b)) 73 for { 74 if len(b) == 0 { 75 return append(u, a...) 76 } 77 if len(a) == 0 { 78 return append(u, b...) 79 } 80 x, y := a[0], b[0] 81 switch { 82 case x == y: 83 a, b = a[1:], b[1:] 84 u = append(u, x) 85 case x < y: 86 u = append(u, x) 87 a = a[1:] 88 default: 89 u = append(u, y) 90 b = b[1:] 91 } 92 } 93 }