this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/core/adt: split ccArc

Use a separate type for the notify slice
and simplify the code.

Now the code is split, we can use the fact that
several of the arguments of addArcDepedency
and addNotificationDependency (which used to
be addDependency) are always the same or are
derived in a particular way. This allows us
to remove a bunch of assertions.

The TODO that was mentioned was actually
incorrect, and was computing the wrong
derivative, which is why that assertion
did not work.

Splitting addDepedency now also allows us
to merge addNotificationDependency with
linkNotify. Note that the uniqueness check
can now be removed and that the assertions
are enforced by the compiler (because of the
limitations of the function signature).

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I9042cb42be98d4e3f761f7a095f44348815a8dd2
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1207453
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>

+45 -73
+8 -9
internal/core/adt/conjunct.go
··· 520 520 n.scheduleConjunct(c, id) 521 521 } 522 522 523 - func (n *nodeContext) addNotify2(v *Vertex, c CloseInfo) []receiver { 523 + func (n *nodeContext) addNotify2(v *Vertex, c CloseInfo) { 524 524 // scheduleConjunct should ensure that the closeContext of of c is aligned 525 525 // with v. We rely on this to be the case here. We enforce this invariant 526 526 // here for clarity and to ensure correctness. 527 527 n.ctx.Assertf(token.NoPos, c.cc.src == v, "close context not aligned with vertex") 528 528 529 529 // No need to do the notification mechanism if we are already complete. 530 - old := n.notify 531 530 switch { 532 531 case n.node.isFinal(): 533 - return old 532 + return 534 533 case !n.node.isInProgress(): 535 534 case n.meets(allAncestorsProcessed): 536 - return old 535 + return 537 536 } 538 537 539 538 // Create a "root" closeContext to reflect the entry point of the ··· 544 543 // is even possible by adding a panic. 545 544 root := n.node.rootCloseContext(n.ctx) 546 545 if root.isDecremented { 547 - return old 546 + return 548 547 } 549 548 550 549 for _, r := range n.notify { 551 550 if r.cc == c.cc { 552 - return old 551 + return 553 552 } 554 553 } 555 554 556 555 cc := c.cc 557 556 558 - if root.linkNotify(n.ctx, cc) { 557 + if root.addNotifyDependency(n.ctx, cc) { 558 + // TODO: this is mostly identical to the slice in the root closeContext. 559 + // Use only one once V2 is removed. 559 560 n.notify = append(n.notify, receiver{cc.src, cc}) 560 561 } 561 - 562 - return old 563 562 } 564 563 565 564 // Literal conjuncts
+18 -50
internal/core/adt/dep.go
··· 133 133 } 134 134 } 135 135 136 - // A ccArcRef x refers to the x.src.[arcs|notify][x.index] 136 + // A ccDepRef x refers to the x.src.[arcs|notify][x.index] 137 137 // 138 138 // We use this instead of pointers, because the address may change when 139 139 // growing a slice. We use this instead mechanism instead of a pointers so 140 140 // that we do not need to maintain separate free buffers once we use pools of 141 141 // closeContext. 142 - type ccArcRef struct { 142 + type ccDepRef struct { 143 143 src *closeContext 144 144 kind depKind 145 145 index int 146 146 } 147 147 148 148 // addArc adds a dependent arc to c. If child is an arc, child.src == key 149 - func (c *closeContext) addArcDependency(ctx *OpContext, matched bool, key, child, root *closeContext) { 150 - const kind = ARC 149 + func (c *closeContext) addArcDependency(ctx *OpContext, matched bool, child *closeContext) { 150 + root := child.src.cc() 151 151 152 152 // NOTE: do not increment 153 153 // - either root closeContext or otherwise resulting from sub closeContext 154 154 // all conjuncts will be added now, notified, or scheduled as task. 155 155 for _, a := range c.arcs { 156 - if a.key == key { 156 + if a.root == root { 157 157 panic("addArc: Label already exists") 158 158 } 159 159 } 160 - child.incDependent(ctx, kind, c) // matched in decDependent REF(arcs) 160 + child.incDependent(ctx, ARC, c) // matched in decDependent REF(arcs) 161 161 162 162 c.arcs = append(c.arcs, ccArc{ 163 163 matched: matched, 164 - key: key, 164 + root: root, 165 165 dst: child, 166 166 }) 167 167 168 - // TODO: this tests seems sensible, but panics. Investigate what could 169 - // trigger this. 170 - // if child.src.Parent != c.src { 171 - // panic("addArc: inconsistent parent") 172 - // } 173 - if child.src.cc() != root.src.cc() { 174 - panic("addArc: inconsistent root") 175 - } 176 - 177 - root.externalDeps = append(root.externalDeps, ccArcRef{ 168 + root.externalDeps = append(root.externalDeps, ccDepRef{ 178 169 src: c, 179 - kind: kind, 170 + kind: ARC, 180 171 index: len(c.arcs) - 1, 181 172 }) 182 173 } 183 174 184 - func (cc *closeContext) linkNotify(ctx *OpContext, key *closeContext) bool { 185 - for _, a := range cc.notify { 186 - if a.key == key { 187 - return false 188 - } 189 - } 190 - 191 - cc.addNotificationDependency(ctx, false, key, key, key.src.cc()) 192 - return true 193 - } 194 - 195 - func (c *closeContext) addNotificationDependency(ctx *OpContext, matched bool, key, child, root *closeContext) { 196 - const kind = NOTIFY 175 + func (c *closeContext) addNotifyDependency(ctx *OpContext, dst *closeContext) bool { 197 176 for _, a := range c.notify { 198 - if a.key == key { 199 - panic("addArc: Label already exists") 177 + if a.dst == dst { 178 + return false 200 179 } 201 180 } 202 - child.incDependent(ctx, kind, c) // matched in decDependent REF(arcs) 203 - 204 - c.notify = append(c.notify, ccArc{ 205 - matched: matched, 206 - key: key, 207 - dst: child, 208 - }) 181 + dst.incDependent(ctx, NOTIFY, c) // matched in decDependent REF(arcs) 209 182 210 - // TODO: this tests seems sensible, but panics. Investigate what could 211 - // trigger this. 212 - // if child.src.Parent != c.src { 213 - // panic("addArc: inconsistent parent") 214 - // } 215 - if child.src.cc() != root.src.cc() { 216 - panic("addArc: inconsistent root") 217 - } 183 + c.notify = append(c.notify, ccNotify{dst: dst}) 218 184 219 - root.externalDeps = append(root.externalDeps, ccArcRef{ 185 + root := dst.src.cc() 186 + root.externalDeps = append(root.externalDeps, ccDepRef{ 220 187 src: c, 221 - kind: kind, 188 + kind: NOTIFY, 222 189 index: len(c.notify) - 1, 223 190 }) 191 + return true 224 192 } 225 193 226 194 // incDisjunct increases disjunction-related counters. We require kind to be
+1 -1
internal/core/adt/disjunct2.go
··· 738 738 outer: 739 739 for _, a := range x.arcs { 740 740 for _, b := range y.arcs { 741 - if a.key.src.Label != b.key.src.Label { 741 + if a.root.src.Label != b.root.src.Label { 742 742 continue 743 743 } 744 744 if !equalPartialNode(ctx, a.dst, b.dst) {
+15 -7
internal/core/adt/fields.go
··· 182 182 // 183 183 // This is only used for root closedContext and only for debugging. 184 184 // TODO: move to nodeContext. 185 - externalDeps []ccArcRef 185 + externalDeps []ccDepRef 186 186 187 187 // child links to a sequence which additional patterns need to be verified 188 188 // against (&&). If there are more than one, these additional nodes are ··· 273 273 // originate from a more specific closeContext, allowing it to stopped 274 274 // sooner and possibly even remove the need for breaking dependency 275 275 // cycles. 276 - notify []ccArc 276 + notify []ccNotify 277 277 278 278 // parentIndex is the position in the parent's arcs slice that corresponds 279 279 // to this closeContext. This is currently unused. The intention is to use ··· 329 329 // matched pattern and that it is not explicitly defined as a field. 330 330 // This is only used for arcs and not for notify. 331 331 matched bool 332 - // key is the closeContext is used to find the destination of the arc, which 333 - // is the root context. 334 - key *closeContext 332 + // root is dst.src.cc(). TODO: remove and use dst directly. 333 + root *closeContext 334 + // dst is the closeContext for which the counters are incremented and 335 + // decremented and which is the actual destination of the dependency. 336 + dst *closeContext 337 + } 338 + 339 + type ccNotify struct { 340 + // decremented indicates whether [decDependant] has been called for this 341 + // dependency. 342 + decremented bool 335 343 // dst is the closeContext for which the counters are incremented and 336 344 // decremented and which is the actual destination of the dependency. 337 345 dst *closeContext ··· 403 411 func (cc *closeContext) getKeyedCC(ctx *OpContext, key *closeContext, c CycleInfo, mode ArcType, checkClosed bool) *closeContext { 404 412 for i := range cc.arcs { 405 413 a := &cc.arcs[i] 406 - if a.key == key { 414 + if a.root == key { 407 415 a.matched = a.matched && !checkClosed 408 416 a.dst.updateArcType(ctx, mode) 409 417 return a.dst ··· 454 462 // prevent a dependency on self. 455 463 if key.src != cc.src { 456 464 matched := !checkClosed 457 - cc.addArcDependency(ctx, matched, key, arc, key) 465 + cc.addArcDependency(ctx, matched, arc) 458 466 } 459 467 } 460 468
+3 -6
internal/core/adt/overlay.go
··· 441 441 if a.dst.overlay == nil { 442 442 continue 443 443 } 444 - if a.key.overlay != nil { 445 - a.key = a.key.overlay // TODO: is this necessary? 444 + if a.root.overlay != nil { 445 + a.root = a.root.overlay // TODO: is this necessary? 446 446 } 447 447 a.dst = a.dst.overlay 448 448 o.arcs = append(o.arcs, a) 449 449 } 450 450 451 451 for _, a := range x.notify { 452 - // If an arc does not have an overlay, we should not decrement the 452 + // If a notification does not have an overlay, we should not decrement the 453 453 // dependency counter. We simply remove the dependency in that case. 454 454 if a.dst.overlay == nil { 455 455 continue 456 - } 457 - if a.key.overlay != nil { 458 - a.key = a.key.overlay // TODO: is this necessary? 459 456 } 460 457 a.dst = a.dst.overlay 461 458 o.notify = append(o.notify, a)