Implement a Merge function on IDLists which is more efficient than repeated Add

This commit is contained in:
Bryan Boreham
2015-07-07 21:59:39 +01:00
parent 76d658b193
commit baf0d94af9
4 changed files with 32 additions and 4 deletions

View File

@@ -85,7 +85,7 @@ func (m Map) render(rpt report.Report) (RenderableNodes, map[string]string) {
output[outRenderable.ID] = outRenderable
mapped[inRenderable.ID] = outRenderable.ID
adjacencies[outRenderable.ID] = adjacencies[outRenderable.ID].Add(inRenderable.Adjacency...)
adjacencies[outRenderable.ID] = adjacencies[outRenderable.ID].Merge(inRenderable.Adjacency)
}
// Rewrite Adjacency for new node IDs.

View File

@@ -53,8 +53,8 @@ func (rn *RenderableNode) Merge(other RenderableNode) {
panic(rn.ID)
}
rn.Adjacency = rn.Adjacency.Add(other.Adjacency...)
rn.Origins = rn.Origins.Add(other.Origins...)
rn.Adjacency = rn.Adjacency.Merge(other.Adjacency)
rn.Origins = rn.Origins.Merge(other.Origins)
rn.AggregateMetadata.Merge(other.AggregateMetadata)
rn.NodeMetadata.Merge(other.NodeMetadata)

View File

@@ -31,6 +31,34 @@ func (a IDList) Add(ids ...string) IDList {
return a
}
// Merge all elements from a and b into a new list
func (a IDList) Merge(b IDList) IDList {
if len(b) == 0 { // Optimise special case, to avoid allocating
return a // (note unit test DeepEquals breaks if we don't do this)
}
d := make(IDList, len(a)+len(b))
for i, j, k := 0, 0, 0; ; k++ {
switch {
case i >= len(a):
copy(d[k:], b[j:])
return d[:k+len(b)-j]
case j >= len(b):
copy(d[k:], a[i:])
return d[:k+len(a)-i]
case a[i] < b[j]:
d[k] = a[i]
i++
case a[i] > b[j]:
d[k] = b[j]
j++
default: // equal
d[k] = a[i]
i++
j++
}
}
}
// Contains returns true if id is in the list.
func (a IDList) Contains(id string) bool {
i := sort.Search(len(a), func(i int) bool { return a[i] >= id })

View File

@@ -24,7 +24,7 @@ func (t *Topology) Merge(other Topology) {
// Merge merges another Adjacency list into the receiver.
func (a *Adjacency) Merge(other Adjacency) {
for addr, adj := range other {
(*a)[addr] = (*a)[addr].Add(adj...)
(*a)[addr] = (*a)[addr].Merge(adj)
}
}