github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/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  }