mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
Always merge into the larger ps.Map
Because they are commutative and immutable, we can do this!
This commit is contained in:
@@ -48,19 +48,35 @@ func (c Counters) Lookup(key string) (int, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Size returns the number of counters
|
||||
func (c Counters) Size() int {
|
||||
return c.psMap.Size()
|
||||
}
|
||||
|
||||
// Merge produces a fresh Counters, container the keys from both inputs. When
|
||||
// both inputs container the same key, the latter value is used.
|
||||
func (c Counters) Merge(other Counters) Counters {
|
||||
output := c.psMap
|
||||
|
||||
other.psMap.ForEach(func(key string, otherVal interface{}) {
|
||||
var (
|
||||
cSize = c.Size()
|
||||
otherSize = other.Size()
|
||||
output = c.psMap
|
||||
iter = other.psMap
|
||||
)
|
||||
switch {
|
||||
case cSize == 0:
|
||||
return other
|
||||
case otherSize == 0:
|
||||
return c
|
||||
case cSize < otherSize:
|
||||
output, iter = iter, output
|
||||
}
|
||||
iter.ForEach(func(key string, otherVal interface{}) {
|
||||
if val, ok := output.Lookup(key); ok {
|
||||
output = output.Set(key, otherVal.(int)+val.(int))
|
||||
} else {
|
||||
output = output.Set(key, otherVal)
|
||||
}
|
||||
})
|
||||
|
||||
return Counters{output}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,19 +49,35 @@ func (c EdgeMetadatas) Lookup(key string) (EdgeMetadata, bool) {
|
||||
return EdgeMetadata{}, false
|
||||
}
|
||||
|
||||
// Size is the number of elements
|
||||
func (c EdgeMetadatas) Size() int {
|
||||
return c.psMap.Size()
|
||||
}
|
||||
|
||||
// Merge produces a fresh Counters, container the keys from both inputs. When
|
||||
// both inputs container the same key, the latter value is used.
|
||||
func (c EdgeMetadatas) Merge(other EdgeMetadatas) EdgeMetadatas {
|
||||
output := c.psMap
|
||||
|
||||
other.psMap.ForEach(func(key string, otherVal interface{}) {
|
||||
var (
|
||||
cSize = c.Size()
|
||||
otherSize = other.Size()
|
||||
output = c.psMap
|
||||
iter = other.psMap
|
||||
)
|
||||
switch {
|
||||
case cSize == 0:
|
||||
return other
|
||||
case otherSize == 0:
|
||||
return c
|
||||
case cSize < otherSize:
|
||||
output, iter = iter, output
|
||||
}
|
||||
iter.ForEach(func(key string, otherVal interface{}) {
|
||||
if val, ok := output.Lookup(key); ok {
|
||||
output = output.Set(key, otherVal.(EdgeMetadata).Merge(val.(EdgeMetadata)))
|
||||
} else {
|
||||
output = output.Set(key, otherVal)
|
||||
}
|
||||
})
|
||||
|
||||
return EdgeMetadatas{output}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,21 +45,36 @@ func (m LatestMap) Copy() LatestMap {
|
||||
return m
|
||||
}
|
||||
|
||||
// Size returns the number of elements
|
||||
func (m LatestMap) Size() int {
|
||||
return m.Map.Size()
|
||||
}
|
||||
|
||||
// Merge produces a fresh LatestMap, container the kers from both inputs. When
|
||||
// both inputs container the same key, the latter value is used.
|
||||
func (m LatestMap) Merge(newer LatestMap) LatestMap {
|
||||
// expect people to do old.Merge(new), optimise for that.
|
||||
// ie if you do {k: v}.Merge({k: v'}), we end up just returning
|
||||
// newer, unmodified.
|
||||
output := newer.Map
|
||||
func (m LatestMap) Merge(other LatestMap) LatestMap {
|
||||
var (
|
||||
mSize = m.Size()
|
||||
otherSize = other.Size()
|
||||
output = m.Map
|
||||
iter = other.Map
|
||||
)
|
||||
switch {
|
||||
case mSize == 0:
|
||||
return other
|
||||
case otherSize == 0:
|
||||
return m
|
||||
case mSize < otherSize:
|
||||
output, iter = iter, output
|
||||
}
|
||||
|
||||
m.Map.ForEach(func(key string, olderVal interface{}) {
|
||||
if newerVal, ok := newer.Map.Lookup(key); ok {
|
||||
if newerVal.(LatestEntry).Timestamp.Before(olderVal.(LatestEntry).Timestamp) {
|
||||
output = output.Set(key, olderVal)
|
||||
iter.ForEach(func(key string, iterVal interface{}) {
|
||||
if existingVal, ok := output.Lookup(key); ok {
|
||||
if existingVal.(LatestEntry).Timestamp.Before(iterVal.(LatestEntry).Timestamp) {
|
||||
output = output.Set(key, iterVal)
|
||||
}
|
||||
} else {
|
||||
output = output.Set(key, olderVal)
|
||||
output = output.Set(key, iterVal)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -95,10 +95,9 @@ func TestMergeNodes(t *testing.T) {
|
||||
},
|
||||
b: report.Nodes{
|
||||
":192.168.1.1:12345": report.MakeNodeWith(map[string]string{ // <-- same ID
|
||||
PID: "0",
|
||||
Name: "curl",
|
||||
Domain: "node-a.local",
|
||||
}),
|
||||
}).WithLatest(PID, time.Now().Add(-1*time.Minute), "0"),
|
||||
},
|
||||
want: report.Nodes{
|
||||
":192.168.1.1:12345": report.MakeNodeWith(map[string]string{
|
||||
@@ -118,10 +117,9 @@ func TestMergeNodes(t *testing.T) {
|
||||
},
|
||||
b: report.Nodes{
|
||||
":192.168.1.1:12345": report.MakeNodeWith(map[string]string{ // <-- same ID
|
||||
PID: "0",
|
||||
Name: "curl",
|
||||
Domain: "node-a.local",
|
||||
}),
|
||||
}).WithLatest(PID, time.Now().Add(-1*time.Minute), "0"),
|
||||
},
|
||||
want: report.Nodes{
|
||||
":192.168.1.1:12345": report.MakeNodeWith(map[string]string{
|
||||
|
||||
@@ -48,12 +48,30 @@ func (s Sets) Lookup(key string) (StringSet, bool) {
|
||||
return EmptyStringSet, false
|
||||
}
|
||||
|
||||
// Size returns the number of elements
|
||||
func (s Sets) Size() int {
|
||||
return s.psMap.Size()
|
||||
}
|
||||
|
||||
// Merge merges two sets maps into a fresh set, performing set-union merges as
|
||||
// appropriate.
|
||||
func (s Sets) Merge(other Sets) Sets {
|
||||
result := s.psMap
|
||||
var (
|
||||
sSize = s.Size()
|
||||
otherSize = other.Size()
|
||||
result = s.psMap
|
||||
iter = other.psMap
|
||||
)
|
||||
switch {
|
||||
case sSize == 0:
|
||||
return other
|
||||
case otherSize == 0:
|
||||
return s
|
||||
case sSize < otherSize:
|
||||
result, iter = iter, result
|
||||
}
|
||||
|
||||
other.psMap.ForEach(func(key string, value interface{}) {
|
||||
iter.ForEach(func(key string, value interface{}) {
|
||||
set := value.(StringSet)
|
||||
if existingSet, ok := result.Lookup(key); ok {
|
||||
set = set.Merge(existingSet.(StringSet))
|
||||
|
||||
Reference in New Issue
Block a user