github.com/nicgrayson/terraform@v0.4.3-0.20150415203910-c4de50829380/helper/schema/set.go (about)

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