Refactor join-Renderer helper functions as methods

New type joinResult is created to hold the nodes and ID mapping.
The implementation move from host.go to render.go.
This commit is contained in:
Bryan Boreham
2017-11-06 21:48:00 +00:00
parent cbba3c0fd3
commit 4feb451760
4 changed files with 71 additions and 65 deletions

View File

@@ -71,8 +71,7 @@ func (c connectionJoin) Render(rpt report.Report, dct Decorator) report.Nodes {
}
}
}
var ret = make(report.Nodes)
var mapped = map[string]string{} // input node ID -> output node ID
ret := newJoinResults()
// Now look at all the endpoints and see which map to IP nodes
for _, m := range endpoints {
@@ -83,7 +82,7 @@ func (c connectionJoin) Render(rpt report.Report, dct Decorator) report.Nodes {
// Nodes without a hostid may be pseudo nodes - if so, pass through to result
if _, ok := m.Latest.Lookup(report.HostNodeID); !ok {
if id, ok := externalNodeID(m, addr, local); ok {
addToResults(m, id, ret, mapped, newPseudoNode)
ret.addToResults(m, id, newPseudoNode)
continue
}
}
@@ -95,20 +94,15 @@ func (c connectionJoin) Render(rpt report.Report, dct Decorator) report.Nodes {
id, found = ipNodes[report.MakeScopedEndpointNodeID(scope, addr, port)]
}
if found && id != "" { // not one we blanked out earlier
addToResults(m, id, ret, mapped, func(id string) report.Node {
ret.addToResults(m, id, func(id string) report.Node {
return inputNodes[id]
})
}
}
// Copy through any unmatched input nodes
for _, n := range inputNodes {
if _, found := ret[n.ID]; !found {
ret[n.ID] = n
}
}
fixupAdjancencies(inputNodes, ret, mapped)
fixupAdjancencies(endpoints, ret, mapped)
return ret
ret.copyUnmatched(inputNodes)
ret.fixupAdjacencies(inputNodes)
ret.fixupAdjacencies(endpoints)
return ret.nodes
}
func (c connectionJoin) Stats(rpt report.Report, _ Decorator) Stats {

View File

@@ -69,9 +69,8 @@ type endpoints2Hosts struct {
func (e endpoints2Hosts) Render(rpt report.Report, dct Decorator) report.Nodes {
ns := SelectEndpoint.Render(rpt, dct)
local := LocalNetworks(rpt)
ret := newJoinResults()
var ret = make(report.Nodes)
var mapped = map[string]string{} // input node ID -> output node ID
for _, n := range ns {
// Nodes without a hostid are treated as pseudo nodes
hostNodeID, timestamp, ok := n.Latest.LookupEntry(report.HostNodeID)
@@ -80,50 +79,17 @@ func (e endpoints2Hosts) Render(rpt report.Report, dct Decorator) report.Nodes {
if !ok {
continue
}
addToResults(n, id, ret, mapped, newPseudoNode)
ret.addToResults(n, id, newPseudoNode)
} else {
id := report.MakeHostNodeID(report.ExtractHostID(n))
addToResults(n, id, ret, mapped, func(id string) report.Node {
ret.addToResults(n, id, func(id string) report.Node {
return report.MakeNode(id).WithTopology(report.Host).
WithLatest(report.HostNodeID, timestamp, hostNodeID)
})
}
}
fixupAdjancencies(ns, ret, mapped)
return ret
}
// Add Node M to the result set ret under id, creating a new result
// node if not already there, and updating the old-id to new-id mapping
// Note we do not update any counters for child topologies here
func addToResults(m report.Node, id string, ret report.Nodes, mapped map[string]string, create func(string) report.Node) {
result, exists := ret[id]
if !exists {
result = create(id)
}
result.Children = result.Children.Add(m)
result.Children = result.Children.Merge(m.Children)
ret[id] = result
mapped[m.ID] = id
}
// Rewrite Adjacency for new nodes in ret, original nodes in input, and mapping old->new IDs in mapped
func fixupAdjancencies(input, ret report.Nodes, mapped map[string]string) {
for _, n := range input {
outID, ok := mapped[n.ID]
if !ok {
continue
}
out := ret[outID]
// for each adjacency in the original node, find out what it maps to (if any),
// and add that to the new node
for _, a := range n.Adjacency {
if mappedDest, found := mapped[a]; found {
out.Adjacency = out.Adjacency.Add(mappedDest)
}
}
ret[outID] = out
}
ret.fixupAdjacencies(ns)
return ret.nodes
}
func (e endpoints2Hosts) Stats(rpt report.Report, _ Decorator) Stats {

View File

@@ -93,14 +93,13 @@ func (e endpoints2Processes) Render(rpt report.Report, dct Decorator) report.Nod
processes := SelectProcess.Render(rpt, dct)
endpoints := SelectEndpoint.Render(rpt, dct)
local := LocalNetworks(rpt)
ret := newJoinResults()
var ret = make(report.Nodes)
var mapped = map[string]string{} // input node ID -> output node ID
for _, n := range endpoints {
// Nodes without a hostid are treated as pseudo nodes
if hostNodeID, ok := n.Latest.Lookup(report.HostNodeID); !ok {
if id, ok := pseudoNodeID(n, local); ok {
addToResults(n, id, ret, mapped, newPseudoNode)
ret.addToResults(n, id, newPseudoNode)
}
} else {
pid, timestamp, ok := n.Latest.LookupEntry(process.PID)
@@ -117,7 +116,7 @@ func (e endpoints2Processes) Render(rpt report.Report, dct Decorator) report.Nod
hostID, _, _ := report.ParseNodeID(hostNodeID)
id := report.MakeProcessNodeID(hostID, pid)
addToResults(n, id, ret, mapped, func(id string) report.Node {
ret.addToResults(n, id, func(id string) report.Node {
if processNode, found := processes[id]; found {
return processNode
}
@@ -127,15 +126,10 @@ func (e endpoints2Processes) Render(rpt report.Report, dct Decorator) report.Nod
})
}
}
// Copy through any unmatched process nodes
for _, n := range processes {
if _, found := ret[n.ID]; !found {
ret[n.ID] = n
}
}
fixupAdjancencies(processes, ret, mapped)
fixupAdjancencies(endpoints, ret, mapped)
return ret
ret.copyUnmatched(processes)
ret.fixupAdjacencies(processes)
ret.fixupAdjacencies(endpoints)
return ret.nodes
}
func (e endpoints2Processes) Stats(rpt report.Report, _ Decorator) Stats {

View File

@@ -207,3 +207,55 @@ func (c ConstantRenderer) Render(_ report.Report, _ Decorator) report.Nodes {
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
mapped map[string]string // input node ID -> output node ID
}
func newJoinResults() joinResults {
return joinResults{nodes: make(report.Nodes), mapped: map[string]string{}}
}
// Add Node M under id, creating a new result node if not already there
// and updating the mapping from old ID to new ID
// Note we do not update any counters for child topologies here, because addToResults
// is only ever called when m is an endpoint and we never look at endpoint counts
func (ret *joinResults) addToResults(m report.Node, id string, create func(string) report.Node) {
result, exists := ret.nodes[id]
if !exists {
result = create(id)
}
result.Children = result.Children.Add(m)
result.Children = result.Children.Merge(m.Children)
ret.nodes[id] = result
ret.mapped[m.ID] = id
}
// Rewrite Adjacency for new nodes in ret for original nodes in input
func (ret *joinResults) fixupAdjacencies(input report.Nodes) {
for _, n := range input {
outID, ok := ret.mapped[n.ID]
if !ok {
continue
}
out := ret.nodes[outID]
// for each adjacency in the original node, find out what it maps to (if any),
// and add that to the new node
for _, a := range n.Adjacency {
if mappedDest, found := ret.mapped[a]; found {
out.Adjacency = out.Adjacency.Add(mappedDest)
}
}
ret.nodes[outID] = out
}
}
func (ret *joinResults) copyUnmatched(input report.Nodes) {
for _, n := range input {
if _, found := ret.nodes[n.ID]; !found {
ret.nodes[n.ID] = n
}
}
}