github.com/chalford/terraform@v0.3.7-0.20150113080010-a78c69a8c81f/helper/schema/set.go (about)

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