Skip to content

Commit 30704a7

Browse files
committed
internal/core/eval: reduce per-node allocations
Removed resultNode from nodeShared and reuse allocations of nodeShared and nodeContext. Reduces running time of all tests by about 15%. This also simplifies disjunction handling and prepares for optimizing disjunction handling further. Note that with this change, it would be possible to merge nodeShared and nodeContext into a single type. This is left for later work. This also delays the creation of the arcMap to when it is really needed, avoiding another allocation for the majority of nodes. Change-Id: I40f39dbc5d07992cbc3490c4512caf9845ac1881 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7403 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent e05eee7 commit 30704a7

File tree

4 files changed

+196
-123
lines changed

4 files changed

+196
-123
lines changed

cue/testdata/cycle/051_resolved_self-reference_cycles_with_disjunction.txtar

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ Result:
172172
xa4: (int){ 10 }
173173
xb1: (int){ |((int){ 8 }, (int){ 9 }) }
174174
xb2: (_|_){
175-
// [incomplete]
175+
// [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
176+
// ./in.cue:18:6
176177
}
177178
xb3: (int){ |((int){ 6 }, (int){ 9 }) }
178179
xb4: (_|_){
@@ -213,7 +214,8 @@ Result:
213214
}
214215
xf1: (int){ |((int){ 8 }, (int){ 9 }) }
215216
xf2: (_|_){
216-
// [incomplete]
217+
// [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
218+
// ./in.cue:52:6
217219
}
218220
xf3: (int){ |((int){ 6 }, (int){ 9 }) }
219221
xf4: (_|_){

cue/testdata/cycle/052_resolved_self-reference_cycles_with_disjunction_with_defaults.txtar

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,8 @@ Result:
140140
xa2: (int){ 8 }
141141
xa3: (int){ 6 }
142142
xa4: (int){ 10 }
143-
xb1: (int){ |(*(int){ 8 }, (int){ 9 }) }
144-
xb2: (_|_){
145-
// [incomplete]
146-
}
143+
xb1: (int){ 8 }
144+
xb2: (int){ 8 }
147145
xb3: (int){ 6 }
148146
xb4: (_|_){
149147
// [cycle] cycle error

internal/core/eval/disjunct.go

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,8 @@ func (n *nodeContext) updateResult() (isFinal bool) {
133133
return n.isFinal
134134
}
135135

136-
d := n.nodeShared.disjunct
137-
if d == nil {
138-
d = &adt.Disjunction{}
139-
n.nodeShared.disjunct = d
140-
}
136+
n.touched = true
137+
d := &n.nodeShared.disjunct
141138

142139
result := *n.node
143140
if result.Value == nil {
@@ -152,6 +149,11 @@ func (n *nodeContext) updateResult() (isFinal bool) {
152149

153150
p := &result
154151
d.Values = append(d.Values, p)
152+
153+
if n.done() && (!n.isDefault() || n.isDefault()) {
154+
n.nodeShared.isDone = true
155+
}
156+
155157
if n.defaultMode == isDefault {
156158
// Keep defaults sorted first.
157159
i := d.NumDefaults
@@ -172,22 +174,9 @@ func (n *nodeContext) updateResult() (isFinal bool) {
172174
case !n.nodeShared.isDefault() && n.defaultMode == isDefault:
173175

174176
default:
175-
if x := n.result(); x == nil && Equal(n.ctx, n.node, x) {
176-
return n.isFinal
177-
}
178-
179-
// TODO: Compute fancy error message.
180-
n.nodeShared.resultNode = n
181-
// n.nodeShared.result.AddErr(n.ctx, &adt.Bottom{
182-
// Code: adt.IncompleteError,
183-
// Err: errors.Newf(n.ctx.Pos(), "ambiguous disjunction"),
184-
// })
185-
n.nodeShared.result_.Arcs = nil
186-
n.nodeShared.result_.Structs = nil
187177
return n.isFinal // n.defaultMode == isDefault
188178
}
189179

190-
n.nodeShared.resultNode = n
191180
n.nodeShared.setResult(n.node)
192181

193182
return n.isFinal
@@ -225,11 +214,11 @@ func (n *nodeContext) insertDisjuncts() (inserted bool) {
225214
p := 0
226215
inserted = true
227216

228-
disjunctions := []envDisjunct{}
217+
n.subDisjunctions = n.subDisjunctions[:0]
229218

230219
// fmt.Println("----", debug.NodeString(n.ctx, n.node, nil))
231220
for _, d := range n.disjunctions {
232-
disjunctions = append(disjunctions, d)
221+
n.subDisjunctions = append(n.subDisjunctions, d)
233222

234223
sub := len(n.disjunctions)
235224
defMode, ok := n.insertSingleDisjunct(p, d, false)
@@ -260,7 +249,7 @@ func (n *nodeContext) insertDisjuncts() (inserted bool) {
260249
// 0 to a referenced number (forces the default to be discarded).
261250
wasScalar := n.scalar != nil // Hack line 1
262251

263-
disjunctions = append(disjunctions, d)
252+
n.subDisjunctions = append(n.subDisjunctions, d)
264253
mode, ok := n.insertSingleDisjunct(p, d, true)
265254
p++
266255
if !ok {
@@ -278,7 +267,7 @@ func (n *nodeContext) insertDisjuncts() (inserted bool) {
278267
}
279268

280269
// Find last disjunction at which there is no overflow.
281-
for ; p > 0 && n.stack[p-1]+1 >= len(disjunctions[p-1].values); p-- {
270+
for ; p > 0 && n.stack[p-1]+1 >= len(n.subDisjunctions[p-1].values); p-- {
282271
}
283272
if p > 0 {
284273
// Increment a valid position and set all subsequent entries to 0.

0 commit comments

Comments
 (0)