in target.Merge(arg), always merge arg into target

That way, as the top-level target.Merge(arg) on Report recursively
descends into the data structure, all component Merge operations are
invoked as target_component.Merge(arg_component).

Merge is commutative, so semantically this does not matter. But it is
easier to reason about and debug Merge code this way.

Moreover, the merge order matters for performance since some merges, in
particular LatestMap.Merge, are faster when the entries in the target
are younger than the entries in the arg. So this change allows
high-level code to invoke Report.Merge in the optimal order, in the
knowledge that the order is preserved for component merges.

Most of the Merge functions were already preserving order. Of the four
that didn't, Nodes.Merge is the most significant - it is the only one
that affects LatestMap.Merge order.
This commit is contained in:
Matthias Radestock
2016-08-14 17:32:03 +01:00
parent 003e13face
commit 21b3bcabe7
4 changed files with 4 additions and 4 deletions

View File

@@ -79,7 +79,7 @@ func (c EdgeMetadatas) Merge(other EdgeMetadatas) EdgeMetadatas {
}
iter.ForEach(func(key string, otherVal interface{}) {
if val, ok := output.Lookup(key); ok {
output = output.Set(key, otherVal.(EdgeMetadata).Merge(val.(EdgeMetadata)))
output = output.Set(key, val.(EdgeMetadata).Merge(otherVal.(EdgeMetadata)))
} else {
output = output.Set(key, otherVal)
}

View File

@@ -92,7 +92,7 @@ func (s Sets) Merge(other Sets) Sets {
iter.ForEach(func(key string, value interface{}) {
set := value.(StringSet)
if existingSet, ok := result.Lookup(key); ok {
set = set.Merge(existingSet.(StringSet))
set = existingSet.(StringSet).Merge(set)
}
result = result.Set(key, set)
})

View File

@@ -163,7 +163,7 @@ func (t TableTemplates) Merge(other TableTemplates) TableTemplates {
}
for k, v := range other {
if existing, ok := result[k]; ok {
result[k] = v.Merge(existing)
result[k] = existing.Merge(v)
} else {
result[k] = v
}

View File

@@ -181,7 +181,7 @@ func (n Nodes) Merge(other Nodes) Nodes {
}
for k, v := range other {
if n, ok := cp[k]; ok { // don't overwrite
cp[k] = v.Merge(n)
cp[k] = n.Merge(v)
} else {
cp[k] = v
}