github.com/lamielle/terraform@v0.3.2-0.20141121070651-81f008ba53d5/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  // NewSet is a convenience method for creating a new set with the given
    18  // items.
    19  func NewSet(f SchemaSetFunc, items []interface{}) *Set {
    20  	s := &Set{F: f}
    21  	for _, i := range items {
    22  		s.Add(i)
    23  	}
    24  
    25  	return s
    26  }
    27  
    28  // Add adds an item to the set if it isn't already in the set.
    29  func (s *Set) Add(item interface{}) {
    30  	s.add(item)
    31  }
    32  
    33  // Contains checks if the set has the given item.
    34  func (s *Set) Contains(item interface{}) bool {
    35  	_, ok := s.m[s.F(item)]
    36  	return ok
    37  }
    38  
    39  // Len returns the amount of items in the set.
    40  func (s *Set) Len() int {
    41  	return len(s.m)
    42  }
    43  
    44  // List returns the elements of this set in slice format.
    45  //
    46  // The order of the returned elements is deterministic. Given the same
    47  // set, the order of this will always be the same.
    48  func (s *Set) List() []interface{} {
    49  	result := make([]interface{}, len(s.m))
    50  	for i, k := range s.listCode() {
    51  		result[i] = s.m[k]
    52  	}
    53  
    54  	return result
    55  }
    56  
    57  // Differences performs a set difference of the two sets, returning
    58  // a new third set that has only the elements unique to this set.
    59  func (s *Set) Difference(other *Set) *Set {
    60  	result := &Set{F: s.F}
    61  	result.init()
    62  
    63  	for k, v := range s.m {
    64  		if _, ok := other.m[k]; !ok {
    65  			result.m[k] = v
    66  		}
    67  	}
    68  
    69  	return result
    70  }
    71  
    72  // Intersection performs the set intersection of the two sets
    73  // and returns a new third set.
    74  func (s *Set) Intersection(other *Set) *Set {
    75  	result := &Set{F: s.F}
    76  	result.init()
    77  
    78  	for k, v := range s.m {
    79  		if _, ok := other.m[k]; ok {
    80  			result.m[k] = v
    81  		}
    82  	}
    83  
    84  	return result
    85  }
    86  
    87  // Union performs the set union of the two sets and returns a new third
    88  // set.
    89  func (s *Set) Union(other *Set) *Set {
    90  	result := &Set{F: s.F}
    91  	result.init()
    92  
    93  	for k, v := range s.m {
    94  		result.m[k] = v
    95  	}
    96  	for k, v := range other.m {
    97  		result.m[k] = v
    98  	}
    99  
   100  	return result
   101  }
   102  
   103  func (s *Set) init() {
   104  	s.m = make(map[int]interface{})
   105  }
   106  
   107  func (s *Set) add(item interface{}) int {
   108  	s.once.Do(s.init)
   109  
   110  	code := s.F(item)
   111  	if _, ok := s.m[code]; !ok {
   112  		s.m[code] = item
   113  	}
   114  
   115  	return code
   116  }
   117  
   118  func (s *Set) index(item interface{}) int {
   119  	return sort.SearchInts(s.listCode(), s.F(item))
   120  }
   121  
   122  func (s *Set) listCode() []int {
   123  	// Sort the hash codes so the order of the list is deterministic
   124  	keys := make([]int, 0, len(s.m))
   125  	for k, _ := range s.m {
   126  		keys = append(keys, k)
   127  	}
   128  	sort.Sort(sort.IntSlice(keys))
   129  	return keys
   130  }