diff --git a/app/collector.go b/app/collector.go index a33e11cff..f9dc48293 100644 --- a/app/collector.go +++ b/app/collector.go @@ -78,7 +78,7 @@ func NewCollector(window time.Duration) Collector { waitableCondition: waitableCondition{ waiters: map[chan struct{}]struct{}{}, }, - merger: NewSmartMerger(), + merger: NewSmartMerger(window), } } diff --git a/app/merger.go b/app/merger.go index 975b31d3b..69d4297d7 100644 --- a/app/merger.go +++ b/app/merger.go @@ -4,6 +4,7 @@ import ( "fmt" "math" "sort" + "time" "github.com/bluele/gcache" "github.com/spaolacci/murmur3" @@ -41,9 +42,13 @@ type smartMerger struct { // 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). -func NewSmartMerger() Merger { +func NewSmartMerger(window time.Duration) Merger { return &smartMerger{ - cache: gcache.New(1000).LRU().Build(), + cache: gcache.New(200). + LRU(). + Expiration(window). + EnableGC(2 * time.Second). + Build(), } } @@ -94,11 +99,9 @@ func (s *smartMerger) Merge(reports []report.Report) report.Report { // 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, rpt: report.MakeReport().Merge(left.rpt).Merge(right.rpt), diff --git a/app/merger_test.go b/app/merger_test.go index 06abc7505..d5d4e88f3 100644 --- a/app/merger_test.go +++ b/app/merger_test.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "testing" + "time" "github.com/weaveworks/scope/app" "github.com/weaveworks/scope/report" @@ -28,7 +29,7 @@ func TestMerger(t *testing.T) { AddNode(report.MakeNode("bar")). AddNode(report.MakeNode("baz")) - for _, merger := range []app.Merger{app.MakeDumbMerger(), app.NewSmartMerger()} { + for _, merger := range []app.Merger{app.MakeDumbMerger(), app.NewSmartMerger(10 * time.Second)} { // Test the empty list case if have := merger.Merge([]report.Report{}); !reflect.DeepEqual(have, report.MakeReport()) { t.Errorf("Bad merge: %s", test.Diff(have, want)) @@ -62,18 +63,18 @@ func TestSmartMerger(t *testing.T) { want := report.MakeReport() want.Endpoint.AddNode(report.MakeNode("foo")) - merger := app.NewSmartMerger() + merger := app.NewSmartMerger(10 * time.Second) if have := merger.Merge(reports); !reflect.DeepEqual(have, want) { t.Errorf("Bad merge: %s", test.Diff(have, want)) } } func BenchmarkSmartMerger(b *testing.B) { - benchmarkMerger(b, app.NewSmartMerger(), false) + benchmarkMerger(b, app.NewSmartMerger(10*time.Second), false) } func BenchmarkSmartMergerWithoutCaching(b *testing.B) { - benchmarkMerger(b, app.NewSmartMerger(), true) + benchmarkMerger(b, app.NewSmartMerger(10*time.Second), true) } func BenchmarkDumbMerger(b *testing.B) {