Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
cue: refactor index
Browse files Browse the repository at this point in the history
Prepare to hoist index type.

Moves Loaded to runtime.Runtime.

Change-Id: Id4fb32a487281e0fed35f88fb911d8db8470ad4a
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9363
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
mpvl committed Apr 13, 2021
1 parent f228236 commit c0fe9ce
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 35 deletions.
10 changes: 4 additions & 6 deletions cue/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (r *Runtime) complete(p *build.Instance) (*Instance, error) {
if err := p.Complete(); err != nil {
return nil, err
}
inst := idx.loadInstance(p)
inst := loadInstance(idx, p)
inst.ImportPath = p.ImportPath
if inst.Err != nil {
return nil, inst.Err
Expand Down Expand Up @@ -165,7 +165,7 @@ func (r *Runtime) build(instances []*build.Instance) ([]*Instance, error) {
_ = p.Complete()
errs = errors.Append(errs, p.Err)

i := index.loadInstance(p)
i := loadInstance(index, p)
errs = errors.Append(errs, i.Err)
loaded = append(loaded, i)
}
Expand All @@ -189,7 +189,6 @@ func (r *Runtime) FromExpr(expr ast.Expr) (*Instance, error) {
// All instances belonging to the same package should share this index.
type index struct {
*runtime.Runtime
loaded map[*build.Instance]*Instance
}

// NewRuntime creates a *runtime.Runtime with builtins preloaded.
Expand All @@ -204,7 +203,6 @@ func newIndex() *index {
r := runtime.New()
i := &index{
Runtime: r,
loaded: map[*build.Instance]*Instance{},
}
r.Data = i
return i
Expand All @@ -214,7 +212,7 @@ func isBuiltin(s string) bool {
return runtime.SharedRuntime.IsBuiltinPackage(s)
}

func (idx *index) loadInstance(p *build.Instance) *Instance {
func loadInstance(idx *index, p *build.Instance) *Instance {
v, _ := idx.Runtime.Build(p)
return idx.getImportFromBuild(p, v)
return getImportFromBuild(idx, p, v)
}
2 changes: 1 addition & 1 deletion cue/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func TestBuild(t *testing.T) {
got = err.Error()
} else {
cfg := &debug.Config{Compact: true}
got = debug.NodeString(insts[0].Runtime, insts[0].Value().v, cfg)
got = debug.NodeString(insts[0].index.Runtime, insts[0].Value().v, cfg)
}
if got != tc.emit {
t.Errorf("\n got: %s\nwant: %s", got, tc.emit)
Expand Down
2 changes: 1 addition & 1 deletion cue/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type context struct {
}

// newContext returns a new evaluation context.
func (idx *index) newContext() *context {
func newContext(idx *index) *context {
c := &context{
index: idx,
}
Expand Down
37 changes: 22 additions & 15 deletions cue/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
// An Instance defines a single configuration based on a collection of
// underlying CUE files.
type Instance struct {
*index
index *index

root *adt.Vertex

Expand All @@ -54,13 +54,20 @@ func (x *index) addInst(p *Instance) *Instance {
}
// fmt.Println(p.ImportPath, "XXX")
x.AddInst(p.ImportPath, p.root, p.inst)
x.loaded[p.inst] = p
x.SetBuildData(p.inst, p)
p.index = x
return p
}

func (x *index) getImportFromBuild(p *build.Instance, v *adt.Vertex) *Instance {
inst := x.loaded[p]
func lookupInstance(x *index, p *build.Instance) *Instance {
if x, ok := x.BuildData(p); ok {
return x.(*Instance)
}
return nil
}

func getImportFromBuild(x *index, p *build.Instance, v *adt.Vertex) *Instance {
inst := lookupInstance(x, p)

if inst != nil {
return inst
Expand All @@ -79,27 +86,27 @@ func (x *index) getImportFromBuild(p *build.Instance, v *adt.Vertex) *Instance {
inst.setListOrError(p.Err)
}

x.loaded[p] = inst
x.SetBuildData(p, inst)

return inst
}

func (x *index) getImportFromNode(v *adt.Vertex) *Instance {
func getImportFromNode(x *index, v *adt.Vertex) *Instance {
p := x.GetInstanceFromNode(v)
if p == nil {
return nil
}

return x.getImportFromBuild(p, v)
return getImportFromBuild(x, p, v)
}

func (x *index) getImportFromPath(id string) *Instance {
func getImportFromPath(x *index, id string) *Instance {
node, _ := x.LoadImport(id)
if node == nil {
return nil
}
b := x.GetInstanceFromNode(node)
inst := x.loaded[b]
inst := lookupInstance(x, b)
if inst == nil {
inst = &Instance{
ImportPath: b.ImportPath,
Expand Down Expand Up @@ -145,7 +152,7 @@ func newInstance(x *index, p *build.Instance, v *adt.Vertex) *Instance {
}

x.AddInst(p.ImportPath, v, p)
x.loaded[p] = inst
x.SetBuildData(p, inst)
inst.index = x
return inst
}
Expand All @@ -170,7 +177,7 @@ func init() {
internal.EvalExpr = func(value, expr interface{}) interface{} {
v := value.(Value)
e := expr.(ast.Expr)
ctx := v.idx.newContext()
ctx := newContext(v.idx)
return newValueRoot(ctx, evalExpr(ctx, v.vertex(ctx), e))
}
}
Expand Down Expand Up @@ -262,7 +269,7 @@ func (inst *Instance) Doc() []*ast.CommentGroup {
// defines in emit value, it will be that value. Otherwise it will be all
// top-level values.
func (inst *Instance) Value() Value {
ctx := inst.newContext()
ctx := newContext(inst.index)
inst.root.Finalize(ctx.opCtx)
return newVertexRoot(ctx, inst.root)
}
Expand All @@ -271,7 +278,7 @@ func (inst *Instance) Value() Value {
//
// Expressions may refer to builtin packages if they can be uniquely identified.
func (inst *Instance) Eval(expr ast.Expr) Value {
ctx := inst.newContext()
ctx := newContext(inst.index)
v := inst.root
v.Finalize(ctx.opCtx)
result := evalExpr(ctx, v, expr)
Expand All @@ -285,7 +292,7 @@ func Merge(inst ...*Instance) *Instance {
v := &adt.Vertex{}

i := inst[0]
ctx := i.index.newContext().opCtx
ctx := newContext(i.index).opCtx

// TODO: interesting test: use actual unification and then on K8s corpus.

Expand Down Expand Up @@ -336,7 +343,7 @@ func (inst *Instance) Build(p *build.Instance) *Instance {
}

func (inst *Instance) value() Value {
return newVertexRoot(inst.newContext(), inst.root)
return newVertexRoot(newContext(inst.index), inst.root)
}

// Lookup reports the value at a path starting from the top level struct. The
Expand Down
4 changes: 2 additions & 2 deletions cue/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (r *Runtime) Unmarshal(b []byte) ([]*Instance, error) {
// The stored instances are functionally the same, but preserving of file
// information is only done on a best-effort basis.
func (r *Runtime) Marshal(instances ...*Instance) (b []byte, err error) {
ctx := r.index().newContext()
ctx := newContext(r.index())

staged := []instanceData{}
done := map[string]int{}
Expand Down Expand Up @@ -192,7 +192,7 @@ func (r *Runtime) Marshal(instances ...*Instance) (b []byte, err error) {
p := len(staged) - 1

for _, imp := range imports {
i := ctx.getImportFromPath(imp)
i := getImportFromPath(ctx.index, imp)
if i == nil || !strings.Contains(imp, ".") {
continue // a builtin package.
}
Expand Down
16 changes: 8 additions & 8 deletions cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ func MakeValue(ctx *adt.OpContext, v adt.Value) Value {
runtime := ctx.Impl().(*runtime.Runtime)
index := runtime.Data.(*index)

return newValueRoot(index.newContext(), v)
return newValueRoot(newContext(index), v)
}

func makeValue(idx *index, v *adt.Vertex) Value {
Expand Down Expand Up @@ -663,7 +663,7 @@ func remakeFinal(base Value, env *adt.Environment, v adt.Value) Value {
}

func (v Value) ctx() *context {
return v.idx.newContext()
return newContext(v.idx)
}

func (v Value) makeChild(ctx *context, i uint32, a *adt.Vertex) Value {
Expand Down Expand Up @@ -876,7 +876,7 @@ func (v Value) marshalJSON() (b []byte, err error) {
if v.v == nil {
return json.Marshal(nil)
}
ctx := v.idx.newContext()
ctx := newContext(v.idx)
x := v.eval(ctx)

if _, ok := x.(adt.Resolver); ok {
Expand Down Expand Up @@ -1749,7 +1749,7 @@ func (v Value) Unify(w Value) Value {
addConjuncts(n, v.v)
addConjuncts(n, w.v)

ctx := v.idx.newContext().opCtx
ctx := newContext(v.idx).opCtx
n.Finalize(ctx)

n.Parent = v.v.Parent
Expand Down Expand Up @@ -1786,7 +1786,7 @@ func (v Value) UnifyAccept(w Value, accept Value) Value {
n.AddConjunct(adt.MakeRootConjunct(nil, v.v))
n.AddConjunct(adt.MakeRootConjunct(nil, w.v))

ctx := v.idx.newContext().opCtx
ctx := newContext(v.idx).opCtx
n.Finalize(ctx)

n.Parent = v.v.Parent
Expand Down Expand Up @@ -1834,7 +1834,7 @@ func (v Value) instance() *Instance {
if v.v == nil {
return nil
}
return v.idx.getImportFromNode(v.v)
return getImportFromNode(v.idx, v.v)
}

// Reference returns the instance and path referred to by this value such that
Expand Down Expand Up @@ -1882,7 +1882,7 @@ func reference(c *context, env *adt.Environment, r adt.Expr) (inst *Instance, pa

case *adt.ImportReference:
imp := x.ImportPath.StringValue(ctx)
inst = c.index.getImportFromPath(imp)
inst = getImportFromPath(c.index, imp)

case *adt.SelectorExpr:
inst, path = reference(c, env, x.X)
Expand All @@ -1902,7 +1902,7 @@ func reference(c *context, env *adt.Environment, r adt.Expr) (inst *Instance, pa

func mkPath(ctx *context, a []string, v *adt.Vertex) (inst *Instance, path []string) {
if v.Parent == nil {
return ctx.index.getImportFromNode(v), a
return getImportFromNode(ctx.index, v), a
}
inst, path = mkPath(ctx, a, v.Parent)
path = append(path, v.Label.SelectorString(ctx.opCtx))
Expand Down
27 changes: 25 additions & 2 deletions internal/core/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,41 @@

package runtime

import (
"cuelang.org/go/cue/build"
)

// A Runtime maintains data structures for indexing and resuse for evaluation.
type Runtime struct {
index *index

// Data holds the legacy index strut. It is for transitional purposes only.
Data interface{}

loaded map[*build.Instance]interface{}
}

func (r *Runtime) SetBuildData(b *build.Instance, x interface{}) {
r.loaded[b] = x
}

func (r *Runtime) BuildData(b *build.Instance) (x interface{}, ok bool) {
x, ok = r.loaded[b]
return x, ok
}

// New creates a new Runtime. The builtins registered with RegisterBuiltin
// are available for
func New() *Runtime {
return &Runtime{
index: sharedIndex,
r := &Runtime{}
r.Init()
return r
}

func (r *Runtime) Init() {
if r.index != nil {
return
}
r.index = sharedIndex
r.loaded = map[*build.Instance]interface{}{}
}

0 comments on commit c0fe9ce

Please sign in to comment.