github.com/wfusion/gofusion@v1.1.14/common/utils/sets.go (about) 1 package utils 2 3 import ( 4 "sync" 5 6 "github.com/wfusion/gofusion/common/utils/clone" 7 ) 8 9 type Set[T comparable] struct { 10 m *sync.RWMutex 11 storage map[T]struct{} 12 } 13 14 func NewSet[T comparable](arr ...T) (s *Set[T]) { 15 s = &Set[T]{ 16 m: new(sync.RWMutex), 17 storage: make(map[T]struct{}, len(arr)), 18 } 19 for _, item := range arr { 20 s.storage[item] = struct{}{} 21 } 22 return 23 } 24 25 func (s *Set[T]) Size() int { 26 s.m.RLock() 27 defer s.m.RUnlock() 28 return len(s.storage) 29 } 30 31 func (s *Set[T]) Items() []T { 32 s.m.RLock() 33 defer s.m.RUnlock() 34 35 i := 0 36 ret := make([]T, len(s.storage)) 37 for key := range s.storage { 38 ret[i] = key 39 i++ 40 } 41 return ret 42 } 43 44 func (s *Set[T]) Insert(val ...T) *Set[T] { 45 s.m.Lock() 46 defer s.m.Unlock() 47 48 for _, v := range val { 49 s.storage[v] = struct{}{} 50 } 51 return s 52 } 53 54 func (s *Set[T]) Remove(val ...T) *Set[T] { 55 s.m.Lock() 56 defer s.m.Unlock() 57 58 for _, v := range val { 59 delete(s.storage, v) 60 } 61 return s 62 } 63 64 func (s *Set[T]) Contains(val T) bool { 65 s.m.RLock() 66 defer s.m.RUnlock() 67 68 _, ok := s.storage[val] 69 return ok 70 } 71 72 func (s *Set[T]) IsSubsetOf(set *Set[T]) bool { 73 s.m.RLock() 74 defer s.m.RUnlock() 75 76 for val := range s.storage { 77 // The empty set is a subset of all sets, but in common business use, 78 // there is rarely such a mathematical interpretation of the empty set being considered as 79 // a subset relationship, so false is chosen here. 80 if set == nil { 81 return false 82 } 83 if _, ok := set.storage[val]; !ok { 84 return false 85 } 86 } 87 return true 88 } 89 90 func (s *Set[T]) IntersectsWith(set *Set[T]) bool { 91 s.m.RLock() 92 defer s.m.RUnlock() 93 94 src := set.storage 95 dst := s.storage 96 if len(src) > len(dst) { 97 src, dst = dst, src 98 } 99 for val := range src { 100 if dst == nil { 101 return false 102 } 103 if _, ok := dst[val]; ok { 104 return true 105 } 106 } 107 return false 108 } 109 110 func (s *Set[T]) Reject(fn func(T) bool) *Set[T] { 111 s.m.Lock() 112 defer s.m.Unlock() 113 114 for key := range s.storage { 115 if fn(key) { 116 delete(s.storage, key) 117 } 118 } 119 return s 120 } 121 122 func (s *Set[T]) Filter(fn func(T) bool) *Set[T] { 123 s.m.Lock() 124 defer s.m.Unlock() 125 126 for key := range s.storage { 127 if !fn(key) { 128 delete(s.storage, key) 129 } 130 } 131 return s 132 } 133 134 func (s *Set[T]) Equals(o *Set[T]) bool { 135 s.m.RLock() 136 defer s.m.RUnlock() 137 138 if s == nil && o == nil { 139 return true 140 } 141 if s == nil || o == nil || s.Size() != o.Size() { 142 return false 143 } 144 145 for item := range s.storage { 146 if _, ok := o.storage[item]; !ok { 147 return false 148 } 149 } 150 for item := range o.storage { 151 if _, ok := s.storage[item]; !ok { 152 return false 153 } 154 } 155 156 return true 157 } 158 159 func (s *Set[T]) Copy() (r *Set[T]) { 160 if s == nil { 161 return 162 } 163 164 s.m.RLock() 165 defer s.m.RUnlock() 166 return NewSet(s.Items()...) 167 } 168 169 func (s *Set[T]) Clone() (r *Set[T]) { 170 if s == nil { 171 return 172 } 173 174 s.m.RLock() 175 defer s.m.RUnlock() 176 177 r = NewSet[T]() 178 for _, e := range s.Items() { 179 if elem, ok := any(e).(clonable[T]); ok { 180 r.Insert(elem.Clone()) 181 } else { 182 r.Insert(clone.Clone(e)) 183 } 184 } 185 186 return 187 }