mirror of
https://github.com/mcuadros/ascode
synced 2024-11-23 01:11:59 +01:00
starlark/types: Values O(1)
Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
This commit is contained in:
parent
8f414b66be
commit
4ea887a849
@ -3,7 +3,6 @@ package types
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/configs/configschema"
|
||||
@ -38,7 +37,7 @@ type Resource struct {
|
||||
typ string
|
||||
kind Kind
|
||||
block *configschema.Block
|
||||
values Values
|
||||
values *Values
|
||||
|
||||
parent *Resource
|
||||
dependenies []*Resource
|
||||
@ -53,6 +52,7 @@ func MakeResource(name, typ string, k Kind, b *configschema.Block, parent *Resou
|
||||
typ: typ,
|
||||
kind: k,
|
||||
block: b,
|
||||
values: NewValues(),
|
||||
parent: parent,
|
||||
}
|
||||
}
|
||||
@ -222,22 +222,22 @@ func (r *Resource) setFieldFromNestedBlock(name string, b *configschema.NestedBl
|
||||
}
|
||||
|
||||
func (r *Resource) toDict() *starlark.Dict {
|
||||
sort.Sort(r.values)
|
||||
d := starlark.NewDict(len(r.values))
|
||||
d := starlark.NewDict(r.values.Len())
|
||||
|
||||
for _, e := range r.values {
|
||||
r.values.ForEach(func(e *NamedValue) error {
|
||||
if r, ok := e.Starlark().(*Resource); ok {
|
||||
d.SetKey(starlark.String(e.Name), r.toDict())
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
if r, ok := e.Starlark().(*ResourceCollection); ok {
|
||||
d.SetKey(starlark.String(e.Name), r.toDict())
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
d.SetKey(starlark.String(e.Name), e.Starlark())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return d
|
||||
}
|
||||
@ -296,11 +296,11 @@ func (x *Resource) doCompareSameType(y *Resource, depth int) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(x.values) != len(y.values) {
|
||||
if x.values.Len() != y.values.Len() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, xval := range x.values {
|
||||
for _, xval := range x.values.List() {
|
||||
yval := y.values.Get(xval.Name)
|
||||
if yval == nil {
|
||||
return false, nil
|
||||
|
@ -119,6 +119,7 @@ func (v *Value) Interface() interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// Hash honors the starlark.Value interface.
|
||||
func (v *Value) Hash() (uint32, error) {
|
||||
switch value := v.v.(type) {
|
||||
case *starlark.List:
|
||||
@ -145,32 +146,39 @@ type NamedValue struct {
|
||||
}
|
||||
|
||||
// Values is a list of NamedValues.
|
||||
type Values []*NamedValue
|
||||
type Values struct {
|
||||
names sort.StringSlice
|
||||
values map[string]*NamedValue
|
||||
}
|
||||
|
||||
// NewValues return a new instance of Values
|
||||
func NewValues() *Values {
|
||||
return &Values{values: make(map[string]*NamedValue)}
|
||||
}
|
||||
|
||||
// Set sets a name and a value and returns it as a NamedValue.
|
||||
func (a *Values) Set(name string, v *Value) *NamedValue {
|
||||
e := a.Get(name)
|
||||
if e != nil {
|
||||
if e, ok := a.values[name]; ok {
|
||||
e.Value = v
|
||||
return e
|
||||
}
|
||||
|
||||
e = &NamedValue{Name: name, Value: v}
|
||||
*a = append(*a, e)
|
||||
e := &NamedValue{Name: name, Value: v}
|
||||
a.values[name] = e
|
||||
a.names = append(a.names, name)
|
||||
return e
|
||||
}
|
||||
|
||||
// Has returns true if Values contains a NamedValue with this name.
|
||||
func (a Values) Has(name string) bool {
|
||||
return a.Get(name) != nil
|
||||
_, ok := a.values[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Get returns the NamedValue with the given name, if any.
|
||||
func (a Values) Get(name string) *NamedValue {
|
||||
for _, e := range a {
|
||||
if e.Name == name {
|
||||
return e
|
||||
}
|
||||
if e, ok := a.values[name]; ok {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -203,18 +211,19 @@ func (a Values) Hash() (uint32, error) {
|
||||
|
||||
// ToStringDict adds a name/value entry to d for each field of the struct.
|
||||
func (a Values) ToStringDict(d starlark.StringDict) {
|
||||
for _, e := range a {
|
||||
d[e.Name] = e.Starlark()
|
||||
sort.Sort(a.names) // we sort the list before hash it.
|
||||
for _, name := range a.names {
|
||||
d[name] = a.values[name].Starlark()
|
||||
}
|
||||
}
|
||||
|
||||
// ForEach call cb for each value on Values, it stop the iteration an error
|
||||
// is returned.
|
||||
func (a Values) ForEach(cb func(*NamedValue) error) error {
|
||||
sort.Sort(a) // we sort the list before hash it.
|
||||
sort.Sort(a.names) // we sort the list before hash it.
|
||||
|
||||
for _, v := range a {
|
||||
if err := cb(v); err != nil {
|
||||
for _, name := range a.names {
|
||||
if err := cb(a.values[name]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -222,6 +231,19 @@ func (a Values) ForEach(cb func(*NamedValue) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a Values) Len() int { return len(a) }
|
||||
func (a Values) Less(i, j int) bool { return a[i].Name < a[j].Name }
|
||||
func (a Values) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
// List return a list of NamedValues sorted by name.
|
||||
func (a Values) List() []*NamedValue {
|
||||
sort.Sort(a.names) // we sort the list before hash it.
|
||||
|
||||
list := make([]*NamedValue, len(a.names))
|
||||
for i, name := range a.names {
|
||||
list[i] = a.values[name]
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// Len return the length.
|
||||
func (a Values) Len() int {
|
||||
return len(a.values)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func TestMustValue(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValuesSet(t *testing.T) {
|
||||
var values Values
|
||||
values := NewValues()
|
||||
val := values.Set("foo", MustValue(starlark.MakeInt(42)))
|
||||
|
||||
assert.Equal(t, val.Name, "foo")
|
||||
@ -79,7 +79,7 @@ func TestValuesSet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValuesGet(t *testing.T) {
|
||||
var values Values
|
||||
values := NewValues()
|
||||
values.Set("foo", MustValue(starlark.MakeInt(42)))
|
||||
values.Set("foo", MustValue(starlark.MakeInt(42*2)))
|
||||
|
||||
@ -94,7 +94,7 @@ func TestValuesGet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValuesHash(t *testing.T) {
|
||||
var a Values
|
||||
a := NewValues()
|
||||
a.Set("foo", MustValue(starlark.MakeInt(42)))
|
||||
a.Set("bar", MustValue(starlark.MakeInt(42*32)))
|
||||
|
||||
@ -102,7 +102,7 @@ func TestValuesHash(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, hashA, uint32(0xfede4ab3))
|
||||
|
||||
var b Values
|
||||
b := NewValues()
|
||||
b.Set("bar", MustValue(starlark.MakeInt(42*32)))
|
||||
b.Set("foo", MustValue(starlark.MakeInt(42)))
|
||||
|
||||
@ -112,7 +112,7 @@ func TestValuesHash(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValuesToStringDict(t *testing.T) {
|
||||
var a Values
|
||||
a := NewValues()
|
||||
a.Set("foo", MustValue(starlark.MakeInt(42)))
|
||||
a.Set("bar", MustValue(starlark.MakeInt(42*32)))
|
||||
|
||||
@ -123,7 +123,7 @@ func TestValuesToStringDict(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValuesForEach(t *testing.T) {
|
||||
var a Values
|
||||
a := NewValues()
|
||||
a.Set("foo", MustValue(starlark.MakeInt(42)))
|
||||
a.Set("bar", MustValue(starlark.MakeInt(42*32)))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user