github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/helper/schema/set.go (about) 1 package schema 2 3 import ( 4 "fmt" 5 "reflect" 6 "sort" 7 "sync" 8 ) 9 10 // Set is a set data structure that is returned for elements of type 11 // TypeSet. 12 type Set struct { 13 F SchemaSetFunc 14 15 m map[int]interface{} 16 once sync.Once 17 } 18 19 // NewSet is a convenience method for creating a new set with the given 20 // items. 21 func NewSet(f SchemaSetFunc, items []interface{}) *Set { 22 s := &Set{F: f} 23 for _, i := range items { 24 s.Add(i) 25 } 26 27 return s 28 } 29 30 // Add adds an item to the set if it isn't already in the set. 31 func (s *Set) Add(item interface{}) { 32 s.add(item) 33 } 34 35 // Contains checks if the set has the given item. 36 func (s *Set) Contains(item interface{}) bool { 37 _, ok := s.m[s.F(item)] 38 return ok 39 } 40 41 // Len returns the amount of items in the set. 42 func (s *Set) Len() int { 43 return len(s.m) 44 } 45 46 // List returns the elements of this set in slice format. 47 // 48 // The order of the returned elements is deterministic. Given the same 49 // set, the order of this will always be the same. 50 func (s *Set) List() []interface{} { 51 result := make([]interface{}, len(s.m)) 52 for i, k := range s.listCode() { 53 result[i] = s.m[k] 54 } 55 56 return result 57 } 58 59 // Differences performs a set difference of the two sets, returning 60 // a new third set that has only the elements unique to this set. 61 func (s *Set) Difference(other *Set) *Set { 62 result := &Set{F: s.F} 63 result.once.Do(result.init) 64 65 for k, v := range s.m { 66 if _, ok := other.m[k]; !ok { 67 result.m[k] = v 68 } 69 } 70 71 return result 72 } 73 74 // Intersection performs the set intersection of the two sets 75 // and returns a new third set. 76 func (s *Set) Intersection(other *Set) *Set { 77 result := &Set{F: s.F} 78 result.once.Do(result.init) 79 80 for k, v := range s.m { 81 if _, ok := other.m[k]; ok { 82 result.m[k] = v 83 } 84 } 85 86 return result 87 } 88 89 // Union performs the set union of the two sets and returns a new third 90 // set. 91 func (s *Set) Union(other *Set) *Set { 92 result := &Set{F: s.F} 93 result.once.Do(result.init) 94 95 for k, v := range s.m { 96 result.m[k] = v 97 } 98 for k, v := range other.m { 99 result.m[k] = v 100 } 101 102 return result 103 } 104 105 func (s *Set) Equal(raw interface{}) bool { 106 other, ok := raw.(*Set) 107 if !ok { 108 return false 109 } 110 111 return reflect.DeepEqual(s.m, other.m) 112 } 113 114 func (s *Set) GoString() string { 115 return fmt.Sprintf("*Set(%#v)", s.m) 116 } 117 118 func (s *Set) init() { 119 s.m = make(map[int]interface{}) 120 } 121 122 func (s *Set) add(item interface{}) int { 123 s.once.Do(s.init) 124 125 code := s.F(item) 126 if _, ok := s.m[code]; !ok { 127 s.m[code] = item 128 } 129 130 return code 131 } 132 133 func (s *Set) index(item interface{}) int { 134 return sort.SearchInts(s.listCode(), s.F(item)) 135 } 136 137 func (s *Set) listCode() []int { 138 // Sort the hash codes so the order of the list is deterministic 139 keys := make([]int, 0, len(s.m)) 140 for k, _ := range s.m { 141 keys = append(keys, k) 142 } 143 sort.Sort(sort.IntSlice(keys)) 144 return keys 145 }