diff --git a/code/sonalyze/table/hosts.go b/code/sonalyze/table/hosts.go index 6bef0ea2..0bb988fa 100644 --- a/code/sonalyze/table/hosts.go +++ b/code/sonalyze/table/hosts.go @@ -248,44 +248,15 @@ func (h *Hostnames) HasElement(hostname string) bool { } func (this *Hostnames) Equal(that *Hostnames) bool { - return setCompare(this, that) == 0 + return compare(this.s.sources, that.s.sources) == 0 } -// A > B if we can traverse B and A together and reach every node in A that is in B. -// -// A >= B if A > B or A = B. -// -// A = B if we can traverse B and A together and reach every node in A that is in B, and if from the -// terminal nodes of that traversal we can continue to walk down the graph to the sinks and we reach -// all the sinks that way. -// -// This is equivalent to saying that when we at every node of A that is reached by members of B, -// every outgoing edge is touched, and there are no members of B that do not touch an outgoing edge, -// or in other words, the set of first elements of B equals (in the normal sense) the set of first -// elements of A. -// -// Consider A = {a.b, a.c, b.x} and B = {a}. At level 1, A has two outgoing edges, for a and b. B -// touches only one of them, and B is therefore a subset, not equal. -// -// It could be that we just need to be talking about the set of leading elements of a and b... that -// would be a blessing. - func (a *Hostnames) HasSubset(b *Hostnames, proper bool) bool { + r := compare(a.s.sources, b.s.sources) if proper { - return properSubset(a.s, b.s) + return r < 0 } - return false -} - -func properSubset(a, b *set) bool { - return false -} - -// This checks whether `that` is a subset of `this`, equal to `this`, or neither (superset or -// incomparable). It returns -1 for the first, 0 for the second, and 1 for the last. - -func setCompare(this, that *Hostnames) int { - panic("NYI") + return r <= 0 } // Returns a string that is a comma-separated lists of the first elements of all the hosts in the diff --git a/code/sonalyze/table/hosts_test.go b/code/sonalyze/table/hosts_test.go index 2eebff00..d7df9cbf 100644 --- a/code/sonalyze/table/hosts_test.go +++ b/code/sonalyze/table/hosts_test.go @@ -65,6 +65,15 @@ func TestSetEquality(t *testing.T) { t.Fatal("equal") } + // a is a prefix of a.b.c and a.b.d so s = r + // s = {a.b.c, a.b.d} + // r = {a} + r := makeSet() + r.addNames("a") + if compare(s.sources, r.sources) != 0 { + t.Fatal("Equal") + } + // a.b is a prefix of a.b.c and a.b.d so s = q // s = {a.b.c, a.b.d} // q = {a.b} @@ -81,22 +90,36 @@ func TestSetEquality(t *testing.T) { } func TestSetInequality(t *testing.T) { - s := makeSet() - s.addNames("a.b.c", "a.b.d", "b.e") - q := makeSet() - q.addNames("a.b") + { + s := makeSet() + s.addNames("a.b.c", "a.b.d", "b.e") + q := makeSet() + q.addNames("a.b") - // q < s - // s = {a.b.c, a.b.d, b.e} - // q = {a.b} - s.addNames("b.e") - if compare(s.sources, q.sources) >= 0 { - t.Fatal("Less") + // q < s + // s = {a.b.c, a.b.d, b.e} + // q = {a.b} + s.addNames("b.e") + if compare(s.sources, q.sources) >= 0 { + t.Fatal("Less") + } + + // Same, but reversed - easy + if compare(q.sources, s.sources) != 1 { + t.Fatal("Not less") + } } - // Same, but reversed - easy - if compare(q.sources, s.sources) != 1 { - t.Fatal("Not less") + { + // Harder: we diverge deeper down + s := makeSet() + s.addNames("a.b.c", "a.b.d") + q := makeSet() + q.addNames("a.b.c") + + if compare(s.sources, q.sources) >= 0 { + t.Fatal("Less") + } } } @@ -172,4 +195,43 @@ func TestHostnames(t *testing.T) { if !h.HasElement("a.b.c.e") { t.Fatal("a.b.c.e") } + + { + lhs := NewHostnames() + lhs.Add("a.b.c") + lhs.Add("a.b.d") + rhs := NewHostnames() + rhs.Add("a.b") + if !lhs.Equal(rhs) { + t.Fatal("Equal") + } + if !lhs.HasSubset(rhs, false) { + t.Fatal("Equal") + } + if rhs.Equal(lhs) { + t.Fatal("Unequal") + } + if rhs.HasSubset(lhs, false) { + t.Fatal("Unequal") + } + } + + { + lhs := NewHostnames() + lhs.Add("a.b.c") + lhs.Add("a.b.d") + rhs := NewHostnames() + rhs.Add("a.b.c") + + if lhs.Equal(rhs) { + t.Fatal("Unequal") + } + if !lhs.HasSubset(rhs, true) { + t.Fatal("Less") + } + if rhs.HasSubset(lhs, true) { + t.Fatal("Less") + } + } + }