mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 01:41:48 -06:00
70eebe3521
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.
114 lines
2.2 KiB
Go
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
|
|
}
|