@@ -6,13 +6,6 @@ import (
66 "sync"
77)
88
9- // StringSet is a set of unique strings.
10- // The lock sync.RWMutex allows to solve concurrency issues
11- type StringSet struct {
12- m map [string ]struct {}
13- lock sync.RWMutex
14- }
15-
169// New creates a new instance of type *Stringset
1710func New () * StringSet {
1811 res := & StringSet {
@@ -22,36 +15,18 @@ func New() *StringSet {
2215 return res
2316}
2417
25- // AddSlice adds the elements of the slice to the set.
26- func (s * StringSet ) AddSlice (slice []string ) * StringSet {
27-
28- s .lock .Lock ()
29- defer s .lock .Unlock ()
30-
31- for _ , str := range slice {
32- s .m [str ] = struct {}{}
33- }
34-
35- return s
36- }
37-
3818// NewStringSet creates a new set for strings.
3919func NewStringSet (strings ... string ) * StringSet {
4020 res := & StringSet {
4121 m : map [string ]struct {}{},
4222 }
23+ res .lock .Lock ()
4324 for _ , s := range strings {
44- res .Add ( s )
25+ res .m [ s ] = struct {}{}
4526 }
46- return res
47- }
27+ res .lock .Unlock ()
4828
49- // Add adds a string to the set.
50- // If string is already in the set, it has no effect.
51- func (s * StringSet ) Add (str string ) {
52- s .lock .Lock ()
53- s .m [str ] = struct {}{}
54- s .lock .Unlock ()
29+ return res
5530}
5631
5732// Exists checks if string exists in the set.
@@ -102,25 +77,8 @@ func (s *StringSet) Contains(other *StringSet) bool {
10277 return true
10378}
10479
105- // Unify returns the first set which contains all elements of the two sets.
106- func (s * StringSet ) Unify (other * StringSet ) {
107- var wg sync.WaitGroup
108- wg .Add (1 )
109- go func () {
110- defer wg .Done ()
111- other .lock .Lock ()
112- for str := range other .m {
113- s .lock .Lock ()
114- s .m [str ] = struct {}{}
115- s .lock .Unlock ()
116- }
117- other .lock .Unlock ()
118- }()
119- wg .Wait ()
120- }
121-
12280// Union returns a new set which contains all elements of the previous ones.
123- func (s * StringSet ) Union (other * StringSet ) ( union * StringSet ) {
81+ func (s * StringSet ) Union (other * StringSet ) * StringSet {
12482 var slen , otherlen int
12583 var wg sync.WaitGroup
12684 wg .Add (2 )
@@ -178,92 +136,40 @@ func (s *StringSet) Len() int {
178136 return n
179137}
180138
181- // Pop removes and returns an arbitrary element from the set and removes it from the
182- // set. If the set was empty, this returns ( "", false) .
183- func (s * StringSet ) Pop () (str string , ok bool ) {
139+ // Pop returns and removes an arbitrary element from the set.
140+ // If the set is empty it returns "", false.
141+ func (s * StringSet ) Pop () (string , bool ) {
184142 s .lock .Lock ()
185143 defer s .lock .Unlock ()
186- if len (s .m ) != 0 {
144+ var str string
145+ switch len (s .m ) {
146+ case 0 :
147+ return "" , false
148+ default :
187149 // deletes only one value from the set and than exits
188150 for str = range s .m {
189151 delete (s .m , str )
190- return str , true
152+ break
191153 }
192154 }
193- return "" , false
155+ return str , true
194156}
195157
196- // Difference returns a new set with all elements from the first set and no elements from the latter.
197- func (s * StringSet ) Difference (other * StringSet ) (diff * StringSet ) {
198- ret := & StringSet {
158+ // Difference returns a new set with all elements from the first set less
159+ // all elements from the second one.
160+ func (s * StringSet ) Difference (other * StringSet ) * StringSet {
161+ diff := & StringSet {
199162 m : map [string ]struct {}{},
200163 }
201164 s .lock .Lock ()
202165 for str := range s .m {
203- ret .m [str ] = struct {}{}
166+ diff .m [str ] = struct {}{}
204167 }
205168 s .lock .Unlock ()
206169 other .lock .Lock ()
207170 for str := range other .m {
208- delete (ret .m , str )
171+ delete (diff .m , str )
209172 }
210173 other .lock .Unlock ()
211- return ret
212- }
213-
214- // Intersect returns a new set which contains only the elemets shared by both input sets.
215- func (s * StringSet ) Intersect (other * StringSet ) (intersection * StringSet ) {
216- var ret * StringSet
217- var wg sync.WaitGroup
218-
219- var slen , otherlen int
220-
221- createIntersect := func (smallerlen int , smaller , greater * StringSet ) (ret * StringSet ) {
222- ret = & StringSet {
223- m : make (map [string ]struct {}, smallerlen ),
224- }
225- // Copy smaller set in ret
226- smaller .lock .Lock ()
227- for str := range smaller .m {
228- ret .m [str ] = struct {}{}
229- }
230- smaller .lock .Unlock ()
231-
232- greater .lock .Lock ()
233- defer greater .lock .Unlock ()
234- for element := range ret .m {
235- // If element in smaller exists also in greater moves along
236- if _ , exists := greater .m [element ]; exists {
237- continue
238- }
239- // otherwise deletes it also from ret
240- ret .lock .Lock ()
241- delete (ret .m , element )
242- ret .lock .Unlock ()
243- }
244- return ret
245- }
246-
247- wg .Add (2 )
248- go func () {
249- defer wg .Done ()
250- s .lock .Lock ()
251- slen = len (s .m )
252- s .lock .Unlock ()
253- }()
254- go func () {
255- defer wg .Done ()
256- other .lock .Lock ()
257- otherlen = len (other .m )
258- other .lock .Unlock ()
259- }()
260- wg .Wait ()
261- switch {
262- case slen >= otherlen :
263- ret = createIntersect (otherlen , other , s )
264-
265- case slen < otherlen :
266- ret = createIntersect (slen , s , other )
267- }
268- return ret
174+ return diff
269175}
0 commit comments