@@ -53,10 +53,15 @@
53 53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
54 54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
typemethod dotsto {path} {
55 55 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
::variable mydotdestination $path
56 56 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
57 57 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ typemethod watch {id} {
60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ::variable mywatchids
61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lappend mywatchids $id
62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
58 63 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
59 64 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
typemethod dot {label changesets} {
60 65 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
::variable mydotprefix $label
61 66 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
::variable mydotid 0
62 67 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@@ -98,10 +103,11 @@
98 103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
log write 3 cyclebreaker {Traverse changesets}
99 104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
100 105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
InitializeCandidates $dg
101 106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
while {1} {
102 107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
while {[WithoutPredecessor $dg n]} {
108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ MarkWatch $dg
103 109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
ProcessedHook $dg $n $myat
104 110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg node delete $n
105 111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
incr myat
106 112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
ShowPendingNodes
107 113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -108,10 +114,11 @@
108 114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
109 115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if {![llength [dg nodes]]} break
110 116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
111 117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
BreakCycleHook $dg
112 118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
InitializeCandidates $dg
119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ MarkWatch $dg
113 120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
114 121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
115 122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg destroy
116 123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
117 124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
log write 3 cyclebreaker Done.
@@ -160,30 +167,34 @@
160 167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# # ## ### ##### ######## #############
161 168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
## Internal methods
162 169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
163 170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
proc Setup {changesets {log 1}} {
164 171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if {$log} {
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- log write 3 cyclebreaker "Create changeset graph, [nsp [llength $changesets] node]"
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ log write 3 cyclebreaker "Creating graph of changesets"
166 173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
167 174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
168 175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
set dg [struct::graph dg]
169 176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
170 177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach cset $changesets {
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set tr [$cset timerange]
171 179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg node insert $cset
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- $dg node set $cset timerange [$cset timerange]
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- $dg node set $cset label [$cset str]
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $dg node set $cset timerange $tr
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $dg node set $cset label "[$cset str]\\n[join [struct::list map $tr {::clock format}] "\\n"]"
174 182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg node set $cset __id__ [$cset id]
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $dg node set $cset shape [expr {[$cset bysymbol]
184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ? "ellipse"
185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ : "box"}]
186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {$log} {
189 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ log write 3 cyclebreaker "Has [nsp [llength $changesets] changeset]"
175 190 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
176 191 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
177 192 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# 2. Find for all relevant changeset their revisions and their
178 193 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# dependencies. Map the latter back to changesets and
179 194 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# construct the corresponding arcs.
180 195 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if {$log} {
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- log write 3 cyclebreaker {Setting up node dependencies}
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
185 196 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach cset $changesets {
186 197 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach succ [$cset successors] {
187 198 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# Changesets may have dependencies outside of the
188 199 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# chosen set. These are ignored
189 200 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if {![$dg node exists $succ]} continue
@@ -209,16 +220,22 @@
209 220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
210 221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
211 222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
212 223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
213 224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {$log} {
227 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ log write 3 cyclebreaker "Has [nsp [llength [$dg arcs]] dependency dependencies]"
228 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
214 229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
215 230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# Run the user hook to manipulate the graph before
216 231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# consummation.
217 232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
218 233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if {$log} { Mark $dg -start }
219 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PreHook $dg
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ MarkWatch $dg
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ PreHook $dg
236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ MarkWatch $dg
220 237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
221 238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# This kills the application if loops (see above) were found.
222 239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
trouble abort?
223 240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return $dg
224 241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -395,14 +412,18 @@
395 412 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
set pre [$dg nodes -in $n]
396 413 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
397 414 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg node delete $n
398 415 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
399 416 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach cset $replacements {
417 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set tr [$cset timerange]
400 418 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg node insert $cset
401 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- $dg node set $cset timerange [$cset timerange]
402 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- $dg node set $cset label [$cset str]
419 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $dg node set $cset timerange $tr
420 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $dg node set $cset label "[$cset str]\\n[join [struct::list map $tr {::clock format}] "\\n"]"
403 421 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
$dg node set $cset __id__ [$cset id]
422 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $dg node set $cset shape [expr {[$cset bysymbol]
423 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ? "ellipse"
424 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ : "box"}]
404 425 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
405 426 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
406 427 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach cset $replacements {
407 428 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach succ [$cset successors] {
408 429 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# The new changesets may have dependencies outside of
@@ -475,10 +496,35 @@
475 496 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
::variable mybreakcmd {}
476 497 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
477 498 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
478 499 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
479 500 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# # ## ### ##### ######## #############
501 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
502 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ proc MarkWatch {graph} {
503 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ::variable mywatchids
504 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set watched [Watched $graph $mywatchids]
505 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {![llength $watched]} return
506 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set neighbours [eval [linsert $watched 0 $graph nodes -adj]]
507 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ #foreach n $neighbours { log write 6 cyclebreaker "Neighbor [$n id] => $n" }
508 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Mark $graph watched [concat $watched $neighbours]
509 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
510 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
511 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
512 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ proc Watched {graph watchids} {
513 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set res {}
514 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach id $watchids {
515 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set nl [$graph nodes -key __id__ -value $id]
516 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {![llength $nl]} continue
517 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lappend res $nl
518 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ #log write 6 breakrcycle "Watching $id => $nl"
519 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $graph node set $nl fontcolor red
520 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
521 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return $res
522 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
523 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
524 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # # ## ### ##### ######## #############
525 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
480 526 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
481 527 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
typevariable myat 0 ; # Counter for commit ids for the
482 528 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# changesets.
483 529 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
typevariable mybottom {} ; # List of the candidate nodes for
484 530 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# committing.
@@ -491,10 +537,12 @@
491 537 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# generated .dot files.
492 538 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
typevariable mydotprefix {} ; # Prefix for dot files when
493 539 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# exporting the graphs.
494 540 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
typevariable mydotid 0 ; # Counter for dot file name
495 541 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# generation.
542 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ typevariable mywatchids {} ; # Changesets to watch the
543 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # neighbourhood of.
496 544 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
497 545 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# # ## ### ##### ######## #############
498 546 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
## Configuration
499 547 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
500 548 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
pragma -hasinstances no ; # singleton
501 549 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!