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