github.com/armen/terraform@v0.5.2-0.20150529052519-caa8117a08f1/dag/set.go (about) 1 package dag 2 3 import ( 4 "sync" 5 ) 6 7 // Set is a set data structure. 8 type Set struct { 9 m map[interface{}]interface{} 10 once sync.Once 11 } 12 13 // Hashable is the interface used by set to get the hash code of a value. 14 // If this isn't given, then the value of the item being added to the set 15 // itself is used as the comparison value. 16 type Hashable interface { 17 Hashcode() interface{} 18 } 19 20 // Add adds an item to the set 21 func (s *Set) Add(v interface{}) { 22 s.once.Do(s.init) 23 s.m[s.code(v)] = v 24 } 25 26 // Delete removes an item from the set. 27 func (s *Set) Delete(v interface{}) { 28 s.once.Do(s.init) 29 delete(s.m, s.code(v)) 30 } 31 32 // Include returns true/false of whether a value is in the set. 33 func (s *Set) Include(v interface{}) bool { 34 s.once.Do(s.init) 35 _, ok := s.m[s.code(v)] 36 return ok 37 } 38 39 // Intersection computes the set intersection with other. 40 func (s *Set) Intersection(other *Set) *Set { 41 result := new(Set) 42 if other != nil { 43 for _, v := range s.m { 44 if other.Include(v) { 45 result.Add(v) 46 } 47 } 48 } 49 50 return result 51 } 52 53 // Len is the number of items in the set. 54 func (s *Set) Len() int { 55 if s == nil { 56 return 0 57 } 58 59 return len(s.m) 60 } 61 62 // List returns the list of set elements. 63 func (s *Set) List() []interface{} { 64 if s == nil { 65 return nil 66 } 67 68 r := make([]interface{}, 0, len(s.m)) 69 for _, v := range s.m { 70 r = append(r, v) 71 } 72 73 return r 74 } 75 76 func (s *Set) code(v interface{}) interface{} { 77 if h, ok := v.(Hashable); ok { 78 return h.Hashcode() 79 } 80 81 return v 82 } 83 84 func (s *Set) init() { 85 s.m = make(map[interface{}]interface{}) 86 }