performance (rendering): Make Node merge a mutating operation.

We only ever call it in contexts where we don't need the original node
to be untouched.
This commit is contained in:
Bryan Boreham
2020-06-04 15:28:18 +00:00
parent 38782ca75a
commit 74182867af
4 changed files with 26 additions and 28 deletions

View File

@@ -28,7 +28,7 @@ func TestApply(t *testing.T) {
from report.Topology
via string
}{
{endpointNode.Merge(report.MakeNode("c").WithTopology(report.Endpoint)), r.Endpoint, endpointNodeID},
{endpointNode.WithTopology(report.Endpoint), r.Endpoint, endpointNodeID},
} {
if want, have := tuple.want, tuple.from.Nodes[tuple.via]; !reflect.DeepEqual(want, have) {
t.Errorf("want %+v, have %+v", want, have)

View File

@@ -180,9 +180,11 @@ func (ret *joinResults) mapChild(from, to string) {
// Note it is not safe to mix calls to add() with addChild(), addChildAndChildren() or addUnmappedChild()
func (ret *joinResults) add(from string, m report.Node) {
if existing, ok := ret.nodes[m.ID]; ok {
m = m.Merge(existing)
existing.UnsafeMerge(m)
ret.nodes[m.ID] = existing
} else {
ret.nodes[m.ID] = m
}
ret.nodes[m.ID] = m
ret.mapChild(from, m.ID)
}

View File

@@ -173,29 +173,22 @@ func (n Node) WithChild(child Node) Node {
return n
}
// Merge mergses the individual components of a node and returns a
// fresh node.
func (n Node) Merge(other Node) Node {
id := n.ID
if id == "" {
id = other.ID
// UnsafeMerge merges the individual components of a node, modifying the original
func (n *Node) UnsafeMerge(other Node) {
if n.ID == "" {
n.ID = other.ID
}
topology := n.Topology
if topology == "" {
topology = other.Topology
} else if other.Topology != "" && topology != other.Topology {
panic("Cannot merge nodes with different topology types: " + topology + " != " + other.Topology)
}
return Node{
ID: id,
Topology: topology,
Sets: n.Sets.Merge(other.Sets),
Adjacency: n.Adjacency.Merge(other.Adjacency),
Latest: n.Latest.Merge(other.Latest),
Metrics: n.Metrics.Merge(other.Metrics),
Parents: n.Parents.Merge(other.Parents),
Children: n.Children.Merge(other.Children),
if n.Topology == "" {
n.Topology = other.Topology
} else if other.Topology != "" && n.Topology != other.Topology {
panic("Cannot merge nodes with different topology types: " + n.Topology + " != " + other.Topology)
}
n.Sets = n.Sets.Merge(other.Sets)
n.Adjacency = n.Adjacency.Merge(other.Adjacency)
n.Latest = n.Latest.Merge(other.Latest)
n.Metrics = n.Metrics.Merge(other.Metrics)
n.Parents = n.Parents.Merge(other.Parents)
n.Children = n.Children.Merge(other.Children)
}
// UnsafeUnMerge removes data from n that would be added by merging other,

View File

@@ -127,9 +127,11 @@ func (t Topology) WithLabel(label, labelPlural string) Topology {
// in that it mutates the Topology, to solve issues of GC pressure.
func (t Topology) AddNode(node Node) {
if existing, ok := t.Nodes[node.ID]; ok {
node = node.Merge(existing)
existing.UnsafeMerge(node)
t.Nodes[node.ID] = existing
} else {
t.Nodes[node.ID] = node
}
t.Nodes[node.ID] = node
}
// ReplaceNode adds node to the topology under key nodeID; if a
@@ -262,8 +264,9 @@ func (n Nodes) Merge(other Nodes) Nodes {
// UnsafeMerge merges the other object into this one, modifying the original.
func (n *Nodes) UnsafeMerge(other Nodes) {
for k, v := range other {
if existing, ok := (*n)[k]; ok { // don't overwrite
(*n)[k] = v.Merge(existing)
if existing, ok := (*n)[k]; ok {
existing.UnsafeMerge(v)
(*n)[k] = existing
} else {
(*n)[k] = v
}