mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-21 22:36:39 +00:00
optimise LatestMap.Merge by merging old into young
This commit is contained in:
@@ -56,9 +56,9 @@ func (m LatestMap) Size() int {
|
||||
return m.Map.Size()
|
||||
}
|
||||
|
||||
// Merge produces a fresh StringLatestMap containing the keys from
|
||||
// both inputs. When both inputs contain the same key, the newer value
|
||||
// is used.
|
||||
// Merge produces a fresh LatestMap, containing the keys from both
|
||||
// inputs. When both inputs contain the same key, the newer value is
|
||||
// used.
|
||||
func (m LatestMap) Merge(other LatestMap) LatestMap {
|
||||
var (
|
||||
mSize = m.Size()
|
||||
@@ -71,7 +71,45 @@ func (m LatestMap) Merge(other LatestMap) LatestMap {
|
||||
return other
|
||||
case otherSize == 0:
|
||||
return m
|
||||
case mSize < otherSize:
|
||||
case mSize*2 < otherSize:
|
||||
// We are selecting between two merge strategies here: 1)
|
||||
// "merge shorter map into longer map" (this branch and the
|
||||
// next), and 2) "merge older map into younger map" (last
|
||||
// branch).
|
||||
//
|
||||
// The "*2" results from the assumptions that a) all the keys
|
||||
// in the smaller map are in the larger map, and b) all the
|
||||
// entries in one map are younger than the entries in the
|
||||
// other. This is typically the case in our usage.
|
||||
// Furthermore, we assume that adding and setting an entry
|
||||
// carries the same cost. This is the case for ps.Map.
|
||||
//
|
||||
// Let len(s) and len(l) be the lengths of the shorter and
|
||||
// longer maps, respectively.
|
||||
//
|
||||
// It is then the case that the worst case complexity of the
|
||||
// "merge shorter map into longer map" strategy is len(s),
|
||||
// which happens when all the entries in the shorter map are
|
||||
// in fact older than their corresponding entries in the
|
||||
// longer map, which means we need to set all of them.
|
||||
//
|
||||
// By contrast, the worst case complexity of the "merge older
|
||||
// map into younger map" strategy is len(l)-len(s), which
|
||||
// happens when all the entries in the shorter map are younger
|
||||
// than their corresponding entries in the longer map, which
|
||||
// means we need to add all the entries from the longer map
|
||||
// that aren't in the shorter map.
|
||||
//
|
||||
// Therefore the cut-over point between the two merge
|
||||
// strategies is when len(s) = len(l)-len(s), i.e. len(s)*2 =
|
||||
// len(l).
|
||||
output, iter = iter, output
|
||||
case otherSize*2 < mSize:
|
||||
// As above, but in reverse.
|
||||
case output.First().(LatestEntry).Timestamp.Before(iter.First().(LatestEntry).Timestamp):
|
||||
// See the "all entries in one map are younger than entries in
|
||||
// the other" assumptions above. We are sampling entries here
|
||||
// to determine which map contains the younger entries.
|
||||
output, iter = iter, output
|
||||
}
|
||||
if m.decoder != other.decoder {
|
||||
|
||||
7
vendor/github.com/weaveworks/ps/map.go
generated
vendored
7
vendor/github.com/weaveworks/ps/map.go
generated
vendored
@@ -42,6 +42,9 @@ type Map interface {
|
||||
// This operation is O(log N) in the number of keys.
|
||||
Lookup(key string) (interface{}, bool)
|
||||
|
||||
// First returns the "first" value in the map, if any, or nil.
|
||||
First() interface{}
|
||||
|
||||
// Size returns the number of key value pairs in the map.
|
||||
// This takes O(1) time.
|
||||
Size() int
|
||||
@@ -348,6 +351,10 @@ func lookupLowLevel(self *tree, partialHash, hash uint64) (interface{}, bool) {
|
||||
return self.value, true
|
||||
}
|
||||
|
||||
func (m *tree) First() interface{} {
|
||||
return m.value
|
||||
}
|
||||
|
||||
func (m *tree) Size() int {
|
||||
return m.count
|
||||
}
|
||||
|
||||
4
vendor/manifest
vendored
4
vendor/manifest
vendored
@@ -1211,8 +1211,8 @@
|
||||
"importpath": "github.com/weaveworks/ps",
|
||||
"repository": "https://github.com/weaveworks/ps",
|
||||
"vcs": "git",
|
||||
"revision": "70d17b2d6f760345ef36a0748751eddf7290a92c",
|
||||
"branch": "master",
|
||||
"revision": "26c07ef9a67b5bd2f5707b9a1957e7492776d945",
|
||||
"branch": "map-first",
|
||||
"notests": true
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user