Skip to content

Commit

Permalink
internal/core/adt: debug options for sorting arcs
Browse files Browse the repository at this point in the history
This is used in Unity to check differences in case
ordering changed between implementations.

Signed-off-by: Marcel van Lohuizen <[email protected]>

Change-Id: I8af59bbd1e22fd931748babbdf45f6fdffe034d5
Signed-off-by: Marcel van Lohuizen <[email protected]>
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/533062
Unity-Result: CUEcueckoo <[email protected]>
TryBot-Result: CUEcueckoo <[email protected]>
Reviewed-by: Paul Jolly <[email protected]>
  • Loading branch information
mpvl committed Feb 17, 2022
1 parent be2ee9b commit b995f5b
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 13 deletions.
4 changes: 4 additions & 0 deletions cmd/cue/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/spf13/pflag"
Expand All @@ -33,6 +34,7 @@ import (
"cuelang.org/go/cue/load"
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/encoding"
"cuelang.org/go/internal/filetypes"
"cuelang.org/go/internal/value"
Expand Down Expand Up @@ -539,6 +541,8 @@ func parseArgs(cmd *Command, args []string, cfg *config) (p *buildPlan, err erro
return nil, err
}

adt.DebugSort, _ = strconv.Atoi(os.Getenv("CUE_DEBUG_SORT_ARCS"))

builds := loadFromArgs(cmd, args, cfg.loadCfg)
if builds == nil {
return nil, errors.Newf(token.NoPos, "invalid args")
Expand Down
2 changes: 1 addition & 1 deletion cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ func (v Value) structValOpts(ctx *adt.OpContext, o options) (s structValue, err
}
}

features := export.VertexFeatures(obj)
features := export.VertexFeatures(ctx, obj)

k := 0
for _, f := range features {
Expand Down
39 changes: 39 additions & 0 deletions internal/core/adt/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"reflect"
"regexp"
"sort"
"strings"

"github.com/cockroachdb/apd/v2"
Expand All @@ -40,6 +41,44 @@ var Debug bool = os.Getenv("CUE_DEBUG") != "0"
// 1: logging
var Verbosity int

// DebugSort specifies that arcs be sorted consistently between implementations.
// 0: default
// 1: sort by Feature: this should be consistent between implementations where
// there is no change in the compiler and indexing code.
// 2: alphabetical
var DebugSort int

func DebugSortArcs(c *OpContext, n *Vertex) {
if n.IsList() {
return
}
switch a := n.Arcs; DebugSort {
case 1:
sort.SliceStable(a, func(i, j int) bool {
return a[i].Label < a[j].Label
})
case 2:
sort.SliceStable(a, func(i, j int) bool {
return a[i].Label.SelectorString(c.Runtime) <
a[j].Label.SelectorString(c.Runtime)
})
}
}

func DebugSortFields(c *OpContext, a []Feature) {
switch DebugSort {
case 1:
sort.SliceStable(a, func(i, j int) bool {
return a[i] < a[j]
})
case 2:
sort.SliceStable(a, func(i, j int) bool {
return a[i].SelectorString(c.Runtime) <
a[j].SelectorString(c.Runtime)
})
}
}

// Assert panics if the condition is false. Assert can be used to check for
// conditions that are considers to break an internal variant or unexpected
// condition, but that nonetheless probably will be handled correctly down the
Expand Down
3 changes: 3 additions & 0 deletions internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,9 @@ func (n *nodeContext) checkClosed(state VertexStatus) bool {
}

func (n *nodeContext) completeArcs(state VertexStatus) {
if DebugSort > 0 {
DebugSortArcs(n.ctx, n.node)
}

if state <= AllArcs {
n.node.UpdateStatus(AllArcs)
Expand Down
18 changes: 11 additions & 7 deletions internal/core/export/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,17 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
return fields[i] > fields[j]
})

m := sortArcs(extractFeatures(e.structs))
sort.SliceStable(fields, func(i, j int) bool {
if m[fields[j]] == 0 {
return m[fields[i]] != 0
}
return m[fields[i]] > m[fields[j]]
})
if adt.DebugSort == 0 {
m := sortArcs(extractFeatures(e.structs))
sort.SliceStable(fields, func(i, j int) bool {
if m[fields[j]] == 0 {
return m[fields[i]] != 0
}
return m[fields[i]] > m[fields[j]]
})
} else {
adt.DebugSortFields(e.ctx, fields)
}

if len(e.fields) == 0 && !e.hasEllipsis {
switch len(e.embed) + len(e.conjuncts) {
Expand Down
12 changes: 10 additions & 2 deletions internal/core/export/toposort.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
// VertexFeatures returns the feature list of v. The list may include more
// features than for which there are arcs and also includes features for
// optional fields. It assumes the Structs fields is properly initialized.
func VertexFeatures(v *adt.Vertex) []adt.Feature {
func VertexFeatures(c *adt.OpContext, v *adt.Vertex) []adt.Feature {
sets := extractFeatures(v.Structs)
m := sortArcs(sets) // TODO: use for convenience.

Expand All @@ -44,7 +44,11 @@ func VertexFeatures(v *adt.Vertex) []adt.Feature {
sets = append(sets, a)
}

return sortedArcs(sets)
a = sortedArcs(sets)
if adt.DebugSort > 0 {
adt.DebugSortFields(c, a)
}
return a
}

// func structFeatures(a []*adt.StructLit) []adt.Feature {
Expand All @@ -53,6 +57,10 @@ func VertexFeatures(v *adt.Vertex) []adt.Feature {
// }

func (e *exporter) sortedArcs(v *adt.Vertex) (sorted []*adt.Vertex) {
if adt.DebugSort > 0 {
return v.Arcs
}

a := extractFeatures(v.Structs)
if len(a) == 0 {
return v.Arcs
Expand Down
2 changes: 1 addition & 1 deletion internal/core/export/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ func (e *exporter) structComposite(v *adt.Vertex, attrs []*ast.Attribute) ast.Ex
}

p := e.cfg
for _, label := range VertexFeatures(v) {
for _, label := range VertexFeatures(e.ctx, v) {
show := false
switch label.Typ() {
case adt.StringLabel:
Expand Down
4 changes: 2 additions & 2 deletions internal/core/subsume/vertex.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (s *subsumer) vertices(x, y *adt.Vertex) bool {
}

// All arcs in x must exist in y and its values must subsume.
xFeatures := export.VertexFeatures(x)
xFeatures := export.VertexFeatures(s.ctx, x)
for _, f := range xFeatures {
if s.Final && !f.IsRegular() {
continue
Expand Down Expand Up @@ -165,7 +165,7 @@ func (s *subsumer) vertices(x, y *adt.Vertex) bool {
return false
}

yFeatures := export.VertexFeatures(y)
yFeatures := export.VertexFeatures(s.ctx, y)
outer:
for _, f := range yFeatures {
if s.Final && !f.IsRegular() {
Expand Down

0 comments on commit b995f5b

Please sign in to comment.