diff options
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/set')
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/set/gob.go | 76 | ||||
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/set/iterator.go | 36 | ||||
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/set/ops.go | 199 | ||||
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/set/rules.go | 25 | ||||
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/set/set.go | 62 |
5 files changed, 398 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/gob.go b/vendor/github.com/zclconf/go-cty/cty/set/gob.go new file mode 100644 index 0000000..da2978f --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/set/gob.go | |||
@@ -0,0 +1,76 @@ | |||
1 | package set | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "encoding/gob" | ||
6 | "fmt" | ||
7 | ) | ||
8 | |||
9 | // GobEncode is an implementation of the interface gob.GobEncoder, allowing | ||
10 | // sets to be included in structures encoded via gob. | ||
11 | // | ||
12 | // The set rules are included in the serialized value, so the caller must | ||
13 | // register its concrete rules type with gob.Register before using a | ||
14 | // set in a gob, and possibly also implement GobEncode/GobDecode to customize | ||
15 | // how any parameters are persisted. | ||
16 | // | ||
17 | // The set elements are also included, so if they are of non-primitive types | ||
18 | // they too must be registered with gob. | ||
19 | // | ||
20 | // If the produced gob values will persist for a long time, the caller must | ||
21 | // ensure compatibility of the rules implementation. In particular, if the | ||
22 | // definition of element equivalence changes between encoding and decoding | ||
23 | // then two distinct stored elements may be considered equivalent on decoding, | ||
24 | // causing the recovered set to have fewer elements than when it was stored. | ||
25 | func (s Set) GobEncode() ([]byte, error) { | ||
26 | gs := gobSet{ | ||
27 | Version: 0, | ||
28 | Rules: s.rules, | ||
29 | Values: s.Values(), | ||
30 | } | ||
31 | |||
32 | buf := &bytes.Buffer{} | ||
33 | enc := gob.NewEncoder(buf) | ||
34 | err := enc.Encode(gs) | ||
35 | if err != nil { | ||
36 | return nil, fmt.Errorf("error encoding set.Set: %s", err) | ||
37 | } | ||
38 | |||
39 | return buf.Bytes(), nil | ||
40 | } | ||
41 | |||
42 | // GobDecode is the opposite of GobEncode. See GobEncode for information | ||
43 | // on the requirements for and caveats of including set values in gobs. | ||
44 | func (s *Set) GobDecode(buf []byte) error { | ||
45 | r := bytes.NewReader(buf) | ||
46 | dec := gob.NewDecoder(r) | ||
47 | |||
48 | var gs gobSet | ||
49 | err := dec.Decode(&gs) | ||
50 | if err != nil { | ||
51 | return fmt.Errorf("error decoding set.Set: %s", err) | ||
52 | } | ||
53 | if gs.Version != 0 { | ||
54 | return fmt.Errorf("unsupported set.Set encoding version %d; need 0", gs.Version) | ||
55 | } | ||
56 | |||
57 | victim := NewSetFromSlice(gs.Rules, gs.Values) | ||
58 | s.vals = victim.vals | ||
59 | s.rules = victim.rules | ||
60 | return nil | ||
61 | } | ||
62 | |||
63 | type gobSet struct { | ||
64 | Version int | ||
65 | Rules Rules | ||
66 | |||
67 | // The bucket-based representation is for efficient in-memory access, but | ||
68 | // for serialization it's enough to just retain the values themselves, | ||
69 | // which we can re-bucket using the rules (which may have changed!) when | ||
70 | // we re-inflate. | ||
71 | Values []interface{} | ||
72 | } | ||
73 | |||
74 | func init() { | ||
75 | gob.Register([]interface{}(nil)) | ||
76 | } | ||
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/iterator.go b/vendor/github.com/zclconf/go-cty/cty/set/iterator.go new file mode 100644 index 0000000..f15498e --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/set/iterator.go | |||
@@ -0,0 +1,36 @@ | |||
1 | package set | ||
2 | |||
3 | type Iterator struct { | ||
4 | bucketIds []int | ||
5 | vals map[int][]interface{} | ||
6 | bucketIdx int | ||
7 | valIdx int | ||
8 | } | ||
9 | |||
10 | func (it *Iterator) Value() interface{} { | ||
11 | return it.currentBucket()[it.valIdx] | ||
12 | } | ||
13 | |||
14 | func (it *Iterator) Next() bool { | ||
15 | if it.bucketIdx == -1 { | ||
16 | // init | ||
17 | if len(it.bucketIds) == 0 { | ||
18 | return false | ||
19 | } | ||
20 | |||
21 | it.valIdx = 0 | ||
22 | it.bucketIdx = 0 | ||
23 | return true | ||
24 | } | ||
25 | |||
26 | it.valIdx++ | ||
27 | if it.valIdx >= len(it.currentBucket()) { | ||
28 | it.valIdx = 0 | ||
29 | it.bucketIdx++ | ||
30 | } | ||
31 | return it.bucketIdx < len(it.bucketIds) | ||
32 | } | ||
33 | |||
34 | func (it *Iterator) currentBucket() []interface{} { | ||
35 | return it.vals[it.bucketIds[it.bucketIdx]] | ||
36 | } | ||
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/ops.go b/vendor/github.com/zclconf/go-cty/cty/set/ops.go new file mode 100644 index 0000000..726e707 --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/set/ops.go | |||
@@ -0,0 +1,199 @@ | |||
1 | package set | ||
2 | |||
3 | import ( | ||
4 | "sort" | ||
5 | ) | ||
6 | |||
7 | // Add inserts the given value into the receiving Set. | ||
8 | // | ||
9 | // This mutates the set in-place. This operation is not thread-safe. | ||
10 | func (s Set) Add(val interface{}) { | ||
11 | hv := s.rules.Hash(val) | ||
12 | if _, ok := s.vals[hv]; !ok { | ||
13 | s.vals[hv] = make([]interface{}, 0, 1) | ||
14 | } | ||
15 | bucket := s.vals[hv] | ||
16 | |||
17 | // See if an equivalent value is already present | ||
18 | for _, ev := range bucket { | ||
19 | if s.rules.Equivalent(val, ev) { | ||
20 | return | ||
21 | } | ||
22 | } | ||
23 | |||
24 | s.vals[hv] = append(bucket, val) | ||
25 | } | ||
26 | |||
27 | // Remove deletes the given value from the receiving set, if indeed it was | ||
28 | // there in the first place. If the value is not present, this is a no-op. | ||
29 | func (s Set) Remove(val interface{}) { | ||
30 | hv := s.rules.Hash(val) | ||
31 | bucket, ok := s.vals[hv] | ||
32 | if !ok { | ||
33 | return | ||
34 | } | ||
35 | |||
36 | for i, ev := range bucket { | ||
37 | if s.rules.Equivalent(val, ev) { | ||
38 | newBucket := make([]interface{}, 0, len(bucket)-1) | ||
39 | newBucket = append(newBucket, bucket[:i]...) | ||
40 | newBucket = append(newBucket, bucket[i+1:]...) | ||
41 | if len(newBucket) > 0 { | ||
42 | s.vals[hv] = newBucket | ||
43 | } else { | ||
44 | delete(s.vals, hv) | ||
45 | } | ||
46 | return | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | // Has returns true if the given value is in the receiving set, or false if | ||
52 | // it is not. | ||
53 | func (s Set) Has(val interface{}) bool { | ||
54 | hv := s.rules.Hash(val) | ||
55 | bucket, ok := s.vals[hv] | ||
56 | if !ok { | ||
57 | return false | ||
58 | } | ||
59 | |||
60 | for _, ev := range bucket { | ||
61 | if s.rules.Equivalent(val, ev) { | ||
62 | return true | ||
63 | } | ||
64 | } | ||
65 | return false | ||
66 | } | ||
67 | |||
68 | // Copy performs a shallow copy of the receiving set, returning a new set | ||
69 | // with the same rules and elements. | ||
70 | func (s Set) Copy() Set { | ||
71 | ret := NewSet(s.rules) | ||
72 | for k, v := range s.vals { | ||
73 | ret.vals[k] = v | ||
74 | } | ||
75 | return ret | ||
76 | } | ||
77 | |||
78 | // Iterator returns an iterator over values in the set, in an undefined order | ||
79 | // that callers should not depend on. | ||
80 | // | ||
81 | // The pattern for using the returned iterator is: | ||
82 | // | ||
83 | // it := set.Iterator() | ||
84 | // for it.Next() { | ||
85 | // val := it.Value() | ||
86 | // // ... | ||
87 | // } | ||
88 | // | ||
89 | // Once an iterator has been created for a set, the set *must not* be mutated | ||
90 | // until the iterator is no longer in use. | ||
91 | func (s Set) Iterator() *Iterator { | ||
92 | // Sort the bucketIds to ensure that we always traverse in a | ||
93 | // consistent order. | ||
94 | bucketIds := make([]int, 0, len(s.vals)) | ||
95 | for id := range s.vals { | ||
96 | bucketIds = append(bucketIds, id) | ||
97 | } | ||
98 | sort.Ints(bucketIds) | ||
99 | |||
100 | return &Iterator{ | ||
101 | bucketIds: bucketIds, | ||
102 | vals: s.vals, | ||
103 | bucketIdx: -1, | ||
104 | } | ||
105 | } | ||
106 | |||
107 | // EachValue calls the given callback once for each value in the set, in an | ||
108 | // undefined order that callers should not depend on. | ||
109 | func (s Set) EachValue(cb func(interface{})) { | ||
110 | it := s.Iterator() | ||
111 | for it.Next() { | ||
112 | cb(it.Value()) | ||
113 | } | ||
114 | } | ||
115 | |||
116 | // Values returns a slice of all of the values in the set in no particular | ||
117 | // order. This is just a wrapper around EachValue that accumulates the results | ||
118 | // in a slice for caller convenience. | ||
119 | // | ||
120 | // The returned slice will be nil if there are no values in the set. | ||
121 | func (s Set) Values() []interface{} { | ||
122 | var ret []interface{} | ||
123 | s.EachValue(func(v interface{}) { | ||
124 | ret = append(ret, v) | ||
125 | }) | ||
126 | return ret | ||
127 | } | ||
128 | |||
129 | // Length returns the number of values in the set. | ||
130 | func (s Set) Length() int { | ||
131 | var count int | ||
132 | for _, bucket := range s.vals { | ||
133 | count = count + len(bucket) | ||
134 | } | ||
135 | return count | ||
136 | } | ||
137 | |||
138 | // Union returns a new set that contains all of the members of both the | ||
139 | // receiving set and the given set. Both sets must have the same rules, or | ||
140 | // else this function will panic. | ||
141 | func (s1 Set) Union(s2 Set) Set { | ||
142 | mustHaveSameRules(s1, s2) | ||
143 | rs := NewSet(s1.rules) | ||
144 | s1.EachValue(func(v interface{}) { | ||
145 | rs.Add(v) | ||
146 | }) | ||
147 | s2.EachValue(func(v interface{}) { | ||
148 | rs.Add(v) | ||
149 | }) | ||
150 | return rs | ||
151 | } | ||
152 | |||
153 | // Intersection returns a new set that contains the values that both the | ||
154 | // receiver and given sets have in common. Both sets must have the same rules, | ||
155 | // or else this function will panic. | ||
156 | func (s1 Set) Intersection(s2 Set) Set { | ||
157 | mustHaveSameRules(s1, s2) | ||
158 | rs := NewSet(s1.rules) | ||
159 | s1.EachValue(func(v interface{}) { | ||
160 | if s2.Has(v) { | ||
161 | rs.Add(v) | ||
162 | } | ||
163 | }) | ||
164 | return rs | ||
165 | } | ||
166 | |||
167 | // Subtract returns a new set that contains all of the values from the receiver | ||
168 | // that are not also in the given set. Both sets must have the same rules, | ||
169 | // or else this function will panic. | ||
170 | func (s1 Set) Subtract(s2 Set) Set { | ||
171 | mustHaveSameRules(s1, s2) | ||
172 | rs := NewSet(s1.rules) | ||
173 | s1.EachValue(func(v interface{}) { | ||
174 | if !s2.Has(v) { | ||
175 | rs.Add(v) | ||
176 | } | ||
177 | }) | ||
178 | return rs | ||
179 | } | ||
180 | |||
181 | // SymmetricDifference returns a new set that contains all of the values from | ||
182 | // both the receiver and given sets, except those that both sets have in | ||
183 | // common. Both sets must have the same rules, or else this function will | ||
184 | // panic. | ||
185 | func (s1 Set) SymmetricDifference(s2 Set) Set { | ||
186 | mustHaveSameRules(s1, s2) | ||
187 | rs := NewSet(s1.rules) | ||
188 | s1.EachValue(func(v interface{}) { | ||
189 | if !s2.Has(v) { | ||
190 | rs.Add(v) | ||
191 | } | ||
192 | }) | ||
193 | s2.EachValue(func(v interface{}) { | ||
194 | if !s1.Has(v) { | ||
195 | rs.Add(v) | ||
196 | } | ||
197 | }) | ||
198 | return rs | ||
199 | } | ||
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/rules.go b/vendor/github.com/zclconf/go-cty/cty/set/rules.go new file mode 100644 index 0000000..7200184 --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/set/rules.go | |||
@@ -0,0 +1,25 @@ | |||
1 | package set | ||
2 | |||
3 | // Rules represents the operations that define membership for a Set. | ||
4 | // | ||
5 | // Each Set has a Rules instance, whose methods must satisfy the interface | ||
6 | // contracts given below for any value that will be added to the set. | ||
7 | type Rules interface { | ||
8 | // Hash returns an int that somewhat-uniquely identifies the given value. | ||
9 | // | ||
10 | // A good hash function will minimize collisions for values that will be | ||
11 | // added to the set, though collisions *are* permitted. Collisions will | ||
12 | // simply reduce the efficiency of operations on the set. | ||
13 | Hash(interface{}) int | ||
14 | |||
15 | // Equivalent returns true if and only if the two values are considered | ||
16 | // equivalent for the sake of set membership. Two values that are | ||
17 | // equivalent cannot exist in the set at the same time, and if two | ||
18 | // equivalent values are added it is undefined which one will be | ||
19 | // returned when enumerating all of the set members. | ||
20 | // | ||
21 | // Two values that are equivalent *must* result in the same hash value, | ||
22 | // though it is *not* required that two values with the same hash value | ||
23 | // be equivalent. | ||
24 | Equivalent(interface{}, interface{}) bool | ||
25 | } | ||
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/set.go b/vendor/github.com/zclconf/go-cty/cty/set/set.go new file mode 100644 index 0000000..b4fb316 --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/set/set.go | |||
@@ -0,0 +1,62 @@ | |||
1 | package set | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | ) | ||
6 | |||
7 | // Set is an implementation of the concept of a set: a collection where all | ||
8 | // values are conceptually either in or out of the set, but the members are | ||
9 | // not ordered. | ||
10 | // | ||
11 | // This type primarily exists to be the internal type of sets in cty, but | ||
12 | // it is considered to be at the same level of abstraction as Go's built in | ||
13 | // slice and map collection types, and so should make no cty-specific | ||
14 | // assumptions. | ||
15 | // | ||
16 | // Set operations are not thread safe. It is the caller's responsibility to | ||
17 | // provide mutex guarantees where necessary. | ||
18 | // | ||
19 | // Set operations are not optimized to minimize memory pressure. Mutating | ||
20 | // a set will generally create garbage and so should perhaps be avoided in | ||
21 | // tight loops where memory pressure is a concern. | ||
22 | type Set struct { | ||
23 | vals map[int][]interface{} | ||
24 | rules Rules | ||
25 | } | ||
26 | |||
27 | // NewSet returns an empty set with the membership rules given. | ||
28 | func NewSet(rules Rules) Set { | ||
29 | return Set{ | ||
30 | vals: map[int][]interface{}{}, | ||
31 | rules: rules, | ||
32 | } | ||
33 | } | ||
34 | |||
35 | func NewSetFromSlice(rules Rules, vals []interface{}) Set { | ||
36 | s := NewSet(rules) | ||
37 | for _, v := range vals { | ||
38 | s.Add(v) | ||
39 | } | ||
40 | return s | ||
41 | } | ||
42 | |||
43 | func sameRules(s1 Set, s2 Set) bool { | ||
44 | return s1.rules == s2.rules | ||
45 | } | ||
46 | |||
47 | func mustHaveSameRules(s1 Set, s2 Set) { | ||
48 | if !sameRules(s1, s2) { | ||
49 | panic(fmt.Errorf("incompatible set rules: %#v, %#v", s1.rules, s2.rules)) | ||
50 | } | ||
51 | } | ||
52 | |||
53 | // HasRules returns true if and only if the receiving set has the given rules | ||
54 | // instance as its rules. | ||
55 | func (s Set) HasRules(rules Rules) bool { | ||
56 | return s.rules == rules | ||
57 | } | ||
58 | |||
59 | // Rules returns the receiving set's rules instance. | ||
60 | func (s Set) Rules() Rules { | ||
61 | return s.rules | ||
62 | } | ||