Skip to content

Commit fc9720c

Browse files
committed
internal/core/adt: hoist dependency code from debug
It is confusing to have the dependency code in debug.go now we made it a part of the evaluator. Signed-off-by: Marcel van Lohuizen <[email protected]> Change-Id: I288142d5d9d7a3ae89009d4984d07ed36c699baa Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1207445 Reviewed-by: Daniel Martí <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent c2ebfdb commit fc9720c

File tree

2 files changed

+134
-117
lines changed

2 files changed

+134
-117
lines changed

Diff for: internal/core/adt/debug.go

-117
Original file line numberDiff line numberDiff line change
@@ -147,123 +147,6 @@ func openDebugGraph(ctx *OpContext, cc *closeContext, name string) {
147147
OpenNodeGraph(name, path, "in", "out", graph)
148148
}
149149

150-
// depKind is a type of dependency that is tracked with incDependent and
151-
// decDependent. For each there should be matching pairs passed to these
152-
// functions. The debugger, when used, tracks and verifies that these
153-
// dependencies are balanced.
154-
type depKind int
155-
156-
//go:generate go run golang.org/x/tools/cmd/stringer -type=depKind
157-
158-
const (
159-
// PARENT dependencies are used to track the completion of parent
160-
// closedContexts within the closedness tree.
161-
PARENT depKind = iota + 1
162-
163-
// ARC dependencies are used to track the completion of corresponding
164-
// closedContexts in parent Vertices.
165-
ARC
166-
167-
// NOTIFY dependencies keep a note while dependent conjuncts are collected
168-
NOTIFY // root node of source
169-
170-
// TASK dependencies are used to track the completion of a task.
171-
TASK
172-
173-
// DISJUNCT is used to mark an incomplete disjunct.
174-
DISJUNCT
175-
176-
// EVAL tracks that the conjunct associated with a closeContext has been
177-
// inserted using scheduleConjunct. A closeContext may not be deleted
178-
// as long as the conjunct has not been evaluated yet.
179-
// This prevents a node from being released if an ARC decrement happens
180-
// before a node is evaluated.
181-
EVAL
182-
183-
// COMP tracks pending arcs in comprehensions.
184-
COMP
185-
186-
// ROOT dependencies are used to track that all nodes of parents are
187-
// added to a tree.
188-
ROOT // Always refers to self.
189-
190-
// INIT dependencies are used to hold ownership of a closeContext during
191-
// initialization and prevent it from being finalized when scheduling a
192-
// node's conjuncts.
193-
INIT
194-
195-
// DEFER is used to track recursive processing of a node.
196-
DEFER // Always refers to self.
197-
198-
// SHARED is used to track shared nodes. The processing of shared nodes may
199-
// change until all other conjuncts have been processed.
200-
SHARED
201-
202-
// TEST is used for testing notifications.
203-
TEST // Always refers to self.
204-
)
205-
206-
// ccDep is used to record counters which is used for debugging only.
207-
// It is purpose is to be precise about matching inc/dec as well as to be able
208-
// to traverse dependency.
209-
type ccDep struct {
210-
dependency *closeContext
211-
kind depKind
212-
decremented bool
213-
214-
// task keeps a reference to a task for TASK dependencies.
215-
task *task
216-
// taskID indicates the sequence number of a task within a scheduler.
217-
taskID int
218-
}
219-
220-
func (c *closeContext) addDependent(ctx *OpContext, kind depKind, dependant *closeContext) *ccDep {
221-
if dependant == nil {
222-
dependant = c
223-
}
224-
225-
if ctx.LogEval > 1 {
226-
ctx.Logf(ctx.vertex, "INC(%s) %v %p parent: %p %d\n", kind, c.Label(), c, c.parent, c.conjunctCount)
227-
}
228-
229-
dep := &ccDep{kind: kind, dependency: dependant}
230-
c.dependencies = append(c.dependencies, dep)
231-
232-
return dep
233-
}
234-
235-
// matchDecrement checks that this decrement matches a previous increment.
236-
func (c *closeContext) matchDecrement(ctx *OpContext, v *Vertex, kind depKind, dependant *closeContext) {
237-
if dependant == nil {
238-
dependant = c
239-
}
240-
241-
if ctx.LogEval > 1 {
242-
ctx.Logf(ctx.vertex, "DEC(%s) %v %p %d\n", kind, c.Label(), c, c.conjunctCount)
243-
}
244-
245-
for _, d := range c.dependencies {
246-
if d.kind != kind {
247-
continue
248-
}
249-
if d.dependency != dependant {
250-
continue
251-
}
252-
// Only one typ-dependant pair possible.
253-
if d.decremented {
254-
// There might be a duplicate entry, so continue searching.
255-
continue
256-
}
257-
258-
d.decremented = true
259-
return
260-
}
261-
262-
if DebugDeps {
263-
panic(fmt.Sprintf("unmatched decrement: %s", kind))
264-
}
265-
}
266-
267150
// mermaidContext is used to create a dependency analysis for a node.
268151
type mermaidContext struct {
269152
ctx *OpContext

Diff for: internal/core/adt/dep.go

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright 2025 CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package adt
16+
17+
import "fmt"
18+
19+
// depKind is a type of dependency that is tracked with incDependent and
20+
// decDependent. For each there should be matching pairs passed to these
21+
// functions. The debugger, when used, tracks and verifies that these
22+
// dependencies are balanced.
23+
type depKind int
24+
25+
//go:generate go run golang.org/x/tools/cmd/stringer -type=depKind
26+
27+
const (
28+
// PARENT dependencies are used to track the completion of parent
29+
// closedContexts within the closedness tree.
30+
PARENT depKind = iota + 1
31+
32+
// ARC dependencies are used to track the completion of corresponding
33+
// closedContexts in parent Vertices.
34+
ARC
35+
36+
// NOTIFY dependencies keep a note while dependent conjuncts are collected
37+
NOTIFY // root node of source
38+
39+
// TASK dependencies are used to track the completion of a task.
40+
TASK
41+
42+
// DISJUNCT is used to mark an incomplete disjunct.
43+
DISJUNCT
44+
45+
// EVAL tracks that the conjunct associated with a closeContext has been
46+
// inserted using scheduleConjunct. A closeContext may not be deleted
47+
// as long as the conjunct has not been evaluated yet.
48+
// This prevents a node from being released if an ARC decrement happens
49+
// before a node is evaluated.
50+
EVAL
51+
52+
// COMP tracks pending arcs in comprehensions.
53+
COMP
54+
55+
// ROOT dependencies are used to track that all nodes of parents are
56+
// added to a tree.
57+
ROOT // Always refers to self.
58+
59+
// INIT dependencies are used to hold ownership of a closeContext during
60+
// initialization and prevent it from being finalized when scheduling a
61+
// node's conjuncts.
62+
INIT
63+
64+
// DEFER is used to track recursive processing of a node.
65+
DEFER // Always refers to self.
66+
67+
// SHARED is used to track shared nodes. The processing of shared nodes may
68+
// change until all other conjuncts have been processed.
69+
SHARED
70+
71+
// TEST is used for testing notifications.
72+
TEST // Always refers to self.
73+
)
74+
75+
// ccDep is used to record counters which is used for debugging only.
76+
// It is purpose is to be precise about matching inc/dec as well as to be able
77+
// to traverse dependency.
78+
type ccDep struct {
79+
dependency *closeContext
80+
kind depKind
81+
decremented bool
82+
83+
// task keeps a reference to a task for TASK dependencies.
84+
task *task
85+
// taskID indicates the sequence number of a task within a scheduler.
86+
taskID int
87+
}
88+
89+
func (c *closeContext) addDependent(ctx *OpContext, kind depKind, dependant *closeContext) *ccDep {
90+
if dependant == nil {
91+
dependant = c
92+
}
93+
94+
if ctx.LogEval > 1 {
95+
ctx.Logf(ctx.vertex, "INC(%s) %v %p parent: %p %d\n", kind, c.Label(), c, c.parent, c.conjunctCount)
96+
}
97+
98+
dep := &ccDep{kind: kind, dependency: dependant}
99+
c.dependencies = append(c.dependencies, dep)
100+
101+
return dep
102+
}
103+
104+
// matchDecrement checks that this decrement matches a previous increment.
105+
func (c *closeContext) matchDecrement(ctx *OpContext, v *Vertex, kind depKind, dependant *closeContext) {
106+
if dependant == nil {
107+
dependant = c
108+
}
109+
110+
if ctx.LogEval > 1 {
111+
ctx.Logf(ctx.vertex, "DEC(%s) %v %p %d\n", kind, c.Label(), c, c.conjunctCount)
112+
}
113+
114+
for _, d := range c.dependencies {
115+
if d.kind != kind {
116+
continue
117+
}
118+
if d.dependency != dependant {
119+
continue
120+
}
121+
// Only one typ-dependant pair possible.
122+
if d.decremented {
123+
// There might be a duplicate entry, so continue searching.
124+
continue
125+
}
126+
127+
d.decremented = true
128+
return
129+
}
130+
131+
if DebugDeps {
132+
panic(fmt.Sprintf("unmatched decrement: %s", kind))
133+
}
134+
}

0 commit comments

Comments
 (0)