@@ -268,6 +268,15 @@ type closeContext struct {
268
268
// tree as this closeContext. In both cases the are keyed by Vertex.
269
269
arcs []ccArc
270
270
271
+ // notify represents closeContexts which to notify of updates.
272
+ //
273
+ // TODO: Note that this slice is very similar to nodeContext.notify and the
274
+ // use of these can likely be merged. It may be better to let the notify
275
+ // originate from a more specific closeContext, allowing it to stopped
276
+ // sooner and possibly even remove the need for breaking dependency
277
+ // cycles.
278
+ notify []ccArc
279
+
271
280
// parentIndex is the position in the parent's arcs slice that corresponds
272
281
// to this closeContext. This is currently unused. The intention is to use
273
282
// this to allow groups with single elements (which will be the majority)
@@ -315,7 +324,6 @@ func (c *closeContext) updateArcType(ctx *OpContext, t ArcType) {
315
324
}
316
325
317
326
type ccArc struct {
318
- kind depKind
319
327
decremented bool
320
328
// matched indicates the arc is only added to track the destination of a
321
329
// matched pattern and that it is not explicitly defined as a field.
@@ -331,6 +339,7 @@ type ccArc struct {
331
339
// closeContext.
332
340
type ccArcRef struct {
333
341
src * closeContext
342
+ kind depKind
334
343
index int
335
344
}
336
345
@@ -464,7 +473,7 @@ func (cc *closeContext) getKeyedCC(ctx *OpContext, key *closeContext, c CycleInf
464
473
}
465
474
466
475
func (cc * closeContext ) linkNotify (ctx * OpContext , key * closeContext ) bool {
467
- for _ , a := range cc .arcs {
476
+ for _ , a := range cc .notify {
468
477
if a .key == key {
469
478
return false
470
479
}
@@ -556,33 +565,67 @@ func (c *closeContext) addDependency(ctx *OpContext, kind depKind, matched bool,
556
565
// NOTE: do not increment
557
566
// - either root closeContext or otherwise resulting from sub closeContext
558
567
// all conjuncts will be added now, notified, or scheduled as task.
568
+ switch kind {
569
+ case ARC :
570
+ for _ , a := range c .arcs {
571
+ if a .key == key {
572
+ panic ("addArc: Label already exists" )
573
+ }
574
+ }
575
+ child .incDependent (ctx , kind , c ) // matched in decDependent REF(arcs)
576
+
577
+ c .arcs = append (c .arcs , ccArc {
578
+ matched : matched ,
579
+ key : key ,
580
+ cc : child ,
581
+ })
582
+
583
+ // TODO: this tests seems sensible, but panics. Investigate what could
584
+ // trigger this.
585
+ // if child.src.Parent != c.src {
586
+ // panic("addArc: inconsistent parent")
587
+ // }
588
+ if child .src .cc () != root .src .cc () {
589
+ panic ("addArc: inconsistent root" )
590
+ }
559
591
560
- child .incDependent (ctx , kind , c ) // matched in decDependent REF(arcs)
561
-
562
- for _ , a := range c .arcs {
563
- if a .key == key {
564
- panic ("addArc: Label already exists" )
592
+ root .externalDeps = append (root .externalDeps , ccArcRef {
593
+ src : c ,
594
+ kind : kind ,
595
+ index : len (c .arcs ) - 1 ,
596
+ })
597
+ case NOTIFY :
598
+ for _ , a := range c .notify {
599
+ if a .key == key {
600
+ panic ("addArc: Label already exists" )
601
+ }
602
+ }
603
+ child .incDependent (ctx , kind , c ) // matched in decDependent REF(arcs)
604
+
605
+ c .notify = append (c .notify , ccArc {
606
+ matched : matched ,
607
+ key : key ,
608
+ cc : child ,
609
+ })
610
+
611
+ // TODO: this tests seems sensible, but panics. Investigate what could
612
+ // trigger this.
613
+ // if child.src.Parent != c.src {
614
+ // panic("addArc: inconsistent parent")
615
+ // }
616
+ if child .src .cc () != root .src .cc () {
617
+ panic ("addArc: inconsistent root" )
565
618
}
619
+
620
+ root .externalDeps = append (root .externalDeps , ccArcRef {
621
+ src : c ,
622
+ kind : kind ,
623
+ index : len (c .notify ) - 1 ,
624
+ })
625
+ default :
626
+ panic (kind )
566
627
}
567
628
568
- // TODO: this tests seems sensible, but panics. Investigate what could
569
- // trigger this.
570
- // if child.src.Parent != c.src {
571
- // panic("addArc: inconsistent parent")
572
- // }
573
- if child .src .cc () != root .src .cc () {
574
- panic ("addArc: inconsistent root" )
575
- }
576
- c .arcs = append (c .arcs , ccArc {
577
- kind : kind ,
578
- matched : matched ,
579
- key : key ,
580
- cc : child ,
581
- })
582
- root .externalDeps = append (root .externalDeps , ccArcRef {
583
- src : c ,
584
- index : len (c .arcs ) - 1 ,
585
- })
586
629
}
587
630
588
631
// incDependent needs to be called for any conjunct or child closeContext
@@ -650,7 +693,16 @@ func (c *closeContext) decDependent(ctx *OpContext, kind depKind, dependant *clo
650
693
continue
651
694
}
652
695
c .arcs [i ].decremented = true
653
- cc .decDependent (ctx , a .kind , c ) // REF(arcs)
696
+ cc .decDependent (ctx , ARC , c )
697
+ }
698
+
699
+ for i , a := range c .notify {
700
+ cc := a .cc
701
+ if a .decremented {
702
+ continue
703
+ }
704
+ c .notify [i ].decremented = true
705
+ cc .decDependent (ctx , NOTIFY , c )
654
706
}
655
707
656
708
c .finalizePattern ()
@@ -1015,9 +1067,6 @@ func isTotal(p Value) bool {
1015
1067
// this is not the case.
1016
1068
func injectClosed (ctx * OpContext , closed , dst * closeContext ) {
1017
1069
for _ , a := range dst .arcs {
1018
- if a .kind != ARC {
1019
- continue
1020
- }
1021
1070
ca := a .cc
1022
1071
switch f := ca .Label (); {
1023
1072
case ca .src .ArcType == ArcOptional ,
0 commit comments