remove now superfluous Renderer.Stats method

step 2 (and final step) in producing stats as part of Rendering
This commit is contained in:
Matthias Radestock
2017-11-07 22:10:22 +00:00
parent 8f7e00f46a
commit 9bd8bd825b
10 changed files with 3 additions and 127 deletions

View File

@@ -14,52 +14,30 @@ import (
var (
benchReportFile = flag.String("bench-report-file", "", "json report file to use for benchmarking (relative to this package)")
benchmarkRenderResult map[string]report.Node
benchmarkStatsResult render.Stats
benchmarkRenderResult render.Nodes
)
func BenchmarkEndpointRender(b *testing.B) { benchmarkRender(b, render.EndpointRenderer) }
func BenchmarkEndpointStats(b *testing.B) { benchmarkStats(b, render.EndpointRenderer) }
func BenchmarkProcessRender(b *testing.B) { benchmarkRender(b, render.ProcessRenderer) }
func BenchmarkProcessStats(b *testing.B) { benchmarkStats(b, render.ProcessRenderer) }
func BenchmarkProcessWithContainerNameRender(b *testing.B) {
benchmarkRender(b, render.ProcessWithContainerNameRenderer)
}
func BenchmarkProcessWithContainerNameStats(b *testing.B) {
benchmarkStats(b, render.ProcessWithContainerNameRenderer)
}
func BenchmarkProcessNameRender(b *testing.B) { benchmarkRender(b, render.ProcessNameRenderer) }
func BenchmarkProcessNameStats(b *testing.B) { benchmarkStats(b, render.ProcessNameRenderer) }
func BenchmarkContainerRender(b *testing.B) { benchmarkRender(b, render.ContainerRenderer) }
func BenchmarkContainerStats(b *testing.B) { benchmarkStats(b, render.ContainerRenderer) }
func BenchmarkContainerWithImageNameRender(b *testing.B) {
benchmarkRender(b, render.ContainerWithImageNameRenderer)
}
func BenchmarkContainerWithImageNameStats(b *testing.B) {
benchmarkStats(b, render.ContainerWithImageNameRenderer)
}
func BenchmarkContainerImageRender(b *testing.B) {
benchmarkRender(b, render.ContainerImageRenderer)
}
func BenchmarkContainerImageStats(b *testing.B) {
benchmarkStats(b, render.ContainerImageRenderer)
}
func BenchmarkContainerHostnameRender(b *testing.B) {
benchmarkRender(b, render.ContainerHostnameRenderer)
}
func BenchmarkContainerHostnameStats(b *testing.B) {
benchmarkStats(b, render.ContainerHostnameRenderer)
}
func BenchmarkHostRender(b *testing.B) { benchmarkRender(b, render.HostRenderer) }
func BenchmarkHostStats(b *testing.B) { benchmarkStats(b, render.HostRenderer) }
func BenchmarkPodRender(b *testing.B) { benchmarkRender(b, render.PodRenderer) }
func BenchmarkPodStats(b *testing.B) { benchmarkStats(b, render.PodRenderer) }
func BenchmarkPodServiceRender(b *testing.B) {
benchmarkRender(b, render.PodServiceRenderer)
}
func BenchmarkPodServiceStats(b *testing.B) {
benchmarkStats(b, render.PodServiceRenderer)
}
func benchmarkRender(b *testing.B, r render.Renderer) {
@@ -74,30 +52,13 @@ func benchmarkRender(b *testing.B, r render.Renderer) {
b.StopTimer()
render.ResetCache()
b.StartTimer()
benchmarkRenderResult = r.Render(report, FilterNoop).Nodes
if len(benchmarkRenderResult) == 0 {
benchmarkRenderResult = r.Render(report, FilterNoop)
if len(benchmarkRenderResult.Nodes) == 0 {
b.Errorf("Rendered topology contained no nodes")
}
}
}
func benchmarkStats(b *testing.B, r render.Renderer) {
report, err := loadReport()
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
// No way to tell if this was successful :(
b.StopTimer()
render.ResetCache()
b.StartTimer()
benchmarkStatsResult = r.Stats(report, FilterNoop)
}
}
func loadReport() (report.Report, error) {
if *benchReportFile == "" {
return fixture.Report, nil

View File

@@ -105,10 +105,6 @@ func (c connectionJoin) Render(rpt report.Report, dct Decorator) Nodes {
return ret.result()
}
func (c connectionJoin) Stats(rpt report.Report, _ Decorator) Stats {
return Stats{} // nothing to report
}
// FilterEmpty is a Renderer which filters out nodes which have no children
// from the specified topology.
func FilterEmpty(topology string, r Renderer) Renderer {

View File

@@ -32,13 +32,6 @@ func (p PreciousNodeRenderer) Render(rpt report.Report, dct Decorator) Nodes {
return finalNodes
}
// Stats implements Renderer
func (p PreciousNodeRenderer) Stats(rpt report.Report, dct Decorator) Stats {
// default to the underlying renderer
// TODO: we don't take into account the precious node, so we may be off by one
return p.Renderer.Stats(rpt, dct)
}
// CustomRenderer allow for mapping functions that received the entire topology
// in one call - useful for functions that need to consider the entire graph.
// We should minimise the use of this renderer type, as it is very inflexible.
@@ -193,15 +186,6 @@ func (f *Filter) render(rpt report.Report, dct Decorator) Nodes {
return Nodes{Nodes: output, Filtered: filtered}
}
// Stats implements Renderer. General logic is to take the first (i.e.
// highest-level) stats we find, so upstream stats are ignored. This means that
// if we want to count the stats from multiple filters we need to compose their
// FilterFuncs, into a single Filter.
func (f Filter) Stats(rpt report.Report, dct Decorator) Stats {
nodes := f.render(rpt, dct)
return Stats{FilteredNodes: nodes.Filtered}
}
// IsConnected is the key added to Node.Metadata by ColorConnected
// to indicate a node has an edge pointing to it or from it
const IsConnected = "is_connected"

View File

@@ -90,7 +90,3 @@ func (e endpoints2Hosts) Render(rpt report.Report, dct Decorator) Nodes {
ret.fixupAdjacencies(endpoints)
return ret.result()
}
func (e endpoints2Hosts) Stats(rpt report.Report, _ Decorator) Stats {
return Stats{} // nothing to report
}

View File

@@ -12,7 +12,6 @@ import (
type renderFunc func(r report.Report) render.Nodes
func (f renderFunc) Render(r report.Report, _ render.Decorator) render.Nodes { return f(r) }
func (f renderFunc) Stats(r report.Report, _ render.Decorator) render.Stats { return render.Stats{} }
func TestMemoise(t *testing.T) {
calls := 0

View File

@@ -138,10 +138,6 @@ func (s selectPodsWithDeployments) Render(rpt report.Report, dct Decorator) Node
return Nodes{Nodes: result}
}
func (s selectPodsWithDeployments) Stats(rpt report.Report, _ Decorator) Stats {
return Stats{}
}
// MapPod2IP maps pod nodes to their IP address. This allows pods to
// be joined directly with the endpoint topology.
func MapPod2IP(m report.Node) []string {

View File

@@ -132,10 +132,6 @@ func (e endpoints2Processes) Render(rpt report.Report, dct Decorator) Nodes {
return ret.result()
}
func (e endpoints2Processes) Stats(rpt report.Report, _ Decorator) Stats {
return Stats{} // nothing to report
}
// MapProcess2Name maps process Nodes to Nodes
// for each process name.
//

View File

@@ -13,12 +13,6 @@ type MapFunc func(report.Node, report.Networks) report.Nodes
// Renderer is something that can render a report to a set of Nodes.
type Renderer interface {
Render(report.Report, Decorator) Nodes
Stats(report.Report, Decorator) Stats
}
// Stats is the type returned by Renderer.Stats
type Stats struct {
FilteredNodes int
}
// Nodes is the result of Rendering
@@ -35,12 +29,6 @@ func (r Nodes) Merge(o Nodes) Nodes {
}
}
func (s Stats) merge(other Stats) Stats {
return Stats{
FilteredNodes: s.FilteredNodes + other.FilteredNodes,
}
}
// Reduce renderer is a Renderer which merges together the output of several
// other renderers.
type Reduce []Renderer
@@ -73,15 +61,6 @@ func (r Reduce) Render(rpt report.Report, dct Decorator) Nodes {
return <-c
}
// Stats implements Renderer
func (r Reduce) Stats(rpt report.Report, dct Decorator) Stats {
var result Stats
for _, renderer := range r {
result = result.merge(renderer.Stats(rpt, dct))
}
return result
}
// Map is a Renderer which produces a set of Nodes from the set of
// Nodes produced by another Renderer.
type Map struct {
@@ -132,14 +111,6 @@ func (m *Map) Render(rpt report.Report, dct Decorator) Nodes {
return Nodes{Nodes: output}
}
// Stats implements Renderer
func (m *Map) Stats(_ report.Report, _ Decorator) Stats {
// There doesn't seem to be an instance where we want stats to recurse
// through Maps - for instance we don't want to see the number of filtered
// processes in the container renderer.
return Stats{}
}
// Decorator transforms one renderer to another. e.g. Filters.
type Decorator func(Renderer) Renderer
@@ -163,12 +134,6 @@ func (ad applyDecorator) Render(rpt report.Report, dct Decorator) Nodes {
}
return ad.Renderer.Render(rpt, nil)
}
func (ad applyDecorator) Stats(rpt report.Report, dct Decorator) Stats {
if dct != nil {
return dct(ad.Renderer).Stats(rpt, nil)
}
return Stats{}
}
// ApplyDecorator returns a renderer which will apply the given decorator to the child render.
func ApplyDecorator(renderer Renderer) Renderer {
@@ -202,12 +167,6 @@ func (cr conditionalRenderer) Render(rpt report.Report, dct Decorator) Nodes {
}
return Nodes{}
}
func (cr conditionalRenderer) Stats(rpt report.Report, dct Decorator) Stats {
if cr.Condition(rpt) {
return cr.Renderer.Stats(rpt, dct)
}
return Stats{}
}
// ConstantRenderer renders a fixed set of nodes
type ConstantRenderer struct {
@@ -219,11 +178,6 @@ func (c ConstantRenderer) Render(_ report.Report, _ Decorator) Nodes {
return c.Nodes
}
// Stats implements Renderer
func (c ConstantRenderer) Stats(_ report.Report, _ Decorator) Stats {
return Stats{}
}
// joinResults is used by Renderers that join sets of nodes
type joinResults struct {
nodes report.Nodes

View File

@@ -19,7 +19,6 @@ func (m mockRenderer) Render(rpt report.Report, d render.Decorator) render.Nodes
}
return render.Nodes{Nodes: m.Nodes}
}
func (m mockRenderer) Stats(rpt report.Report, _ render.Decorator) render.Stats { return render.Stats{} }
func TestReduceRender(t *testing.T) {
renderer := render.Reduce([]render.Renderer{

View File

@@ -14,11 +14,6 @@ func (t TopologySelector) Render(r report.Report, _ Decorator) Nodes {
return Nodes{Nodes: topology.Nodes}
}
// Stats implements Renderer
func (t TopologySelector) Stats(r report.Report, _ Decorator) Stats {
return Stats{}
}
// The topology selectors implement a Renderer which fetch the nodes from the
// various report topologies.
var (