github.com/hashicorp/packer@v1.14.3/internal/dag/set.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package dag
     5  
     6  // Set is a set data structure.
     7  type Set map[interface{}]interface{}
     8  
     9  // Hashable is the interface used by set to get the hash code of a value.
    10  // If this isn't given, then the value of the item being added to the set
    11  // itself is used as the comparison value.
    12  type Hashable interface {
    13  	Hashcode() interface{}
    14  }
    15  
    16  // hashcode returns the hashcode used for set elements.
    17  func hashcode(v interface{}) interface{} {
    18  	if h, ok := v.(Hashable); ok {
    19  		return h.Hashcode()
    20  	}
    21  
    22  	return v
    23  }
    24  
    25  // Add adds an item to the set
    26  func (s Set) Add(v interface{}) {
    27  	s[hashcode(v)] = v
    28  }
    29  
    30  // Delete removes an item from the set.
    31  func (s Set) Delete(v interface{}) {
    32  	delete(s, hashcode(v))
    33  }
    34  
    35  // Include returns true/false of whether a value is in the set.
    36  func (s Set) Include(v interface{}) bool {
    37  	_, ok := s[hashcode(v)]
    38  	return ok
    39  }
    40  
    41  // Intersection computes the set intersection with other.
    42  func (s Set) Intersection(other Set) Set {
    43  	result := make(Set)
    44  	if s == nil || other == nil {
    45  		return result
    46  	}
    47  	// Iteration over a smaller set has better performance.
    48  	if other.Len() < s.Len() {
    49  		s, other = other, s
    50  	}
    51  	for _, v := range s {
    52  		if other.Include(v) {
    53  			result.Add(v)
    54  		}
    55  	}
    56  	return result
    57  }
    58  
    59  // Difference returns a set with the elements that s has but
    60  // other doesn't.
    61  func (s Set) Difference(other Set) Set {
    62  	if other == nil || other.Len() == 0 {
    63  		return s.Copy()
    64  	}
    65  
    66  	result := make(Set)
    67  	for k, v := range s {
    68  		if _, ok := other[k]; !ok {
    69  			result.Add(v)
    70  		}
    71  	}
    72  
    73  	return result
    74  }
    75  
    76  // Filter returns a set that contains the elements from the receiver
    77  // where the given callback returns true.
    78  func (s Set) Filter(cb func(interface{}) bool) Set {
    79  	result := make(Set)
    80  
    81  	for _, v := range s {
    82  		if cb(v) {
    83  			result.Add(v)
    84  		}
    85  	}
    86  
    87  	return result
    88  }
    89  
    90  // Len is the number of items in the set.
    91  func (s Set) Len() int {
    92  	return len(s)
    93  }
    94  
    95  // List returns the list of set elements.
    96  func (s Set) List() []interface{} {
    97  	if s == nil {
    98  		return nil
    99  	}
   100  
   101  	r := make([]interface{}, 0, len(s))
   102  	for _, v := range s {
   103  		r = append(r, v)
   104  	}
   105  
   106  	return r
   107  }
   108  
   109  // Copy returns a shallow copy of the set.
   110  func (s Set) Copy() Set {
   111  	c := make(Set, len(s))
   112  	for k, v := range s {
   113  		c[k] = v
   114  	}
   115  	return c
   116  }