k8s.io/apimachinery@v0.29.2/pkg/util/sets/set.go (about) 1 /* 2 Copyright 2022 The Kubernetes 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 sets 18 19 import ( 20 "sort" 21 ) 22 23 // Set is a set of the same type elements, implemented via map[comparable]struct{} for minimal memory consumption. 24 type Set[T comparable] map[T]Empty 25 26 // cast transforms specified set to generic Set[T]. 27 func cast[T comparable](s map[T]Empty) Set[T] { return s } 28 29 // New creates a Set from a list of values. 30 // NOTE: type param must be explicitly instantiated if given items are empty. 31 func New[T comparable](items ...T) Set[T] { 32 ss := make(Set[T], len(items)) 33 ss.Insert(items...) 34 return ss 35 } 36 37 // KeySet creates a Set from a keys of a map[comparable](? extends interface{}). 38 // If the value passed in is not actually a map, this will panic. 39 func KeySet[T comparable, V any](theMap map[T]V) Set[T] { 40 ret := Set[T]{} 41 for keyValue := range theMap { 42 ret.Insert(keyValue) 43 } 44 return ret 45 } 46 47 // Insert adds items to the set. 48 func (s Set[T]) Insert(items ...T) Set[T] { 49 for _, item := range items { 50 s[item] = Empty{} 51 } 52 return s 53 } 54 55 func Insert[T comparable](set Set[T], items ...T) Set[T] { 56 return set.Insert(items...) 57 } 58 59 // Delete removes all items from the set. 60 func (s Set[T]) Delete(items ...T) Set[T] { 61 for _, item := range items { 62 delete(s, item) 63 } 64 return s 65 } 66 67 // Clear empties the set. 68 // It is preferable to replace the set with a newly constructed set, 69 // but not all callers can do that (when there are other references to the map). 70 // In some cases the set *won't* be fully cleared, e.g. a Set[float32] containing NaN 71 // can't be cleared because NaN can't be removed. 72 // For sets containing items of a type that is reflexive for ==, 73 // this is optimized to a single call to runtime.mapclear(). 74 func (s Set[T]) Clear() Set[T] { 75 for key := range s { 76 delete(s, key) 77 } 78 return s 79 } 80 81 // Has returns true if and only if item is contained in the set. 82 func (s Set[T]) Has(item T) bool { 83 _, contained := s[item] 84 return contained 85 } 86 87 // HasAll returns true if and only if all items are contained in the set. 88 func (s Set[T]) HasAll(items ...T) bool { 89 for _, item := range items { 90 if !s.Has(item) { 91 return false 92 } 93 } 94 return true 95 } 96 97 // HasAny returns true if any items are contained in the set. 98 func (s Set[T]) HasAny(items ...T) bool { 99 for _, item := range items { 100 if s.Has(item) { 101 return true 102 } 103 } 104 return false 105 } 106 107 // Clone returns a new set which is a copy of the current set. 108 func (s Set[T]) Clone() Set[T] { 109 result := make(Set[T], len(s)) 110 for key := range s { 111 result.Insert(key) 112 } 113 return result 114 } 115 116 // Difference returns a set of objects that are not in s2. 117 // For example: 118 // s1 = {a1, a2, a3} 119 // s2 = {a1, a2, a4, a5} 120 // s1.Difference(s2) = {a3} 121 // s2.Difference(s1) = {a4, a5} 122 func (s1 Set[T]) Difference(s2 Set[T]) Set[T] { 123 result := New[T]() 124 for key := range s1 { 125 if !s2.Has(key) { 126 result.Insert(key) 127 } 128 } 129 return result 130 } 131 132 // SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. 133 // For example: 134 // s1 = {a1, a2, a3} 135 // s2 = {a1, a2, a4, a5} 136 // s1.SymmetricDifference(s2) = {a3, a4, a5} 137 // s2.SymmetricDifference(s1) = {a3, a4, a5} 138 func (s1 Set[T]) SymmetricDifference(s2 Set[T]) Set[T] { 139 return s1.Difference(s2).Union(s2.Difference(s1)) 140 } 141 142 // Union returns a new set which includes items in either s1 or s2. 143 // For example: 144 // s1 = {a1, a2} 145 // s2 = {a3, a4} 146 // s1.Union(s2) = {a1, a2, a3, a4} 147 // s2.Union(s1) = {a1, a2, a3, a4} 148 func (s1 Set[T]) Union(s2 Set[T]) Set[T] { 149 result := s1.Clone() 150 for key := range s2 { 151 result.Insert(key) 152 } 153 return result 154 } 155 156 // Intersection returns a new set which includes the item in BOTH s1 and s2 157 // For example: 158 // s1 = {a1, a2} 159 // s2 = {a2, a3} 160 // s1.Intersection(s2) = {a2} 161 func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] { 162 var walk, other Set[T] 163 result := New[T]() 164 if s1.Len() < s2.Len() { 165 walk = s1 166 other = s2 167 } else { 168 walk = s2 169 other = s1 170 } 171 for key := range walk { 172 if other.Has(key) { 173 result.Insert(key) 174 } 175 } 176 return result 177 } 178 179 // IsSuperset returns true if and only if s1 is a superset of s2. 180 func (s1 Set[T]) IsSuperset(s2 Set[T]) bool { 181 for item := range s2 { 182 if !s1.Has(item) { 183 return false 184 } 185 } 186 return true 187 } 188 189 // Equal returns true if and only if s1 is equal (as a set) to s2. 190 // Two sets are equal if their membership is identical. 191 // (In practice, this means same elements, order doesn't matter) 192 func (s1 Set[T]) Equal(s2 Set[T]) bool { 193 return len(s1) == len(s2) && s1.IsSuperset(s2) 194 } 195 196 type sortableSliceOfGeneric[T ordered] []T 197 198 func (g sortableSliceOfGeneric[T]) Len() int { return len(g) } 199 func (g sortableSliceOfGeneric[T]) Less(i, j int) bool { return less[T](g[i], g[j]) } 200 func (g sortableSliceOfGeneric[T]) Swap(i, j int) { g[i], g[j] = g[j], g[i] } 201 202 // List returns the contents as a sorted T slice. 203 // 204 // This is a separate function and not a method because not all types supported 205 // by Generic are ordered and only those can be sorted. 206 func List[T ordered](s Set[T]) []T { 207 res := make(sortableSliceOfGeneric[T], 0, len(s)) 208 for key := range s { 209 res = append(res, key) 210 } 211 sort.Sort(res) 212 return res 213 } 214 215 // UnsortedList returns the slice with contents in random order. 216 func (s Set[T]) UnsortedList() []T { 217 res := make([]T, 0, len(s)) 218 for key := range s { 219 res = append(res, key) 220 } 221 return res 222 } 223 224 // PopAny returns a single element from the set. 225 func (s Set[T]) PopAny() (T, bool) { 226 for key := range s { 227 s.Delete(key) 228 return key, true 229 } 230 var zeroValue T 231 return zeroValue, false 232 } 233 234 // Len returns the size of the set. 235 func (s Set[T]) Len() int { 236 return len(s) 237 } 238 239 func less[T ordered](lhs, rhs T) bool { 240 return lhs < rhs 241 }