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 }