11 "github.com/hashicorp/terraform/helper/hashcode"
14 // HashString hashes strings. If you want a Set of strings, this is the
15 // SchemaSetFunc you want.
16 func HashString(v interface{}) int {
17 return hashcode.String(v.(string))
20 // HashResource hashes complex structures that are described using
21 // a *Resource. This is the default set implementation used when a set's
22 // element type is a full resource.
23 func HashResource(resource *Resource) SchemaSetFunc {
24 return func(v interface{}) int {
26 SerializeResourceForHash(&buf, v, resource)
27 return hashcode.String(buf.String())
31 // HashSchema hashes values that are described using a *Schema. This is the
32 // default set implementation used when a set's element type is a single
34 func HashSchema(schema *Schema) SchemaSetFunc {
35 return func(v interface{}) int {
37 SerializeValueForHash(&buf, v, schema)
38 return hashcode.String(buf.String())
42 // Set is a set data structure that is returned for elements of type
47 m map[string]interface{}
51 // NewSet is a convenience method for creating a new set with the given
53 func NewSet(f SchemaSetFunc, items []interface{}) *Set {
55 for _, i := range items {
62 // CopySet returns a copy of another set.
63 func CopySet(otherSet *Set) *Set {
64 return NewSet(otherSet.F, otherSet.List())
67 // Add adds an item to the set if it isn't already in the set.
68 func (s *Set) Add(item interface{}) {
72 // Remove removes an item if it's already in the set. Idempotent.
73 func (s *Set) Remove(item interface{}) {
77 // Contains checks if the set has the given item.
78 func (s *Set) Contains(item interface{}) bool {
79 _, ok := s.m[s.hash(item)]
83 // Len returns the amount of items in the set.
84 func (s *Set) Len() int {
88 // List returns the elements of this set in slice format.
90 // The order of the returned elements is deterministic. Given the same
91 // set, the order of this will always be the same.
92 func (s *Set) List() []interface{} {
93 result := make([]interface{}, len(s.m))
94 for i, k := range s.listCode() {
101 // Difference performs a set difference of the two sets, returning
102 // a new third set that has only the elements unique to this set.
103 func (s *Set) Difference(other *Set) *Set {
104 result := &Set{F: s.F}
105 result.once.Do(result.init)
107 for k, v := range s.m {
108 if _, ok := other.m[k]; !ok {
116 // Intersection performs the set intersection of the two sets
117 // and returns a new third set.
118 func (s *Set) Intersection(other *Set) *Set {
119 result := &Set{F: s.F}
120 result.once.Do(result.init)
122 for k, v := range s.m {
123 if _, ok := other.m[k]; ok {
131 // Union performs the set union of the two sets and returns a new third
133 func (s *Set) Union(other *Set) *Set {
134 result := &Set{F: s.F}
135 result.once.Do(result.init)
137 for k, v := range s.m {
140 for k, v := range other.m {
147 func (s *Set) Equal(raw interface{}) bool {
148 other, ok := raw.(*Set)
153 return reflect.DeepEqual(s.m, other.m)
156 func (s *Set) GoString() string {
157 return fmt.Sprintf("*Set(%#v)", s.m)
160 func (s *Set) init() {
161 s.m = make(map[string]interface{})
164 func (s *Set) add(item interface{}, computed bool) string {
172 if _, ok := s.m[code]; !ok {
179 func (s *Set) hash(item interface{}) string {
181 // Always return a nonnegative hashcode.
185 return strconv.Itoa(code)
188 func (s *Set) remove(item interface{}) string {
197 func (s *Set) index(item interface{}) int {
198 return sort.SearchStrings(s.listCode(), s.hash(item))
201 func (s *Set) listCode() []string {
202 // Sort the hash codes so the order of the list is deterministic
203 keys := make([]string, 0, len(s.m))
205 keys = append(keys, k)
207 sort.Sort(sort.StringSlice(keys))