Merge pull request #309 from weaveworks/266-smarter-merge

Reduce garbage generation with smarter IDList merge
This commit is contained in:
Tom Wilkie
2015-07-08 13:07:12 +01:00
4 changed files with 41 additions and 5 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

@@ -8,6 +8,12 @@ type IDList []string
// MakeIDList makes a new IDList.
func MakeIDList(ids ...string) IDList {
sort.Strings(ids)
for i := 1; i < len(ids); i++ { // shuffle down any duplicates
if ids[i-1] == ids[i] {
ids = append(ids[:i-1], ids[i:]...)
i--
}
}
return IDList(ids)
}
@@ -20,11 +26,41 @@ func (a IDList) Add(ids ...string) IDList {
continue
}
// It a new element, insert it in order.
a = append(a[:i], append(IDList{s}, a[i:]...)...)
a = append(a, "")
copy(a[i+1:], a[i:])
a[i] = s
}
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)
}
}