5
5
"fmt"
6
6
"math/rand"
7
7
"regexp"
8
+ "strconv"
8
9
"strings"
9
10
"sync"
10
11
@@ -25,6 +26,20 @@ const (
25
26
groupComponent = 2
26
27
)
27
28
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
+
28
43
// ByNumberAndComponent creates parallelization for tasks whose original filenames are of the form
29
44
// 0000_NN_NAME_* - files that share 0000_NN_NAME_ are run in serial, but chunks of files that have
30
45
// 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 {
45
60
}
46
61
47
62
var buckets [][]* TaskNode
48
- var lastNode * TaskNode
49
63
for i := 0 ; i < count ; {
50
64
matchBase := matches [i ]
51
65
j := i + 1
@@ -56,26 +70,31 @@ func ByNumberAndComponent(tasks []*Task) [][]*TaskNode {
56
70
break
57
71
}
58
72
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 )
60
78
i = j
61
79
}
62
80
matchBase = matchNext
63
81
}
64
82
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 )
66
88
i = j
67
89
buckets = append (buckets , groups )
68
- lastNode = nil
69
90
continue
70
91
}
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 ]... ),
76
94
}
77
- lastNode . Tasks = append ( lastNode . Tasks , tasks [ i : j ] ... )
95
+ node . runlevel , node . component = matchValues ( matchBase )
78
96
i = j
97
+ buckets = append (buckets , []* TaskNode {node })
79
98
}
80
99
return buckets
81
100
}
@@ -105,21 +124,32 @@ func FlattenByNumberAndComponent(tasks []*Task) [][]*TaskNode {
105
124
break
106
125
}
107
126
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 )
109
132
i = j
110
133
}
111
134
matchBase = matchNext
112
135
}
113
136
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 )
115
142
i = j
116
143
lastNode = nil
117
144
continue
118
145
}
119
146
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 ])
122
151
groups = append (groups , lastNode )
152
+ i = j
123
153
continue
124
154
}
125
155
lastNode .Tasks = append (lastNode .Tasks , tasks [i :j ]... )
@@ -137,6 +167,12 @@ type TaskNode struct {
137
167
Tasks []* Task
138
168
// Out is a list of node indices to which there is an edge from this node (=dependents).
139
169
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
140
176
}
141
177
142
178
func (n * TaskNode ) String () string {
@@ -148,7 +184,7 @@ func (n *TaskNode) String() string {
148
184
}
149
185
arr = append (arr , t .Manifest .GVK .String ())
150
186
}
151
- return "{ Tasks: " + strings .Join (arr , ", " ) + "}"
187
+ return fmt . Sprintf ( "{RunLevel: %d, Component: %q, Tasks: %s}" , n . runlevel , n . component , strings .Join (arr , ", " ))
152
188
}
153
189
154
190
func (n * TaskNode ) replaceIn (index , with int ) {
@@ -370,21 +406,34 @@ func (g *TaskGraph) Roots() []int {
370
406
}
371
407
372
408
// Tree renders the task graph in Graphviz DOT.
373
- func (g * TaskGraph ) Tree () string {
409
+ func (g * TaskGraph ) Tree (granularity string ) string {
374
410
out := []string {
375
411
"digraph tasks {" ,
376
412
" labelloc=t;" ,
377
413
" rankdir=TB;" ,
378
414
}
379
415
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 ))
383
421
}
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 ))
386
435
}
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 ))
388
437
}
389
438
for i , node := range g .Nodes {
390
439
for _ , j := range node .Out {
0 commit comments