github.com/zhongdalu/gf@v1.0.0/g/container/gset/gset_int_set.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 // 7 8 package gset 9 10 import ( 11 "github.com/zhongdalu/gf/g/internal/rwmutex" 12 "github.com/zhongdalu/gf/g/util/gconv" 13 "strings" 14 ) 15 16 type IntSet struct { 17 mu *rwmutex.RWMutex 18 m map[int]struct{} 19 } 20 21 // New create and returns a new set, which contains un-repeated items. 22 // The parameter <unsafe> used to specify whether using set in un-concurrent-safety, 23 // which is false in default. 24 func NewIntSet(unsafe ...bool) *IntSet { 25 return &IntSet{ 26 m: make(map[int]struct{}), 27 mu: rwmutex.New(unsafe...), 28 } 29 } 30 31 // NewIntSetFrom returns a new set from <items>. 32 func NewIntSetFrom(items []int, unsafe ...bool) *IntSet { 33 m := make(map[int]struct{}) 34 for _, v := range items { 35 m[v] = struct{}{} 36 } 37 return &IntSet{ 38 m: m, 39 mu: rwmutex.New(unsafe...), 40 } 41 } 42 43 // Iterator iterates the set with given callback function <f>, 44 // if <f> returns true then continue iterating; or false to stop. 45 func (set *IntSet) Iterator(f func(v int) bool) *IntSet { 46 set.mu.RLock() 47 defer set.mu.RUnlock() 48 for k, _ := range set.m { 49 if !f(k) { 50 break 51 } 52 } 53 return set 54 } 55 56 // Add adds one or multiple items to the set. 57 func (set *IntSet) Add(item ...int) *IntSet { 58 set.mu.Lock() 59 for _, v := range item { 60 set.m[v] = struct{}{} 61 } 62 set.mu.Unlock() 63 return set 64 } 65 66 // Contains checks whether the set contains <item>. 67 func (set *IntSet) Contains(item int) bool { 68 set.mu.RLock() 69 _, exists := set.m[item] 70 set.mu.RUnlock() 71 return exists 72 } 73 74 // Remove deletes <item> from set. 75 func (set *IntSet) Remove(item int) *IntSet { 76 set.mu.Lock() 77 delete(set.m, item) 78 set.mu.Unlock() 79 return set 80 } 81 82 // Size returns the size of the set. 83 func (set *IntSet) Size() int { 84 set.mu.RLock() 85 l := len(set.m) 86 set.mu.RUnlock() 87 return l 88 } 89 90 // Clear deletes all items of the set. 91 func (set *IntSet) Clear() *IntSet { 92 set.mu.Lock() 93 set.m = make(map[int]struct{}) 94 set.mu.Unlock() 95 return set 96 } 97 98 // Slice returns the a of items of the set as slice. 99 func (set *IntSet) Slice() []int { 100 set.mu.RLock() 101 ret := make([]int, len(set.m)) 102 i := 0 103 for k, _ := range set.m { 104 ret[i] = k 105 i++ 106 } 107 set.mu.RUnlock() 108 return ret 109 } 110 111 // Join joins items with a string <glue>. 112 func (set *IntSet) Join(glue string) string { 113 return strings.Join(gconv.Strings(set.Slice()), ",") 114 } 115 116 // String returns items as a string, which are joined by char ','. 117 func (set *IntSet) String() string { 118 return set.Join(",") 119 } 120 121 // LockFunc locks writing with callback function <f>. 122 func (set *IntSet) LockFunc(f func(m map[int]struct{})) { 123 set.mu.Lock() 124 defer set.mu.Unlock() 125 f(set.m) 126 } 127 128 // RLockFunc locks reading with callback function <f>. 129 func (set *IntSet) RLockFunc(f func(m map[int]struct{})) { 130 set.mu.RLock() 131 defer set.mu.RUnlock() 132 f(set.m) 133 } 134 135 // Equal checks whether the two sets equal. 136 func (set *IntSet) Equal(other *IntSet) bool { 137 if set == other { 138 return true 139 } 140 set.mu.RLock() 141 defer set.mu.RUnlock() 142 other.mu.RLock() 143 defer other.mu.RUnlock() 144 if len(set.m) != len(other.m) { 145 return false 146 } 147 for key := range set.m { 148 if _, ok := other.m[key]; !ok { 149 return false 150 } 151 } 152 return true 153 } 154 155 // IsSubsetOf checks whether the current set is a sub-set of <other>. 156 func (set *IntSet) IsSubsetOf(other *IntSet) bool { 157 if set == other { 158 return true 159 } 160 set.mu.RLock() 161 defer set.mu.RUnlock() 162 other.mu.RLock() 163 defer other.mu.RUnlock() 164 for key := range set.m { 165 if _, ok := other.m[key]; !ok { 166 return false 167 } 168 } 169 return true 170 } 171 172 // Union returns a new set which is the union of <set> and <other>. 173 // Which means, all the items in <newSet> are in <set> or in <other>. 174 func (set *IntSet) Union(others ...*IntSet) (newSet *IntSet) { 175 newSet = NewIntSet(true) 176 set.mu.RLock() 177 defer set.mu.RUnlock() 178 for _, other := range others { 179 if set != other { 180 other.mu.RLock() 181 } 182 for k, v := range set.m { 183 newSet.m[k] = v 184 } 185 if set != other { 186 for k, v := range other.m { 187 newSet.m[k] = v 188 } 189 } 190 if set != other { 191 other.mu.RUnlock() 192 } 193 } 194 195 return 196 } 197 198 // Diff returns a new set which is the difference set from <set> to <other>. 199 // Which means, all the items in <newSet> are in <set> but not in <other>. 200 func (set *IntSet) Diff(others ...*IntSet) (newSet *IntSet) { 201 newSet = NewIntSet(true) 202 set.mu.RLock() 203 defer set.mu.RUnlock() 204 for _, other := range others { 205 if set == other { 206 continue 207 } 208 other.mu.RLock() 209 for k, v := range set.m { 210 if _, ok := other.m[k]; !ok { 211 newSet.m[k] = v 212 } 213 } 214 other.mu.RUnlock() 215 } 216 return 217 } 218 219 // Intersect returns a new set which is the intersection from <set> to <other>. 220 // Which means, all the items in <newSet> are in <set> and also in <other>. 221 func (set *IntSet) Intersect(others ...*IntSet) (newSet *IntSet) { 222 newSet = NewIntSet(true) 223 set.mu.RLock() 224 defer set.mu.RUnlock() 225 for _, other := range others { 226 if set != other { 227 other.mu.RLock() 228 } 229 for k, v := range set.m { 230 if _, ok := other.m[k]; ok { 231 newSet.m[k] = v 232 } 233 } 234 if set != other { 235 other.mu.RUnlock() 236 } 237 } 238 return 239 } 240 241 // Complement returns a new set which is the complement from <set> to <full>. 242 // Which means, all the items in <newSet> are in <full> and not in <set>. 243 // 244 // It returns the difference between <full> and <set> 245 // if the given set <full> is not the full set of <set>. 246 func (set *IntSet) Complement(full *IntSet) (newSet *IntSet) { 247 newSet = NewIntSet(true) 248 set.mu.RLock() 249 defer set.mu.RUnlock() 250 if set != full { 251 full.mu.RLock() 252 defer full.mu.RUnlock() 253 } 254 for k, v := range full.m { 255 if _, ok := set.m[k]; !ok { 256 newSet.m[k] = v 257 } 258 } 259 return 260 } 261 262 // Merge adds items from <others> sets into <set>. 263 func (set *IntSet) Merge(others ...*IntSet) *IntSet { 264 set.mu.Lock() 265 defer set.mu.Unlock() 266 for _, other := range others { 267 if set != other { 268 other.mu.RLock() 269 } 270 for k, v := range other.m { 271 set.m[k] = v 272 } 273 if set != other { 274 other.mu.RUnlock() 275 } 276 } 277 return set 278 } 279 280 // Sum sums items. 281 // Note: The items should be converted to int type, 282 // or you'd get a result that you unexpected. 283 func (set *IntSet) Sum() (sum int) { 284 set.mu.RLock() 285 defer set.mu.RUnlock() 286 for k, _ := range set.m { 287 sum += k 288 } 289 return 290 } 291 292 // Pops randomly pops an item from set. 293 func (set *IntSet) Pop(size int) int { 294 set.mu.RLock() 295 defer set.mu.RUnlock() 296 for k, _ := range set.m { 297 return k 298 } 299 return 0 300 } 301 302 // Pops randomly pops <size> items from set. 303 func (set *IntSet) Pops(size int) []int { 304 set.mu.RLock() 305 defer set.mu.RUnlock() 306 if size > len(set.m) { 307 size = len(set.m) 308 } 309 index := 0 310 array := make([]int, size) 311 for k, _ := range set.m { 312 array[index] = k 313 index++ 314 if index == size { 315 break 316 } 317 } 318 return array 319 }