Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / deckarep / golang-set / threadunsafe.go
1 /*
2 Open Source Initiative OSI - The MIT License (MIT):Licensing
3
4 The MIT License (MIT)
5 Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com)
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy of
8 this software and associated documentation files (the "Software"), to deal in
9 the Software without restriction, including without limitation the rights to
10 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 of the Software, and to permit persons to whom the Software is furnished to do
12 so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 */
25
26 package mapset
27
28 import (
29         "fmt"
30         "reflect"
31         "strings"
32 )
33
34 type threadUnsafeSet map[interface{}]struct{}
35
36 type orderedPair struct {
37         first  interface{}
38         second interface{}
39 }
40
41 func newThreadUnsafeSet() threadUnsafeSet {
42         return make(threadUnsafeSet)
43 }
44
45 func (pair *orderedPair) Equal(other orderedPair) bool {
46         if pair.first == other.first &&
47                 pair.second == other.second {
48                 return true
49         }
50
51         return false
52 }
53
54 func (set *threadUnsafeSet) Add(i interface{}) bool {
55         _, found := (*set)[i]
56         (*set)[i] = struct{}{}
57         return !found //False if it existed already
58 }
59
60 func (set *threadUnsafeSet) Contains(i ...interface{}) bool {
61         for _, val := range i {
62                 if _, ok := (*set)[val]; !ok {
63                         return false
64                 }
65         }
66         return true
67 }
68
69 func (set *threadUnsafeSet) IsSubset(other Set) bool {
70         _ = other.(*threadUnsafeSet)
71         for elem := range *set {
72                 if !other.Contains(elem) {
73                         return false
74                 }
75         }
76         return true
77 }
78
79 func (set *threadUnsafeSet) IsSuperset(other Set) bool {
80         return other.IsSubset(set)
81 }
82
83 func (set *threadUnsafeSet) Union(other Set) Set {
84         o := other.(*threadUnsafeSet)
85
86         unionedSet := newThreadUnsafeSet()
87
88         for elem := range *set {
89                 unionedSet.Add(elem)
90         }
91         for elem := range *o {
92                 unionedSet.Add(elem)
93         }
94         return &unionedSet
95 }
96
97 func (set *threadUnsafeSet) Intersect(other Set) Set {
98         o := other.(*threadUnsafeSet)
99
100         intersection := newThreadUnsafeSet()
101         // loop over smaller set
102         if set.Cardinality() < other.Cardinality() {
103                 for elem := range *set {
104                         if other.Contains(elem) {
105                                 intersection.Add(elem)
106                         }
107                 }
108         } else {
109                 for elem := range *o {
110                         if set.Contains(elem) {
111                                 intersection.Add(elem)
112                         }
113                 }
114         }
115         return &intersection
116 }
117
118 func (set *threadUnsafeSet) Difference(other Set) Set {
119         _ = other.(*threadUnsafeSet)
120
121         difference := newThreadUnsafeSet()
122         for elem := range *set {
123                 if !other.Contains(elem) {
124                         difference.Add(elem)
125                 }
126         }
127         return &difference
128 }
129
130 func (set *threadUnsafeSet) SymmetricDifference(other Set) Set {
131         _ = other.(*threadUnsafeSet)
132
133         aDiff := set.Difference(other)
134         bDiff := other.Difference(set)
135         return aDiff.Union(bDiff)
136 }
137
138 func (set *threadUnsafeSet) Clear() {
139         *set = newThreadUnsafeSet()
140 }
141
142 func (set *threadUnsafeSet) Remove(i interface{}) {
143         delete(*set, i)
144 }
145
146 func (set *threadUnsafeSet) Cardinality() int {
147         return len(*set)
148 }
149
150 func (set *threadUnsafeSet) Iter() <-chan interface{} {
151         ch := make(chan interface{})
152         go func() {
153                 for elem := range *set {
154                         ch <- elem
155                 }
156                 close(ch)
157         }()
158
159         return ch
160 }
161
162 func (set *threadUnsafeSet) Equal(other Set) bool {
163         _ = other.(*threadUnsafeSet)
164
165         if set.Cardinality() != other.Cardinality() {
166                 return false
167         }
168         for elem := range *set {
169                 if !other.Contains(elem) {
170                         return false
171                 }
172         }
173         return true
174 }
175
176 func (set *threadUnsafeSet) Clone() Set {
177         clonedSet := newThreadUnsafeSet()
178         for elem := range *set {
179                 clonedSet.Add(elem)
180         }
181         return &clonedSet
182 }
183
184 func (set *threadUnsafeSet) String() string {
185         items := make([]string, 0, len(*set))
186
187         for elem := range *set {
188                 items = append(items, fmt.Sprintf("%v", elem))
189         }
190         return fmt.Sprintf("Set{%s}", strings.Join(items, ", "))
191 }
192
193 func (pair orderedPair) String() string {
194         return fmt.Sprintf("(%v, %v)", pair.first, pair.second)
195 }
196
197 func (set *threadUnsafeSet) PowerSet() Set {
198         powSet := NewThreadUnsafeSet()
199         nullset := newThreadUnsafeSet()
200         powSet.Add(&nullset)
201
202         for es := range *set {
203                 u := newThreadUnsafeSet()
204                 j := powSet.Iter()
205                 for er := range j {
206                         p := newThreadUnsafeSet()
207                         if reflect.TypeOf(er).Name() == "" {
208                                 k := er.(*threadUnsafeSet)
209                                 for ek := range *(k) {
210                                         p.Add(ek)
211                                 }
212                         } else {
213                                 p.Add(er)
214                         }
215                         p.Add(es)
216                         u.Add(&p)
217                 }
218
219                 powSet = powSet.Union(&u)
220         }
221
222         return powSet
223 }
224
225 func (set *threadUnsafeSet) CartesianProduct(other Set) Set {
226         o := other.(*threadUnsafeSet)
227         cartProduct := NewThreadUnsafeSet()
228
229         for i := range *set {
230                 for j := range *o {
231                         elem := orderedPair{first: i, second: j}
232                         cartProduct.Add(elem)
233                 }
234         }
235
236         return cartProduct
237 }
238
239 func (set *threadUnsafeSet) ToSlice() []interface{} {
240         keys := make([]interface{}, 0, set.Cardinality())
241         for elem := range *set {
242                 keys = append(keys, elem)
243         }
244
245         return keys
246 }