mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
This is an alternate way of solving the same problem as 4007a902a264e5ff2c3be6b269ade515c9c1c145, but in a nicer way. Compared to using pointers, this approach more obviously preserves the original behaviour, and is arguably more readable than the original code. Credit to @rade for this approach.
63 lines
1.2 KiB
Go
63 lines
1.2 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/spaolacci/murmur3"
|
|
|
|
"github.com/weaveworks/scope/report"
|
|
)
|
|
|
|
// Merger is the type for a thing that can merge reports.
|
|
type Merger interface {
|
|
Merge([]report.Report) report.Report
|
|
}
|
|
|
|
type dumbMerger struct{}
|
|
|
|
// MakeDumbMerger makes a Merger which merges together reports in the simplest possible way.
|
|
func MakeDumbMerger() Merger {
|
|
return dumbMerger{}
|
|
}
|
|
|
|
func (dumbMerger) Merge(reports []report.Report) report.Report {
|
|
rpt := report.MakeReport()
|
|
id := murmur3.New64()
|
|
for _, r := range reports {
|
|
rpt = rpt.Merge(r)
|
|
id.Write([]byte(r.ID))
|
|
}
|
|
rpt.ID = fmt.Sprintf("%x", id.Sum64())
|
|
return rpt
|
|
}
|
|
|
|
type smartMerger struct{}
|
|
|
|
// NewSmartMerger makes a Merger which merges reports in
|
|
// parallel. Speed up comes from the fact that a) most merges are
|
|
// between small reports, and b) we take advantage of available cores.
|
|
func NewSmartMerger() Merger {
|
|
return smartMerger{}
|
|
}
|
|
|
|
func (smartMerger) Merge(reports []report.Report) report.Report {
|
|
l := len(reports)
|
|
switch l {
|
|
case 0:
|
|
return report.MakeReport()
|
|
case 1:
|
|
return reports[0]
|
|
}
|
|
c := make(chan report.Report, l)
|
|
for _, r := range reports {
|
|
c <- r
|
|
}
|
|
for ; l > 1; l-- {
|
|
left, right := <-c, <-c
|
|
go func() {
|
|
c <- left.Merge(right)
|
|
}()
|
|
}
|
|
return <-c
|
|
}
|