55 "fmt"
66 "math/rand"
77 "regexp"
8+ "strconv"
89 "strings"
910 "sync"
1011
@@ -25,6 +26,20 @@ const (
2526 groupComponent = 2
2627)
2728
29+ // matchValues takes a reMatchPattern match and returns the runlevel and component.
30+ func matchValues (match []string ) (int , string ) {
31+ if match == nil {
32+ return 0 , ""
33+ }
34+
35+ runlevel , err := strconv .Atoi (match [groupNumber ])
36+ if err != nil {
37+ panic (err )
38+ }
39+
40+ return runlevel , match [groupComponent ]
41+ }
42+
2843// ByNumberAndComponent creates parallelization for tasks whose original filenames are of the form
2944// 0000_NN_NAME_* - files that share 0000_NN_NAME_ are run in serial, but chunks of files that have
3045// the same 0000_NN but different NAME can be run in parallel. If the input is not sorted in an order
@@ -45,7 +60,6 @@ func ByNumberAndComponent(tasks []*Task) [][]*TaskNode {
4560 }
4661
4762 var buckets [][]* TaskNode
48- var lastNode * TaskNode
4963 for i := 0 ; i < count ; {
5064 matchBase := matches [i ]
5165 j := i + 1
@@ -56,26 +70,31 @@ func ByNumberAndComponent(tasks []*Task) [][]*TaskNode {
5670 break
5771 }
5872 if matchBase [groupComponent ] != matchNext [groupComponent ] {
59- groups = append (groups , & TaskNode {Tasks : tasks [i :j ]})
73+ node := & TaskNode {
74+ Tasks : tasks [i :j ],
75+ }
76+ node .runlevel , node .component = matchValues (matchBase )
77+ groups = append (groups , node )
6078 i = j
6179 }
6280 matchBase = matchNext
6381 }
6482 if len (groups ) > 0 {
65- groups = append (groups , & TaskNode {Tasks : tasks [i :j ]})
83+ node := & TaskNode {
84+ Tasks : tasks [i :j ],
85+ }
86+ node .runlevel , node .component = matchValues (matchBase )
87+ groups = append (groups , node )
6688 i = j
6789 buckets = append (buckets , groups )
68- lastNode = nil
6990 continue
7091 }
71- if lastNode == nil {
72- lastNode = & TaskNode {Tasks : append ([]* Task (nil ), tasks [i :j ]... )}
73- i = j
74- buckets = append (buckets , []* TaskNode {lastNode })
75- continue
92+ node := & TaskNode {
93+ Tasks : append ([]* Task (nil ), tasks [i :j ]... ),
7694 }
77- lastNode . Tasks = append ( lastNode . Tasks , tasks [ i : j ] ... )
95+ node . runlevel , node . component = matchValues ( matchBase )
7896 i = j
97+ buckets = append (buckets , []* TaskNode {node })
7998 }
8099 return buckets
81100}
@@ -105,21 +124,32 @@ func FlattenByNumberAndComponent(tasks []*Task) [][]*TaskNode {
105124 break
106125 }
107126 if matchBase [groupComponent ] != matchNext [groupComponent ] {
108- groups = append (groups , & TaskNode {Tasks : tasks [i :j ]})
127+ node := & TaskNode {
128+ Tasks : tasks [i :j ],
129+ }
130+ node .runlevel , node .component = matchValues (matchBase )
131+ groups = append (groups , node )
109132 i = j
110133 }
111134 matchBase = matchNext
112135 }
113136 if len (groups ) > 0 {
114- groups = append (groups , & TaskNode {Tasks : tasks [i :j ]})
137+ node := & TaskNode {
138+ Tasks : tasks [i :j ],
139+ }
140+ node .runlevel , node .component = matchValues (matchBase )
141+ groups = append (groups , node )
115142 i = j
116143 lastNode = nil
117144 continue
118145 }
119146 if lastNode == nil {
120- lastNode = & TaskNode {Tasks : append ([]* Task (nil ), tasks [i :j ]... )}
121- i = j
147+ lastNode = & TaskNode {
148+ Tasks : append ([]* Task (nil ), tasks [i :j ]... ),
149+ }
150+ lastNode .runlevel , lastNode .component = matchValues (matches [i ])
122151 groups = append (groups , lastNode )
152+ i = j
123153 continue
124154 }
125155 lastNode .Tasks = append (lastNode .Tasks , tasks [i :j ]... )
@@ -137,6 +167,12 @@ type TaskNode struct {
137167 Tasks []* Task
138168 // Out is a list of node indices to which there is an edge from this node (=dependents).
139169 Out []int
170+
171+ // runlevel is task's run level, extracted from the manifest filename.
172+ runlevel int
173+
174+ // component is task's component name, extracted from the manifest filename.
175+ component string
140176}
141177
142178func (n * TaskNode ) String () string {
@@ -148,7 +184,7 @@ func (n *TaskNode) String() string {
148184 }
149185 arr = append (arr , t .Manifest .GVK .String ())
150186 }
151- return "{ Tasks: " + strings .Join (arr , ", " ) + "}"
187+ return fmt . Sprintf ( "{RunLevel: %d, Component: %q, Tasks: %s}" , n . runlevel , n . component , strings .Join (arr , ", " ))
152188}
153189
154190func (n * TaskNode ) replaceIn (index , with int ) {
@@ -370,21 +406,34 @@ func (g *TaskGraph) Roots() []int {
370406}
371407
372408// Tree renders the task graph in Graphviz DOT.
373- func (g * TaskGraph ) Tree () string {
409+ func (g * TaskGraph ) Tree (granularity string ) string {
374410 out := []string {
375411 "digraph tasks {" ,
376412 " labelloc=t;" ,
377413 " rankdir=TB;" ,
378414 }
379415 for i , node := range g .Nodes {
380- label := make ([]string , 0 , len (node .Tasks ))
381- for _ , task := range node .Tasks {
382- label = append (label , strings .Replace (task .String (), "\" " , "" , - 1 ))
416+ var label string
417+ if node .runlevel != 0 || node .component != "" {
418+ label = fmt .Sprintf ("%02d-%s, %d manifests" , node .runlevel , node .component , len (node .Tasks ))
419+ } else {
420+ label = fmt .Sprintf ("%d manifests" , len (node .Tasks ))
383421 }
384- if len (label ) == 0 {
385- label = append (label , "no manifests" )
422+ switch granularity {
423+ case "manifest" :
424+ labels := make ([]string , 0 , len (node .Tasks ))
425+ for _ , task := range node .Tasks {
426+ labels = append (labels , strings .Replace (task .String (), "\" " , "" , - 1 ))
427+ }
428+ if len (labels ) > 0 {
429+ label = fmt .Sprintf ("%s\\ n%s" , label , strings .Join (labels , "\\ n" ))
430+ }
431+ case "task-node" :
432+ // nothing to append
433+ default :
434+ panic (fmt .Sprintf ("unrecognized granularity %q" , granularity ))
386435 }
387- out = append (out , fmt .Sprintf (" %d [ label=\" %s\" shape=\" box\" ];" , i , strings . Join ( label , " \\ n" ) ))
436+ out = append (out , fmt .Sprintf (" %d [ label=\" %s\" shape=\" box\" ];" , i , label ))
388437 }
389438 for i , node := range g .Nodes {
390439 for _ , j := range node .Out {
0 commit comments