-
Notifications
You must be signed in to change notification settings - Fork 0
/
work.go
100 lines (85 loc) · 2.4 KB
/
work.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package mapreduce
type jobAndDirectoryStack struct {
Job Job
stack []interface{}
}
func newStack(jobs Jobs) []jobAndDirectoryStack {
r := make([]jobAndDirectoryStack, 0, len(jobs))
for _, job := range jobs {
r = append(r, jobAndDirectoryStack{
Job: job,
stack: nil,
})
}
return r
}
func (f folderToMap) Matches(path string) []jobAndDirectoryStack {
results := make([]jobAndDirectoryStack, 0, len(f.jobsAndStack))
for _, s := range f.jobsAndStack {
if s.Job.Filter.Match(path) {
results = append(results, s)
}
}
return results
}
func (f folderToMap) Potential(path string) []jobAndDirectoryStack {
results := make([]jobAndDirectoryStack, 0, len(f.jobsAndStack))
for _, s := range f.jobsAndStack {
if s.Job.Filter.CouldMatch(path) {
results = append(results, s)
}
}
return results
}
type folderToMap struct {
// The relative path of the folder to the root
Path string
// The jobs that are potentially applicable to the folder
// and the directory files associated with the job
jobsAndStack []jobAndDirectoryStack
}
type workRemaining []folderToMap
func (w *workRemaining) Done() bool {
return len(*w) == 0
}
func (w *workRemaining) Add(r folderToMap) {
*w = append(*w, r)
}
func (w *workRemaining) Pop() (folderToMap, bool) {
if len(*w) == 0 {
return folderToMap{}, false
}
popped := (*w)[len(*w)-1]
*w = (*w)[0 : len(*w)-1]
return popped, true
}
func (w *workRemaining) addSubfoldersToRemainingWork(
currentFolder folderToMap,
folders []string,
newStackItemsForJobs map[int]interface{},
) {
for _, folder := range folders {
subfolder := joinWithSlash(currentFolder.Path, folder)
potentialJobsForSubfolder := currentFolder.Potential(subfolder)
if len(potentialJobsForSubfolder) > 0 {
// Take the previous stacks for these jobs and make new ones
newstacks := make([]jobAndDirectoryStack, len(potentialJobsForSubfolder))
for i := range newstacks {
newstacks[i].Job = potentialJobsForSubfolder[i].Job
newstacks[i].stack = make([]interface{}, 0, len(currentFolder.jobsAndStack)+1)
newstacks[i].stack = append(newstacks[i].stack, potentialJobsForSubfolder[i].stack...)
jobIndex := newstacks[i].Job.jobIndex
if newItem, found := newStackItemsForJobs[jobIndex]; found {
newstacks[i].stack = append(
newstacks[i].stack,
newItem,
)
}
}
w.Add(folderToMap{
Path: subfolder,
jobsAndStack: newstacks,
})
}
}
}