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  }