github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/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  }