From 3e62f7b75462c77f712a575e1d14a2a16aa109bb Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Sat, 11 Nov 2017 11:49:25 +0000 Subject: [PATCH] Rewrite MapProcess2Name to process all nodes in one pass This is more efficient as there are typically many fewer names than processes. --- render/process.go | 41 ++++++++++++++++++----------------------- render/render.go | 7 +++++++ 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/render/process.go b/render/process.go index eacf95f91..b69586e21 100644 --- a/render/process.go +++ b/render/process.go @@ -74,12 +74,7 @@ var ProcessWithContainerNameRenderer = processWithContainerNameRenderer{ProcessR // name graph by munging the progess graph. // // not memoised -var ProcessNameRenderer = ConditionalRenderer(renderProcesses, - MakeMap( - MapProcess2Name, - ProcessRenderer, - ), -) +var ProcessNameRenderer = CustomRenderer{RenderFunc: processes2Names, Renderer: ProcessRenderer} // endpoints2Processes joins the endpoint topology to the process // topology, matching on hostID and pid. @@ -132,23 +127,23 @@ func (e endpoints2Processes) Render(rpt report.Report) Nodes { return ret.result() } -// MapProcess2Name maps process Nodes to Nodes -// for each process name. -// -// This mapper is unlike the other foo2bar mappers as the intention -// is not to join the information with another topology. -func MapProcess2Name(n report.Node, _ report.Networks) report.Nodes { - if n.Topology == Pseudo { - return report.Nodes{n.ID: n} - } +// processes2Names maps process Nodes to Nodes for each process name. +func processes2Names(processes Nodes) Nodes { + ret := newJoinResults() - name, timestamp, ok := n.Latest.LookupEntry(process.Name) - if !ok { - return report.Nodes{} + for _, n := range processes.Nodes { + if n.Topology == Pseudo { + ret.passThrough(n) + } else { + name, timestamp, ok := n.Latest.LookupEntry(process.Name) + if ok { + ret.addChildAndChildren(n, name, func(id string) report.Node { + return report.MakeNode(id).WithTopology(MakeGroupNodeTopology(n.Topology, process.Name)). + WithLatest(process.Name, timestamp, name) + }) + } + } } - - node := NewDerivedNode(name, n).WithTopology(MakeGroupNodeTopology(n.Topology, process.Name)) - node.Latest = node.Latest.Set(process.Name, timestamp, name) - node.Counters = node.Counters.Add(n.Topology, 1) - return report.Nodes{name: node} + ret.fixupAdjacencies(processes) + return ret.result() } diff --git a/render/render.go b/render/render.go index b67e84e64..4b3d9e0fe 100644 --- a/render/render.go +++ b/render/render.go @@ -188,6 +188,13 @@ func (ret *joinResults) addChildAndChildren(m report.Node, id string, create fun ret.mapped[m.ID] = id } +// Add a copy of n straight into the results +func (ret *joinResults) passThrough(n report.Node) { + n.Adjacency = nil // fixupAdjacencies assumes all nodes start with blank lists + ret.nodes[n.ID] = n + ret.mapped[n.ID] = n.ID +} + // Rewrite Adjacency for new nodes in ret for original nodes in input func (ret *joinResults) fixupAdjacencies(input Nodes) { for _, n := range input.Nodes {