opentofu/internal/dag/set.go
Martin Atkins 70eebe3521 Move dag/ to internal/dag/
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.

If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
2021-05-17 14:09:07 -07:00

114 lines
2.2 KiB
Go

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
}