mirror of
https://github.com/hashicorp/packer.git
synced 2026-06-09 16:50:08 -04:00
The dag package is a port over from Terraform to Packer, changing what little there was to fit our current dependency ecosystem. Most of the changes are on the type of diagnostics returned, as Terraform has its own type for them, while we rely on hcl's Diagnostics. Other than that, the functionality is essentially equivalent, and the code was barely touched.
116 lines
2.2 KiB
Go
116 lines
2.2 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package dag
|
|
|
|
// Set is a set data structure.
|
|
type Set map[interface{}]interface{}
|
|
|
|
// Hashable is the interface used by set to get the hash code of a value.
|
|
// If this isn't given, then the value of the item being added to the set
|
|
// itself is used as the comparison value.
|
|
type Hashable interface {
|
|
Hashcode() interface{}
|
|
}
|
|
|
|
// hashcode returns the hashcode used for set elements.
|
|
func hashcode(v interface{}) interface{} {
|
|
if h, ok := v.(Hashable); ok {
|
|
return h.Hashcode()
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
// Add adds an item to the set
|
|
func (s Set) Add(v interface{}) {
|
|
s[hashcode(v)] = v
|
|
}
|
|
|
|
// Delete removes an item from the set.
|
|
func (s Set) Delete(v interface{}) {
|
|
delete(s, hashcode(v))
|
|
}
|
|
|
|
// Include returns true/false of whether a value is in the set.
|
|
func (s Set) Include(v interface{}) bool {
|
|
_, ok := s[hashcode(v)]
|
|
return ok
|
|
}
|
|
|
|
// Intersection computes the set intersection with other.
|
|
func (s Set) Intersection(other Set) Set {
|
|
result := make(Set)
|
|
if s == nil || other == nil {
|
|
return result
|
|
}
|
|
// Iteration over a smaller set has better performance.
|
|
if other.Len() < s.Len() {
|
|
s, other = other, s
|
|
}
|
|
for _, v := range s {
|
|
if other.Include(v) {
|
|
result.Add(v)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// Difference returns a set with the elements that s has but
|
|
// other doesn't.
|
|
func (s Set) Difference(other Set) Set {
|
|
if other == nil || other.Len() == 0 {
|
|
return s.Copy()
|
|
}
|
|
|
|
result := make(Set)
|
|
for k, v := range s {
|
|
if _, ok := other[k]; !ok {
|
|
result.Add(v)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// Filter returns a set that contains the elements from the receiver
|
|
// where the given callback returns true.
|
|
func (s Set) Filter(cb func(interface{}) bool) Set {
|
|
result := make(Set)
|
|
|
|
for _, v := range s {
|
|
if cb(v) {
|
|
result.Add(v)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// Len is the number of items in the set.
|
|
func (s Set) Len() int {
|
|
return len(s)
|
|
}
|
|
|
|
// List returns the list of set elements.
|
|
func (s Set) List() []interface{} {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
|
|
r := make([]interface{}, 0, len(s))
|
|
for _, v := range s {
|
|
r = append(r, v)
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
// Copy returns a shallow copy of the set.
|
|
func (s Set) Copy() Set {
|
|
c := make(Set, len(s))
|
|
for k, v := range s {
|
|
c[k] = v
|
|
}
|
|
return c
|
|
}
|