github.com/intel/goresctrl@v0.5.0/pkg/utils/idset.go (about) 1 /* 2 Copyright 2019-2021 Intel Corporation 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 utils 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "sort" 23 "strconv" 24 "strings" 25 ) 26 27 const ( 28 // Unknown represents an unknown id. 29 Unknown ID = -1 30 ) 31 32 // ID is nn integer id, used to identify packages, CPUs, nodes, etc. 33 type ID = int 34 35 // IDSet is an unordered set of integer ids. 36 type IDSet map[ID]struct{} 37 38 // NewIDSet creates a new unordered set of (integer) ids. 39 func NewIDSet(ids ...ID) IDSet { 40 s := make(map[ID]struct{}) 41 42 for _, id := range ids { 43 s[id] = struct{}{} 44 } 45 46 return s 47 } 48 49 // NewIDSetFromIntSlice creates a new unordered set from an integer slice. 50 func NewIDSetFromIntSlice(ids ...int) IDSet { 51 s := make(map[ID]struct{}) 52 53 for _, id := range ids { 54 s[ID(id)] = struct{}{} 55 } 56 57 return s 58 } 59 60 // Clone returns a copy of this IdSet. 61 func (s IDSet) Clone() IDSet { 62 return NewIDSet(s.Members()...) 63 } 64 65 // Add adds the given ids into the set. 66 func (s IDSet) Add(ids ...ID) { 67 for _, id := range ids { 68 s[id] = struct{}{} 69 } 70 } 71 72 // Del deletes the given ids from the set. 73 func (s IDSet) Del(ids ...ID) { 74 if s != nil { 75 for _, id := range ids { 76 delete(s, id) 77 } 78 } 79 } 80 81 // Size returns the number of ids in the set. 82 func (s IDSet) Size() int { 83 return len(s) 84 } 85 86 // Has tests if all the ids are present in the set. 87 func (s IDSet) Has(ids ...ID) bool { 88 if s == nil { 89 return false 90 } 91 92 for _, id := range ids { 93 _, ok := s[id] 94 if !ok { 95 return false 96 } 97 } 98 99 return true 100 } 101 102 // Members returns all ids in the set as a randomly ordered slice. 103 func (s IDSet) Members() []ID { 104 if s == nil { 105 return []ID{} 106 } 107 ids := make([]ID, len(s)) 108 idx := 0 109 for id := range s { 110 ids[idx] = id 111 idx++ 112 } 113 return ids 114 } 115 116 // SortedMembers returns all ids in the set as a sorted slice. 117 func (s IDSet) SortedMembers() []ID { 118 ids := s.Members() 119 sort.Slice(ids, func(i, j int) bool { 120 return ids[i] < ids[j] 121 }) 122 return ids 123 } 124 125 // String returns the set as a string. 126 func (s IDSet) String() string { 127 return s.StringWithSeparator(",") 128 } 129 130 // StringWithSeparator returns the set as a string, separated with the given separator. 131 func (s IDSet) StringWithSeparator(args ...string) string { 132 if len(s) == 0 { 133 return "" 134 } 135 136 var sep string 137 138 if len(args) == 1 { 139 sep = args[0] 140 } else { 141 sep = "," 142 } 143 144 str := "" 145 t := "" 146 for _, id := range s.SortedMembers() { 147 str = str + t + strconv.Itoa(int(id)) 148 t = sep 149 } 150 151 return str 152 } 153 154 // MarshalJSON is the JSON marshaller for IDSet. 155 func (s IDSet) MarshalJSON() ([]byte, error) { 156 return json.Marshal(s.String()) 157 } 158 159 // UnmarshalJSON is the JSON unmarshaller for IDSet. 160 func (s *IDSet) UnmarshalJSON(data []byte) error { 161 str := "" 162 if err := json.Unmarshal(data, &str); err != nil { 163 return fmt.Errorf("invalid IDSet entry '%s': %v", string(data), err) 164 } 165 166 *s = NewIDSet() 167 if str == "" { 168 return nil 169 } 170 171 for _, idstr := range strings.Split(str, ",") { 172 id, err := strconv.ParseUint(idstr, 10, 0) 173 if err != nil { 174 return fmt.Errorf("invalid IDSet entry '%s': %v", idstr, err) 175 } 176 s.Add(ID(id)) 177 } 178 179 return nil 180 }