-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathanalyzer.go
71 lines (59 loc) · 1.3 KB
/
analyzer.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
package main
import (
"sort"
"sync"
)
type Analyzer struct {
workerCount int
workerInput chan string
}
func NewAnalyzer(workerCount int) *Analyzer {
return &Analyzer{
workerCount: workerCount,
workerInput: make(chan string),
}
}
func (this *Analyzer) AnalyzeAll(paths []string) (fetches []*GitReport) {
go this.loadInputs(paths)
outputs := this.startWorkers()
for fetch := range merge(outputs...) {
fetches = append(fetches, fetch)
}
sort.Slice(fetches, func(i, j int) bool {
return fetches[i].RepoPath < fetches[j].RepoPath
})
return fetches
}
func (this *Analyzer) loadInputs(paths []string) {
for _, path := range paths {
this.workerInput <- path
}
close(this.workerInput)
}
func (this *Analyzer) startWorkers() (outputs []chan *GitReport) {
for x := 0; x < this.workerCount; x++ {
output := make(chan *GitReport)
outputs = append(outputs, output)
go NewWorker(x, this.workerInput, output).Start()
}
return outputs
}
func merge(fannedOut ...chan *GitReport) chan *GitReport {
var waiter sync.WaitGroup
waiter.Add(len(fannedOut))
fannedIn := make(chan *GitReport)
output := func(c <-chan *GitReport) {
for n := range c {
fannedIn <- n
}
waiter.Done()
}
for _, c := range fannedOut {
go output(c)
}
go func() {
waiter.Wait()
close(fannedIn)
}()
return fannedIn
}