github.com/jonasi/terraform@v0.6.10-0.20160125170522-e865c342cc1f/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 // hashcode returns the hashcode used for set elements. 21 func hashcode(v interface{}) interface{} { 22 if h, ok := v.(Hashable); ok { 23 return h.Hashcode() 24 } 25 26 return v 27 } 28 29 // Add adds an item to the set 30 func (s *Set) Add(v interface{}) { 31 s.once.Do(s.init) 32 s.m[hashcode(v)] = v 33 } 34 35 // Delete removes an item from the set. 36 func (s *Set) Delete(v interface{}) { 37 s.once.Do(s.init) 38 delete(s.m, hashcode(v)) 39 } 40 41 // Include returns true/false of whether a value is in the set. 42 func (s *Set) Include(v interface{}) bool { 43 s.once.Do(s.init) 44 _, ok := s.m[hashcode(v)] 45 return ok 46 } 47 48 // Intersection computes the set intersection with other. 49 func (s *Set) Intersection(other *Set) *Set { 50 result := new(Set) 51 if other != nil { 52 for _, v := range s.m { 53 if other.Include(v) { 54 result.Add(v) 55 } 56 } 57 } 58 59 return result 60 } 61 62 // Len is the number of items in the set. 63 func (s *Set) Len() int { 64 if s == nil { 65 return 0 66 } 67 68 return len(s.m) 69 } 70 71 // List returns the list of set elements. 72 func (s *Set) List() []interface{} { 73 if s == nil { 74 return nil 75 } 76 77 r := make([]interface{}, 0, len(s.m)) 78 for _, v := range s.m { 79 r = append(r, v) 80 } 81 82 return r 83 } 84 85 func (s *Set) init() { 86 s.m = make(map[interface{}]interface{}) 87 }