graph: implement SubGraph and Equal
This commit is contained in:
parent
91c0629377
commit
c1bdb46623
@ -204,3 +204,32 @@ func (g Graph) Traverse(start Value, next func(v Value, in, out []Edge) (Value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (g Graph) edgesShared(g2 Graph) bool {
|
||||
for id := range g2.m {
|
||||
if _, ok := g.m[id]; !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// SubGraph returns true if the given Graph shares all of its Edges with this
|
||||
// Graph.
|
||||
func (g Graph) SubGraph(g2 Graph) bool {
|
||||
// as a quick check before iterating through the edges, if g has fewer edges
|
||||
// than g2 then g2 can't possibly be a sub-graph of it
|
||||
if len(g.m) < len(g2.m) {
|
||||
return false
|
||||
}
|
||||
return g.edgesShared(g2)
|
||||
}
|
||||
|
||||
// Equal returns true if the given Graph and this Graph have exactly the same
|
||||
// Edges.
|
||||
func (g Graph) Equal(g2 Graph) bool {
|
||||
if len(g.m) != len(g2.m) {
|
||||
return false
|
||||
}
|
||||
return g.edgesShared(g2)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package graph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
. "testing"
|
||||
"time"
|
||||
|
||||
@ -9,7 +10,12 @@ import (
|
||||
"github.com/mediocregopher/mediocre-go-lib/mtest/mchk"
|
||||
)
|
||||
|
||||
func strV(s string) Value {
|
||||
return Value{ID: s, V: s}
|
||||
}
|
||||
|
||||
func TestGraph(t *T) {
|
||||
t.Parallel()
|
||||
type state struct {
|
||||
Graph
|
||||
|
||||
@ -21,10 +27,6 @@ func TestGraph(t *T) {
|
||||
del Edge
|
||||
}
|
||||
|
||||
strV := func(s string) Value {
|
||||
return Value{ID: s, V: s}
|
||||
}
|
||||
|
||||
chk := mchk.Checker{
|
||||
Init: func() mchk.State {
|
||||
return state{
|
||||
@ -118,15 +120,64 @@ func TestGraph(t *T) {
|
||||
|
||||
return s, nil
|
||||
},
|
||||
MaxLength: 10,
|
||||
}
|
||||
|
||||
err := chk.RunCase(
|
||||
params{add: Edge{Tail: strV("4"), Val: strV("d"), Head: strV("4")}},
|
||||
params{del: Edge{Tail: strV("4"), Val: strV("d"), Head: strV("4")}},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := chk.RunFor(5 * time.Second); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubGraphAndEqual(t *T) {
|
||||
t.Parallel()
|
||||
type state struct {
|
||||
g1, g2 Graph
|
||||
expEqual, expSubGraph bool
|
||||
}
|
||||
|
||||
type params struct {
|
||||
e Edge
|
||||
add1, add2 bool
|
||||
}
|
||||
|
||||
chk := mchk.Checker{
|
||||
Init: func() mchk.State {
|
||||
return state{expEqual: true, expSubGraph: true}
|
||||
},
|
||||
Next: func(ss mchk.State) mchk.Action {
|
||||
i := mrand.Intn(10)
|
||||
p := params{
|
||||
e: Edge{
|
||||
Tail: strV(mrand.Hex(1)),
|
||||
Val: strV(mrand.Hex(8)),
|
||||
Head: strV(mrand.Hex(1)),
|
||||
},
|
||||
add1: i != 0,
|
||||
add2: i != 1,
|
||||
}
|
||||
return mchk.Action{Params: p}
|
||||
},
|
||||
Apply: func(ss mchk.State, a mchk.Action) (mchk.State, error) {
|
||||
s, p := ss.(state), a.Params.(params)
|
||||
if p.add1 {
|
||||
s.g1 = s.g1.AddEdge(p.e)
|
||||
}
|
||||
if p.add2 {
|
||||
s.g2 = s.g2.AddEdge(p.e)
|
||||
}
|
||||
s.expSubGraph = s.expSubGraph && p.add1
|
||||
s.expEqual = s.expEqual && p.add1 && p.add2
|
||||
|
||||
if s.g1.SubGraph(s.g2) != s.expSubGraph {
|
||||
return nil, fmt.Errorf("SubGraph expected to return %v", s.expSubGraph)
|
||||
}
|
||||
|
||||
if s.g1.Equal(s.g2) != s.expEqual {
|
||||
return nil, fmt.Errorf("Equal expected to return %v", s.expEqual)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
},
|
||||
MaxLength: 100,
|
||||
}
|
||||
|
||||
if err := chk.RunFor(5 * time.Second); err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user