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