Skip to content

Commit

Permalink
Refactor join-Renderer helper functions as methods
Browse files Browse the repository at this point in the history
New type joinResult is created to hold the nodes and ID mapping.
The implementation move from host.go to render.go.
  • Loading branch information
bboreham committed Nov 6, 2017
1 parent 4f29349 commit 747ad94
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 65 deletions.
20 changes: 7 additions & 13 deletions render/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
}
Expand All @@ -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 {
Expand Down
44 changes: 5 additions & 39 deletions render/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand Down
20 changes: 7 additions & 13 deletions render/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
}
Expand All @@ -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 {
Expand Down
52 changes: 52 additions & 0 deletions render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}

0 comments on commit 747ad94

Please sign in to comment.