From d528292cd47dad1cc1c1cb5f5994aa6b7fb9f2f3 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Thu, 7 Dec 2017 21:01:34 +0000 Subject: [PATCH] make report upgrading fast when it's a no-op The vast majority of the cost is memory allocation, so doing a first pass to see whether any upgrading is necessary at all, and thus avoiding allocation when it isn't, is a massive saving. --- app/benchmark_internal_test.go | 14 ++++++++++++++ report/report.go | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/app/benchmark_internal_test.go b/app/benchmark_internal_test.go index 84b2e1b98..d889fc3ad 100644 --- a/app/benchmark_internal_test.go +++ b/app/benchmark_internal_test.go @@ -67,6 +67,20 @@ func BenchmarkReportMerge(b *testing.B) { } } +func BenchmarkReportUpgrade(b *testing.B) { + reports, err := readReportFiles(*benchReportPath) + if err != nil { + b.Fatal(err) + } + r := NewSmartMerger().Merge(reports) + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + r.Upgrade() + } +} + func BenchmarkTopologyList(b *testing.B) { benchmarkRender(b, func(report report.Report) { request := &http.Request{ diff --git a/report/report.go b/report/report.go index 84eb88550..edb52e423 100644 --- a/report/report.go +++ b/report/report.go @@ -341,6 +341,18 @@ func (r Report) Validate() error { // // This for now creates node's LatestControls from Controls. func (r Report) Upgrade() Report { + needUpgrade := false + r.WalkTopologies(func(topology *Topology) { + for _, node := range topology.Nodes { + if node.LatestControls.Size() == 0 && len(node.Controls.Controls) > 0 { + needUpgrade = true + } + } + }) + if !needUpgrade { + return r + } + cp := r.Copy() ncd := NodeControlData{ Dead: false,