diff --git a/app/merger.go b/app/merger.go index 975b31d3b..f901d2e41 100644 --- a/app/merger.go +++ b/app/merger.go @@ -38,13 +38,11 @@ type smartMerger struct { cache gcache.Cache } -// NewSmartMerger makes a Merger which merges together reports, caching intermediate merges -// to accelerate future merges. Idea is to cache pair-wise merged reports, forming a merge -// tree. Merging a new report into this tree should be log(N). +// NewSmartMerger makes a Merger which merges together reports as +// a binary tree of reports. Speed up comes from the fact that +// most merges are between small reports. func NewSmartMerger() Merger { - return &smartMerger{ - cache: gcache.New(1000).LRU().Build(), - } + return smartMerger{} } type node struct { @@ -66,11 +64,7 @@ func hash(ids ...string) uint64 { return id.Sum64() } -func (s *smartMerger) ClearCache() { - s.cache.Purge() -} - -func (s *smartMerger) Merge(reports []report.Report) report.Report { +func (s smartMerger) Merge(reports []report.Report) report.Report { // Start with a sorted list of leaves. // Note we must dedupe reports with the same ID to ensure the // algorithm below doesn't go into an infinite loop. This is @@ -93,18 +87,10 @@ func (s *smartMerger) Merge(reports []report.Report) report.Report { // Define how to merge two nodes together. The result of merging // two reports is cached. merge := func(left, right *node) *node { - id := hash(left.rpt.ID, right.rpt.ID) - - if result, err := s.cache.Get(id); err == nil { - return result.(*node) - } - - n := &node{ - id: id, + return &node{ + id: hash(left.rpt.ID, right.rpt.ID), rpt: report.MakeReport().Merge(left.rpt).Merge(right.rpt), } - s.cache.Set(id, n) - return n } // Define how to reduce n nodes to 1. diff --git a/app/merger_test.go b/app/merger_test.go index 06abc7505..94227594a 100644 --- a/app/merger_test.go +++ b/app/merger_test.go @@ -69,20 +69,16 @@ func TestSmartMerger(t *testing.T) { } func BenchmarkSmartMerger(b *testing.B) { - benchmarkMerger(b, app.NewSmartMerger(), false) -} - -func BenchmarkSmartMergerWithoutCaching(b *testing.B) { - benchmarkMerger(b, app.NewSmartMerger(), true) + benchmarkMerger(b, app.NewSmartMerger()) } func BenchmarkDumbMerger(b *testing.B) { - benchmarkMerger(b, app.MakeDumbMerger(), false) + benchmarkMerger(b, app.MakeDumbMerger()) } const numHosts = 15 -func benchmarkMerger(b *testing.B, merger app.Merger, clearCache bool) { +func benchmarkMerger(b *testing.B, merger app.Merger) { makeReport := func() report.Report { rpt := report.MakeReport() for i := 0; i < 100; i++ { @@ -95,12 +91,6 @@ func benchmarkMerger(b *testing.B, merger app.Merger, clearCache bool) { for i := 0; i < numHosts*5; i++ { reports = append(reports, makeReport()) } - merger.Merge(reports) // prime the cache - if clearable, ok := merger.(interface { - ClearCache() - }); ok && clearCache { - clearable.ClearCache() - } b.ReportAllocs() b.ResetTimer() @@ -112,11 +102,5 @@ func benchmarkMerger(b *testing.B, merger app.Merger, clearCache bool) { } merger.Merge(reports) - - if clearable, ok := merger.(interface { - ClearCache() - }); ok && clearCache { - clearable.ClearCache() - } } }