Skip to content

Commit

Permalink
internal/core/adt: reorganize nodeContext fields
Browse files Browse the repository at this point in the history
Hoist the fields that need copying when cloning to make cloning
less error prone in anticipation for the new evaluator which will
move things around.

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: If2597bd91133b789cc01ea155eb955121e962590
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/551412
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
Reviewed-by: Aram Hăvărneanu <aram@cue.works>
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
  • Loading branch information
mpvl committed Mar 24, 2023
1 parent ce65141 commit f807ee8
Showing 1 changed file with 71 additions and 66 deletions.
137 changes: 71 additions & 66 deletions internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -914,69 +914,40 @@ type nodeContext struct {
nextFree *nodeContext
refCount int

// Keep these two out of the nodeContextState to make them more accessible
// for source-level debuggers.
ctx *OpContext
node *Vertex

// TODO: (this is CL is first step)
// filter *Vertex a subset of composite with concrete fields for
// bloom-like filtering of disjuncts. We should first verify, however,
// whether some breath-first search gives sufficient performance, as this
// should already ensure a quick-fail for struct disjunctions with
// discriminators.
nodeContextState

arcMap []arcKey
// Below are slices that need to be managed when cloning and reclaiming
// nodeContexts for reuse. We want to ensure that, instead of setting
// slices to nil, we truncate the existing buffers so that they do not
// need to be reallocated upon reuse of the nodeContext.

// snapshot holds the last value of the vertex before calling postDisjunct.
snapshot Vertex

// Result holds the last evaluated value of the vertex after calling
// postDisjunct.
result Vertex

// Current value (may be under construction)
scalar Value // TODO: use Value in node.
scalarID CloseInfo
arcMap []arcKey // not copied for cloning

// Concrete conjuncts
kind Kind
kindExpr Expr // expr that adjust last value (for error reporting)
kindID CloseInfo // for error tracing
lowerBound *BoundValue // > or >=
upperBound *BoundValue // < or <=
checks []Validator // BuiltinValidator, other bound values.
postChecks []envCheck // Check non-monotic constraints, among other things.
errs *Bottom
// notify is used to communicate errors in cyclic dependencies.
// TODO: also use this to communicate increasingly more concrete values.
notify []*Vertex

// Conjuncts holds a reference to the Vertex Arcs that still need
// processing. It does NOT need to be copied.
conjuncts []Conjunct
cyclicConjuncts []cyclicConjunct

// conjunctsPos is an index into conjuncts indicating the next conjunct
// to process. This is used to avoids processing a conjunct twice in some
// cases where there is an evaluation cycle.
conjunctsPos int

// notify is used to communicate errors in cyclic dependencies.
// TODO: also use this to communicate increasingly more concrete values.
notify []*Vertex

// Struct information
dynamicFields []envDynamic
comprehensions []envYield
selfComprehensions []envYield // comprehensions iterating over own struct.
aStruct Expr
aStructID CloseInfo

// Expression conjuncts
lists []envList
vLists []*Vertex
exprs []envExpr

hasTop bool
hasCycle bool // has conjunct with structural cycle
hasNonCycle bool // has conjunct without structural cycle
depth int32
checks []Validator // BuiltinValidator, other bound values.
postChecks []envCheck // Check non-monotonic constraints, among other things.

// Disjunction handling
disjunctions []envDisjunct
Expand All @@ -987,10 +958,51 @@ type nodeContext struct {
// be treated as a marked disjunction.
usedDefault []defaultInfo

defaultMode defaultMode
disjuncts []*nodeContext
buffer []*nodeContext
disjunctErrs []*Bottom

// snapshot holds the last value of the vertex before calling postDisjunct.
snapshot Vertex

// Result holds the last evaluated value of the vertex after calling
// postDisjunct.
result Vertex
}

type nodeContextState struct {
// State info

hasTop bool
hasCycle bool // has conjunct with structural cycle
hasNonCycle bool // has conjunct without structural cycle

depth int32
defaultMode defaultMode

// Value info

kind Kind
kindExpr Expr // expr that adjust last value (for error reporting)
kindID CloseInfo // for error tracing

// Current value (may be under construction)
scalar Value // TODO: use Value in node.
scalarID CloseInfo

aStruct Expr
aStructID CloseInfo

lowerBound *BoundValue // > or >=
upperBound *BoundValue // < or <=
errs *Bottom

// Slice positions

// conjunctsPos is an index into conjuncts indicating the next conjunct
// to process. This is used to avoids processing a conjunct twice in some
// cases where there is an evaluation cycle.
conjunctsPos int
}

// Logf substitutes args in format. Arguments of type Feature, Value, and Expr
Expand Down Expand Up @@ -1025,36 +1037,26 @@ func (n *nodeContext) clone() *nodeContext {
d.ctx = n.ctx
d.node = n.node

d.scalar = n.scalar
d.scalarID = n.scalarID
d.kind = n.kind
d.kindExpr = n.kindExpr
d.kindID = n.kindID
d.aStruct = n.aStruct
d.aStructID = n.aStructID

d.lowerBound = n.lowerBound
d.upperBound = n.upperBound
d.errs = n.errs
d.hasTop = n.hasTop
d.hasCycle = n.hasCycle
d.hasNonCycle = n.hasNonCycle
d.depth = n.depth
d.nodeContextState = n.nodeContextState

d.arcMap = append(d.arcMap, n.arcMap...)
d.cyclicConjuncts = append(d.cyclicConjuncts, n.cyclicConjuncts...)
d.notify = append(d.notify, n.notify...)
d.checks = append(d.checks, n.checks...)
d.postChecks = append(d.postChecks, n.postChecks...)

d.conjuncts = append(d.conjuncts, n.conjuncts...)
d.cyclicConjuncts = append(d.cyclicConjuncts, n.cyclicConjuncts...)
d.dynamicFields = append(d.dynamicFields, n.dynamicFields...)
d.comprehensions = append(d.comprehensions, n.comprehensions...)
d.selfComprehensions = append(d.selfComprehensions, n.selfComprehensions...)
d.lists = append(d.lists, n.lists...)
d.vLists = append(d.vLists, n.vLists...)
d.exprs = append(d.exprs, n.exprs...)
d.checks = append(d.checks, n.checks...)
d.postChecks = append(d.postChecks, n.postChecks...)

d.usedDefault = append(d.usedDefault, n.usedDefault...)

// No need to clone d.disjunctions
// Do not clone other disjunction-related slices, like disjuncts and buffer:
// disjunction slices are managed by disjunction processing directly.

return d
}
Expand All @@ -1065,9 +1067,11 @@ func (c *OpContext) newNodeContext(node *Vertex) *nodeContext {
c.freeListNode = n.nextFree

*n = nodeContext{
ctx: c,
node: node,
kind: TopKind,
ctx: c,
node: node,
nodeContextState: nodeContextState{
kind: TopKind,
},
arcMap: n.arcMap[:0],
cyclicConjuncts: n.cyclicConjuncts[:0],
notify: n.notify[:0],
Expand All @@ -1093,7 +1097,8 @@ func (c *OpContext) newNodeContext(node *Vertex) *nodeContext {
return &nodeContext{
ctx: c,
node: node,
kind: TopKind,

nodeContextState: nodeContextState{kind: TopKind},
}
}

Expand Down

0 comments on commit f807ee8

Please sign in to comment.