optimization: store just IDs of child nodes

IDs are a lot smaller, hence quicker to manage.
Any time we want to refer back to the full node we look it up in its topology.

(This relies on nobody trying to store a rendered node as a child).
This commit is contained in:
Bryan Boreham
2020-06-08 16:39:50 +00:00
parent b4a73b7f87
commit d76da767d8
13 changed files with 233 additions and 280 deletions

View File

@@ -262,6 +262,19 @@ func split2(s, sep string) (s1, s2 string, ok bool) {
return s[:pos], s[pos+1:], true
}
// NodeIDType returns the type of a node ID - e.g. process, pod, endpoint
func NodeIDType(nodeID string) (string, bool) {
if _, tag, ok := ParseNodeID(nodeID); ok {
switch {
case len(tag) >= 2 && tag[0] == '<' && tag[len(tag)-1] == '>':
return tag[1 : len(tag)-1], true
case len(tag) >= 1 && tag[0] >= '0' && tag[0] <= '9':
return Endpoint, true
}
}
return "", false
}
// ParseNodeID produces the id and tag of a single-component node ID.
func ParseNodeID(nodeID string) (id string, tag string, ok bool) {
return split2(nodeID, ScopeDelim)

View File

@@ -3,6 +3,7 @@ package report_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/weaveworks/scope/report"
)
@@ -78,3 +79,18 @@ func TestECSServiceNodeIDCompat(t *testing.T) {
t.Errorf("Backwards-compatible id %q parsed name to %q, expected %q", testID, name, testName)
}
}
func TestNodeIDType(t *testing.T) {
ty, ok := report.NodeIDType("")
assert.False(t, ok)
ty, ok = report.NodeIDType(clientHostNodeID)
assert.True(t, ok)
assert.Equal(t, report.Host, ty)
ty, ok = report.NodeIDType(client54001EndpointNodeID)
assert.True(t, ok)
assert.Equal(t, report.Endpoint, ty)
rsetID := report.MakeReplicaSetNodeID("foo")
ty, ok = report.NodeIDType(rsetID)
assert.True(t, ok)
assert.Equal(t, report.ReplicaSet, ty)
}

View File

@@ -19,7 +19,7 @@ type Node struct {
Latest StringLatestMap `json:"latest,omitempty"`
Metrics Metrics `json:"metrics,omitempty" deepequal:"nil==empty"`
Parents Sets `json:"parents,omitempty"`
Children NodeSet `json:"children,omitempty"`
ChildIDs IDList `json:"cs,omitempty"`
}
// MakeNode creates a new Node with no initial metadata.
@@ -162,14 +162,16 @@ func (n Node) PruneParents() Node {
}
// WithChildren returns a fresh copy of n, with children merged in.
func (n Node) WithChildren(children NodeSet) Node {
n.Children = n.Children.Merge(children)
func (n Node) WithChildren(children IDList) Node {
for _, childID := range children {
n.ChildIDs = n.ChildIDs.Add(childID)
}
return n
}
// WithChild returns a fresh copy of n, with one child merged in.
func (n Node) WithChild(child Node) Node {
n.Children = n.Children.Merge(MakeNodeSet(child))
// WithChildID returns a fresh copy of n, with one child merged in.
func (n Node) WithChildID(childID string) Node {
n.ChildIDs = n.ChildIDs.Add(childID)
return n
}
@@ -194,7 +196,7 @@ func (n Node) Merge(other Node) Node {
Latest: n.Latest.Merge(other.Latest),
Metrics: n.Metrics.Merge(other.Metrics),
Parents: n.Parents.Merge(other.Parents),
Children: n.Children.Merge(other.Children),
ChildIDs: n.ChildIDs.Merge(other.ChildIDs),
}
}