pgraph: Replace edge struct with interface
This further cleans up the pgraph lib to be more generic.
This commit is contained in:
@@ -492,8 +492,13 @@ func (obj *Main) Run() error {
|
|||||||
resources.VtoR(v).Exit() // sync
|
resources.VtoR(v).Exit() // sync
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
edgeCmpFn := func(e1, e2 pgraph.Edge) (bool, error) {
|
||||||
|
edge1 := e1.(*resources.Edge) // panic if wrong
|
||||||
|
edge2 := e2.(*resources.Edge) // panic if wrong
|
||||||
|
return edge1.Name == edge2.Name && edge1.Notify == edge2.Notify, nil // simple cmp
|
||||||
|
}
|
||||||
// on success, this updates the receiver graph...
|
// on success, this updates the receiver graph...
|
||||||
if err := oldGraph.GraphSync(newGraph, vertexCmpFn, vertexAddFn, vertexRemoveFn); err != nil {
|
if err := oldGraph.GraphSync(newGraph, vertexCmpFn, vertexAddFn, vertexRemoveFn, edgeCmpFn); err != nil {
|
||||||
log.Printf("Main: Error running graph sync: %v", err)
|
log.Printf("Main: Error running graph sync: %v", err)
|
||||||
// unpause!
|
// unpause!
|
||||||
if !first {
|
if !first {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import (
|
|||||||
// This updates the Graph on success only.
|
// This updates the Graph on success only.
|
||||||
// FIXME: should we do this with copies of the vertex resources?
|
// FIXME: should we do this with copies of the vertex resources?
|
||||||
// FIXME: add test cases
|
// FIXME: add test cases
|
||||||
func (obj *Graph) GraphSync(newGraph *Graph, vertexCmpFn func(Vertex, Vertex) (bool, error), vertexAddFn func(Vertex) error, vertexRemoveFn func(Vertex) error) error {
|
func (obj *Graph) GraphSync(newGraph *Graph, vertexCmpFn func(Vertex, Vertex) (bool, error), vertexAddFn func(Vertex) error, vertexRemoveFn func(Vertex) error, edgeCmpFn func(Edge, Edge) (bool, error)) error {
|
||||||
|
|
||||||
oldGraph := obj.Copy() // work on a copy of the old graph
|
oldGraph := obj.Copy() // work on a copy of the old graph
|
||||||
if oldGraph == nil {
|
if oldGraph == nil {
|
||||||
@@ -43,7 +43,7 @@ func (obj *Graph) GraphSync(newGraph *Graph, vertexCmpFn func(Vertex, Vertex) (b
|
|||||||
|
|
||||||
var lookup = make(map[Vertex]Vertex)
|
var lookup = make(map[Vertex]Vertex)
|
||||||
var vertexKeep []Vertex // list of vertices which are the same in new graph
|
var vertexKeep []Vertex // list of vertices which are the same in new graph
|
||||||
var edgeKeep []*Edge // list of vertices which are the same in new graph
|
var edgeKeep []Edge // list of vertices which are the same in new graph
|
||||||
|
|
||||||
for v := range newGraph.Adjacency() { // loop through the vertices (resources)
|
for v := range newGraph.Adjacency() { // loop through the vertices (resources)
|
||||||
var vertex Vertex
|
var vertex Vertex
|
||||||
@@ -100,9 +100,14 @@ func (obj *Graph) GraphSync(newGraph *Graph, vertexCmpFn func(Vertex, Vertex) (b
|
|||||||
}
|
}
|
||||||
|
|
||||||
edge, exists := oldGraph.Adjacency()[vertex1][vertex2]
|
edge, exists := oldGraph.Adjacency()[vertex1][vertex2]
|
||||||
if !exists || edge.Name != e.Name { // TODO: edgeCmp
|
if !exists {
|
||||||
edge = e // use or overwrite edge
|
edge = e // use edge
|
||||||
|
} else if b, err := edgeCmpFn(edge, e); err != nil {
|
||||||
|
return errwrap.Wrapf(err, "edgeCmpFn failed")
|
||||||
|
} else if !b {
|
||||||
|
edge = e // overwrite edge
|
||||||
}
|
}
|
||||||
|
|
||||||
oldGraph.Adjacency()[vertex1][vertex2] = edge // store it (AddEdge)
|
oldGraph.Adjacency()[vertex1][vertex2] = edge // store it (AddEdge)
|
||||||
edgeKeep = append(edgeKeep, edge) // mark as saved
|
edgeKeep = append(edgeKeep, edge) // mark as saved
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ func (g *Graph) Graphviz() (out string) {
|
|||||||
for j := range g.Adjacency()[i] {
|
for j := range g.Adjacency()[i] {
|
||||||
k := g.Adjacency()[i][j]
|
k := g.Adjacency()[i][j]
|
||||||
// use str for clearer output ordering
|
// use str for clearer output ordering
|
||||||
if k.Notify {
|
//if fmtBoldFn(k) { // TODO: add this sort of formatting
|
||||||
str += fmt.Sprintf("\t\"%s\" -> \"%s\" [label=\"%s\",style=bold];\n", i, j, k.Name)
|
// str += fmt.Sprintf("\t\"%s\" -> \"%s\" [label=\"%s\",style=bold];\n", i, j, k)
|
||||||
} else {
|
//} else {
|
||||||
str += fmt.Sprintf("\t\"%s\" -> \"%s\" [label=\"%s\"];\n", i, j, k.Name)
|
str += fmt.Sprintf("\t\"%s\" -> \"%s\" [label=\"%s\"];\n", i, j, k)
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out += str
|
out += str
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
type Graph struct {
|
type Graph struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
adjacency map[Vertex]map[Vertex]*Edge // Vertex -> Vertex (edge)
|
adjacency map[Vertex]map[Vertex]Edge // Vertex -> Vertex (edge)
|
||||||
kv map[string]interface{} // some values associated with the graph
|
kv map[string]interface{} // some values associated with the graph
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,12 +44,10 @@ type Vertex interface {
|
|||||||
fmt.Stringer // String() string
|
fmt.Stringer // String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edge is the primary edge struct in this library.
|
// Edge is the primary edge struct in this library. It can be anything that
|
||||||
type Edge struct {
|
// implements Stringer. The string output must be stable and unique in a graph.
|
||||||
Name string
|
type Edge interface {
|
||||||
Notify bool // should we send a refresh notification along this edge?
|
fmt.Stringer // String() string
|
||||||
|
|
||||||
refresh bool // is there a notify pending for the dest vertex ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes the graph which populates all the internal structures.
|
// Init initializes the graph which populates all the internal structures.
|
||||||
@@ -58,7 +56,7 @@ func (g *Graph) Init() error {
|
|||||||
return fmt.Errorf("can't initialize graph with empty name")
|
return fmt.Errorf("can't initialize graph with empty name")
|
||||||
}
|
}
|
||||||
|
|
||||||
//g.adjacency = make(map[Vertex]map[Vertex]*Edge) // not required
|
//g.adjacency = make(map[Vertex]map[Vertex]Edge) // not required
|
||||||
//g.kv = make(map[string]interface{}) // not required
|
//g.kv = make(map[string]interface{}) // not required
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -81,21 +79,11 @@ func NewVertex(x Vertex) Vertex {
|
|||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEdge returns a new graph edge struct.
|
// NewEdge returns whatever was passed in. This is for compatibility with the
|
||||||
func NewEdge(name string) *Edge {
|
// usage of the old NewEdge method. This is considered deprecated.
|
||||||
return &Edge{
|
// FIXME: remove me
|
||||||
Name: name,
|
func NewEdge(x Edge) Edge {
|
||||||
}
|
return x
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh returns the pending refresh status of this edge.
|
|
||||||
func (obj *Edge) Refresh() bool {
|
|
||||||
return obj.refresh
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRefresh sets the pending refresh status of this edge.
|
|
||||||
func (obj *Edge) SetRefresh(b bool) {
|
|
||||||
obj.refresh = b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns a value stored alongside the graph in a particular key.
|
// Value returns a value stored alongside the graph in a particular key.
|
||||||
@@ -119,7 +107,7 @@ func (g *Graph) Copy() *Graph {
|
|||||||
}
|
}
|
||||||
newGraph := &Graph{
|
newGraph := &Graph{
|
||||||
Name: g.Name,
|
Name: g.Name,
|
||||||
adjacency: make(map[Vertex]map[Vertex]*Edge, len(g.adjacency)),
|
adjacency: make(map[Vertex]map[Vertex]Edge, len(g.adjacency)),
|
||||||
kv: g.kv,
|
kv: g.kv,
|
||||||
}
|
}
|
||||||
for k, v := range g.adjacency {
|
for k, v := range g.adjacency {
|
||||||
@@ -141,11 +129,11 @@ func (g *Graph) SetName(name string) {
|
|||||||
// AddVertex uses variadic input to add all listed vertices to the graph.
|
// AddVertex uses variadic input to add all listed vertices to the graph.
|
||||||
func (g *Graph) AddVertex(xv ...Vertex) {
|
func (g *Graph) AddVertex(xv ...Vertex) {
|
||||||
if g.adjacency == nil { // initialize on first use
|
if g.adjacency == nil { // initialize on first use
|
||||||
g.adjacency = make(map[Vertex]map[Vertex]*Edge)
|
g.adjacency = make(map[Vertex]map[Vertex]Edge)
|
||||||
}
|
}
|
||||||
for _, v := range xv {
|
for _, v := range xv {
|
||||||
if _, exists := g.adjacency[v]; !exists {
|
if _, exists := g.adjacency[v]; !exists {
|
||||||
g.adjacency[v] = make(map[Vertex]*Edge)
|
g.adjacency[v] = make(map[Vertex]Edge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +147,7 @@ func (g *Graph) DeleteVertex(v Vertex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddEdge adds a directed edge to the graph from v1 to v2.
|
// AddEdge adds a directed edge to the graph from v1 to v2.
|
||||||
func (g *Graph) AddEdge(v1, v2 Vertex, e *Edge) {
|
func (g *Graph) AddEdge(v1, v2 Vertex, e Edge) {
|
||||||
// NOTE: this doesn't allow more than one edge between two vertexes...
|
// NOTE: this doesn't allow more than one edge between two vertexes...
|
||||||
g.AddVertex(v1, v2) // supports adding N vertices now
|
g.AddVertex(v1, v2) // supports adding N vertices now
|
||||||
// TODO: check if an edge exists to avoid overwriting it!
|
// TODO: check if an edge exists to avoid overwriting it!
|
||||||
@@ -169,7 +157,7 @@ func (g *Graph) AddEdge(v1, v2 Vertex, e *Edge) {
|
|||||||
|
|
||||||
// DeleteEdge deletes a particular edge from the graph.
|
// DeleteEdge deletes a particular edge from the graph.
|
||||||
// FIXME: add test cases
|
// FIXME: add test cases
|
||||||
func (g *Graph) DeleteEdge(e *Edge) {
|
func (g *Graph) DeleteEdge(e Edge) {
|
||||||
for v1 := range g.adjacency {
|
for v1 := range g.adjacency {
|
||||||
for v2, edge := range g.adjacency[v1] {
|
for v2, edge := range g.adjacency[v1] {
|
||||||
if e == edge {
|
if e == edge {
|
||||||
@@ -218,7 +206,7 @@ func (g *Graph) NumEdges() int {
|
|||||||
// Adjacency returns the adjacency map representing this graph. This is useful
|
// Adjacency returns the adjacency map representing this graph. This is useful
|
||||||
// for users who which to operate on the raw data structure more efficiently.
|
// for users who which to operate on the raw data structure more efficiently.
|
||||||
// This works because maps are reference types so we can edit this at will.
|
// This works because maps are reference types so we can edit this at will.
|
||||||
func (g *Graph) Adjacency() map[Vertex]map[Vertex]*Edge {
|
func (g *Graph) Adjacency() map[Vertex]map[Vertex]Edge {
|
||||||
return g.adjacency
|
return g.adjacency
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,8 +291,8 @@ func (g *Graph) GraphVertices(v Vertex) []Vertex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IncomingGraphEdges returns all of the edges that point to vertex v (??? -> v).
|
// IncomingGraphEdges returns all of the edges that point to vertex v (??? -> v).
|
||||||
func (g *Graph) IncomingGraphEdges(v Vertex) []*Edge {
|
func (g *Graph) IncomingGraphEdges(v Vertex) []Edge {
|
||||||
var edges []*Edge
|
var edges []Edge
|
||||||
for v1 := range g.adjacency { // reverse paths
|
for v1 := range g.adjacency { // reverse paths
|
||||||
for v2, e := range g.adjacency[v1] {
|
for v2, e := range g.adjacency[v1] {
|
||||||
if v2 == v {
|
if v2 == v {
|
||||||
@@ -316,8 +304,8 @@ func (g *Graph) IncomingGraphEdges(v Vertex) []*Edge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OutgoingGraphEdges returns all of the edges that point from vertex v (v -> ???).
|
// OutgoingGraphEdges returns all of the edges that point from vertex v (v -> ???).
|
||||||
func (g *Graph) OutgoingGraphEdges(v Vertex) []*Edge {
|
func (g *Graph) OutgoingGraphEdges(v Vertex) []Edge {
|
||||||
var edges []*Edge
|
var edges []Edge
|
||||||
for _, e := range g.adjacency[v] { // forward paths
|
for _, e := range g.adjacency[v] { // forward paths
|
||||||
edges = append(edges, e)
|
edges = append(edges, e)
|
||||||
}
|
}
|
||||||
@@ -326,8 +314,8 @@ func (g *Graph) OutgoingGraphEdges(v Vertex) []*Edge {
|
|||||||
|
|
||||||
// GraphEdges returns an array (slice) of all edges that connect to vertex v.
|
// GraphEdges returns an array (slice) of all edges that connect to vertex v.
|
||||||
// This is the union of IncomingGraphEdges and OutgoingGraphEdges.
|
// This is the union of IncomingGraphEdges and OutgoingGraphEdges.
|
||||||
func (g *Graph) GraphEdges(v Vertex) []*Edge {
|
func (g *Graph) GraphEdges(v Vertex) []Edge {
|
||||||
var edges []*Edge
|
var edges []Edge
|
||||||
edges = append(edges, g.IncomingGraphEdges(v)...)
|
edges = append(edges, g.IncomingGraphEdges(v)...)
|
||||||
edges = append(edges, g.OutgoingGraphEdges(v)...)
|
edges = append(edges, g.OutgoingGraphEdges(v)...)
|
||||||
return edges
|
return edges
|
||||||
@@ -535,7 +523,7 @@ func VertexContains(needle Vertex, haystack []Vertex) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EdgeContains is an "in array" function to test for an edge in a slice of edges.
|
// EdgeContains is an "in array" function to test for an edge in a slice of edges.
|
||||||
func EdgeContains(needle *Edge, haystack []*Edge) bool {
|
func EdgeContains(needle Edge, haystack []Edge) bool {
|
||||||
for _, v := range haystack {
|
for _, v := range haystack {
|
||||||
if needle == v {
|
if needle == v {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type vertex struct {
|
|||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String is a required method of the Vertex interface we must fulfill.
|
// String is a required method of the Vertex interface that we must fulfill.
|
||||||
func (v *vertex) String() string {
|
func (v *vertex) String() string {
|
||||||
return v.name
|
return v.name
|
||||||
}
|
}
|
||||||
@@ -38,6 +38,22 @@ func NV(s string) Vertex {
|
|||||||
return NewVertex(obj)
|
return NewVertex(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// edge is a test struct to test the library.
|
||||||
|
type edge struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is a required method of the Edge interface that we must fulfill.
|
||||||
|
func (e *edge) String() string {
|
||||||
|
return e.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// NE is a helper function to make testing easier. It creates a new noop edge.
|
||||||
|
func NE(s string) Edge {
|
||||||
|
obj := &edge{s}
|
||||||
|
return NewEdge(obj)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPgraphT1(t *testing.T) {
|
func TestPgraphT1(t *testing.T) {
|
||||||
|
|
||||||
G := &Graph{}
|
G := &Graph{}
|
||||||
@@ -52,7 +68,7 @@ func TestPgraphT1(t *testing.T) {
|
|||||||
|
|
||||||
v1 := NV("v1")
|
v1 := NV("v1")
|
||||||
v2 := NV("v2")
|
v2 := NV("v2")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
|
|
||||||
if i := G.NumVertices(); i != 2 {
|
if i := G.NumVertices(); i != 2 {
|
||||||
@@ -73,12 +89,12 @@ func TestPgraphT2(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
//e6 := NewEdge("e6")
|
//e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v1, e3)
|
G.AddEdge(v3, v1, e3)
|
||||||
@@ -100,12 +116,12 @@ func TestPgraphT3(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
//e6 := NewEdge("e6")
|
//e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v1, e3)
|
G.AddEdge(v3, v1, e3)
|
||||||
@@ -138,9 +154,9 @@ func TestPgraphT4(t *testing.T) {
|
|||||||
v1 := NV("v1")
|
v1 := NV("v1")
|
||||||
v2 := NV("v2")
|
v2 := NV("v2")
|
||||||
v3 := NV("v3")
|
v3 := NV("v3")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v1, e3)
|
G.AddEdge(v3, v1, e3)
|
||||||
@@ -163,12 +179,12 @@ func TestPgraphT5(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
//e6 := NewEdge("e6")
|
//e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v1, e3)
|
G.AddEdge(v3, v1, e3)
|
||||||
@@ -196,12 +212,12 @@ func TestPgraphT6(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
//e6 := NewEdge("e6")
|
//e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v1, e3)
|
G.AddEdge(v3, v1, e3)
|
||||||
@@ -226,9 +242,9 @@ func TestPgraphT7(t *testing.T) {
|
|||||||
v1 := NV("v1")
|
v1 := NV("v1")
|
||||||
v2 := NV("v2")
|
v2 := NV("v2")
|
||||||
v3 := NV("v3")
|
v3 := NV("v3")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v1, e3)
|
G.AddEdge(v3, v1, e3)
|
||||||
@@ -300,12 +316,12 @@ func TestPgraphT9(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
e6 := NewEdge("e6")
|
e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v1, v3, e2)
|
G.AddEdge(v1, v3, e2)
|
||||||
G.AddEdge(v2, v4, e3)
|
G.AddEdge(v2, v4, e3)
|
||||||
@@ -376,12 +392,12 @@ func TestPgraphT10(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
e6 := NewEdge("e6")
|
e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v4, e3)
|
G.AddEdge(v3, v4, e3)
|
||||||
@@ -433,11 +449,11 @@ func TestPgraphReachability0(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v1, v4, e3)
|
G.AddEdge(v1, v4, e3)
|
||||||
@@ -467,12 +483,12 @@ func TestPgraphReachability1(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
//e6 := NewEdge("e6")
|
//e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v4, e3)
|
G.AddEdge(v3, v4, e3)
|
||||||
@@ -501,12 +517,12 @@ func TestPgraphReachability2(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
e6 := NewEdge("e6")
|
e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v1, v3, e2)
|
G.AddEdge(v1, v3, e2)
|
||||||
G.AddEdge(v2, v4, e3)
|
G.AddEdge(v2, v4, e3)
|
||||||
@@ -538,12 +554,12 @@ func TestPgraphReachability3(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
e6 := NewEdge("e6")
|
e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v4, e3)
|
G.AddEdge(v3, v4, e3)
|
||||||
@@ -573,12 +589,12 @@ func TestPgraphReachability4(t *testing.T) {
|
|||||||
v4 := NV("v4")
|
v4 := NV("v4")
|
||||||
v5 := NV("v5")
|
v5 := NV("v5")
|
||||||
v6 := NV("v6")
|
v6 := NV("v6")
|
||||||
e1 := NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := NewEdge("e4")
|
e4 := NE("e4")
|
||||||
e5 := NewEdge("e5")
|
e5 := NE("e5")
|
||||||
e6 := NewEdge("e6")
|
e6 := NE("e6")
|
||||||
G.AddEdge(v1, v2, e1)
|
G.AddEdge(v1, v2, e1)
|
||||||
G.AddEdge(v2, v3, e2)
|
G.AddEdge(v2, v3, e2)
|
||||||
G.AddEdge(v3, v4, e3)
|
G.AddEdge(v3, v4, e3)
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ func (obj *BaseRes) RefreshPending() bool {
|
|||||||
var refresh bool
|
var refresh bool
|
||||||
for _, edge := range obj.Graph.IncomingGraphEdges(obj.Vertex) {
|
for _, edge := range obj.Graph.IncomingGraphEdges(obj.Vertex) {
|
||||||
// if we asked for a notify *and* if one is pending!
|
// if we asked for a notify *and* if one is pending!
|
||||||
|
edge := edge.(*Edge) // panic if wrong
|
||||||
if edge.Notify && edge.Refresh() {
|
if edge.Notify && edge.Refresh() {
|
||||||
refresh = true
|
refresh = true
|
||||||
break
|
break
|
||||||
@@ -151,6 +152,7 @@ func (obj *BaseRes) RefreshPending() bool {
|
|||||||
// SetUpstreamRefresh sets the refresh value to any upstream vertices.
|
// SetUpstreamRefresh sets the refresh value to any upstream vertices.
|
||||||
func (obj *BaseRes) SetUpstreamRefresh(b bool) {
|
func (obj *BaseRes) SetUpstreamRefresh(b bool) {
|
||||||
for _, edge := range obj.Graph.IncomingGraphEdges(obj.Vertex) {
|
for _, edge := range obj.Graph.IncomingGraphEdges(obj.Vertex) {
|
||||||
|
edge := edge.(*Edge) // panic if wrong
|
||||||
if edge.Notify {
|
if edge.Notify {
|
||||||
edge.SetRefresh(b)
|
edge.SetRefresh(b)
|
||||||
}
|
}
|
||||||
@@ -160,6 +162,7 @@ func (obj *BaseRes) SetUpstreamRefresh(b bool) {
|
|||||||
// SetDownstreamRefresh sets the refresh value to any downstream vertices.
|
// SetDownstreamRefresh sets the refresh value to any downstream vertices.
|
||||||
func (obj *BaseRes) SetDownstreamRefresh(b bool) {
|
func (obj *BaseRes) SetDownstreamRefresh(b bool) {
|
||||||
for _, edge := range obj.Graph.OutgoingGraphEdges(obj.Vertex) {
|
for _, edge := range obj.Graph.OutgoingGraphEdges(obj.Vertex) {
|
||||||
|
edge := edge.(*Edge) // panic if wrong
|
||||||
// if we asked for a notify *and* if one is pending!
|
// if we asked for a notify *and* if one is pending!
|
||||||
if edge.Notify {
|
if edge.Notify {
|
||||||
edge.SetRefresh(b)
|
edge.SetRefresh(b)
|
||||||
|
|||||||
@@ -61,11 +61,13 @@ func addEdgesByMatchingUIDS(g *pgraph.Graph, v pgraph.Vertex, uids []ResUID) []b
|
|||||||
if uid.IsReversed() {
|
if uid.IsReversed() {
|
||||||
txt := fmt.Sprintf("AutoEdge: %s -> %s", VtoR(vv).String(), VtoR(v).String())
|
txt := fmt.Sprintf("AutoEdge: %s -> %s", VtoR(vv).String(), VtoR(v).String())
|
||||||
log.Printf("Compile: Adding %s", txt)
|
log.Printf("Compile: Adding %s", txt)
|
||||||
g.AddEdge(vv, v, pgraph.NewEdge(txt))
|
edge := &Edge{Name: txt}
|
||||||
|
g.AddEdge(vv, v, edge)
|
||||||
} else { // edges go the "normal" way, eg: pkg resource
|
} else { // edges go the "normal" way, eg: pkg resource
|
||||||
txt := fmt.Sprintf("AutoEdge: %s -> %s", VtoR(v).String(), VtoR(vv).String())
|
txt := fmt.Sprintf("AutoEdge: %s -> %s", VtoR(v).String(), VtoR(vv).String())
|
||||||
log.Printf("Compile: Adding %s", txt)
|
log.Printf("Compile: Adding %s", txt)
|
||||||
g.AddEdge(v, vv, pgraph.NewEdge(txt))
|
edge := &Edge{Name: txt}
|
||||||
|
g.AddEdge(v, vv, edge)
|
||||||
}
|
}
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ type AutoGrouper interface {
|
|||||||
vertexNext() (pgraph.Vertex, pgraph.Vertex, error) // mostly algorithmic
|
vertexNext() (pgraph.Vertex, pgraph.Vertex, error) // mostly algorithmic
|
||||||
vertexCmp(pgraph.Vertex, pgraph.Vertex) error // can we merge these ?
|
vertexCmp(pgraph.Vertex, pgraph.Vertex) error // can we merge these ?
|
||||||
vertexMerge(pgraph.Vertex, pgraph.Vertex) (pgraph.Vertex, error) // vertex merge fn to use
|
vertexMerge(pgraph.Vertex, pgraph.Vertex) (pgraph.Vertex, error) // vertex merge fn to use
|
||||||
edgeMerge(*pgraph.Edge, *pgraph.Edge) *pgraph.Edge // edge merge fn to use
|
edgeMerge(pgraph.Edge, pgraph.Edge) pgraph.Edge // edge merge fn to use
|
||||||
vertexTest(bool) (bool, error) // call until false
|
vertexTest(bool) (bool, error) // call until false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ func (ag *baseGrouper) vertexMerge(v1, v2 pgraph.Vertex) (v pgraph.Vertex, err e
|
|||||||
return // success or fail, and no need to merge the actual vertices!
|
return // success or fail, and no need to merge the actual vertices!
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ag *baseGrouper) edgeMerge(e1, e2 *pgraph.Edge) *pgraph.Edge {
|
func (ag *baseGrouper) edgeMerge(e1, e2 pgraph.Edge) pgraph.Edge {
|
||||||
return e1 // noop
|
return e1 // noop
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ func (ag *NonReachabilityGrouper) vertexNext() (v1, v2 pgraph.Vertex, err error)
|
|||||||
// and then by deleting v2 from the graph. Since more than one edge between two
|
// and then by deleting v2 from the graph. Since more than one edge between two
|
||||||
// vertices is not allowed, duplicate edges are merged as well. an edge merge
|
// vertices is not allowed, duplicate edges are merged as well. an edge merge
|
||||||
// function can be provided if you'd like to control how you merge the edges!
|
// function can be provided if you'd like to control how you merge the edges!
|
||||||
func VertexMerge(g *pgraph.Graph, v1, v2 pgraph.Vertex, vertexMergeFn func(pgraph.Vertex, pgraph.Vertex) (pgraph.Vertex, error), edgeMergeFn func(*pgraph.Edge, *pgraph.Edge) *pgraph.Edge) error {
|
func VertexMerge(g *pgraph.Graph, v1, v2 pgraph.Vertex, vertexMergeFn func(pgraph.Vertex, pgraph.Vertex) (pgraph.Vertex, error), edgeMergeFn func(pgraph.Edge, pgraph.Edge) pgraph.Edge) error {
|
||||||
// methodology
|
// methodology
|
||||||
// 1) edges between v1 and v2 are removed
|
// 1) edges between v1 and v2 are removed
|
||||||
//Loop:
|
//Loop:
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ import (
|
|||||||
"github.com/purpleidea/mgmt/util"
|
"github.com/purpleidea/mgmt/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NE is a helper function to make testing easier. It creates a new noop edge.
|
||||||
|
func NE(s string) pgraph.Edge {
|
||||||
|
obj := &Edge{Name: s}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
type testGrouper struct {
|
type testGrouper struct {
|
||||||
// TODO: this algorithm may not be correct in all cases. replace if needed!
|
// TODO: this algorithm may not be correct in all cases. replace if needed!
|
||||||
NonReachabilityGrouper // "inherit" what we want, and reimplement the rest
|
NonReachabilityGrouper // "inherit" what we want, and reimplement the rest
|
||||||
@@ -54,14 +60,16 @@ func (ag *testGrouper) vertexMerge(v1, v2 pgraph.Vertex) (v pgraph.Vertex, err e
|
|||||||
return // success or fail, and no need to merge the actual vertices!
|
return // success or fail, and no need to merge the actual vertices!
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ag *testGrouper) edgeMerge(e1, e2 *pgraph.Edge) *pgraph.Edge {
|
func (ag *testGrouper) edgeMerge(e1, e2 pgraph.Edge) pgraph.Edge {
|
||||||
|
edge1 := e1.(*Edge) // panic if wrong
|
||||||
|
edge2 := e2.(*Edge) // panic if wrong
|
||||||
// HACK: update the name so it makes a union of both names
|
// HACK: update the name so it makes a union of both names
|
||||||
n1 := strings.Split(e1.Name, ",") // load
|
n1 := strings.Split(edge1.Name, ",") // load
|
||||||
n2 := strings.Split(e2.Name, ",") // load
|
n2 := strings.Split(edge2.Name, ",") // load
|
||||||
names := append(n1, n2...)
|
names := append(n1, n2...)
|
||||||
names = util.StrRemoveDuplicatesInList(names) // remove duplicates
|
names = util.StrRemoveDuplicatesInList(names) // remove duplicates
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
return pgraph.NewEdge(strings.Join(names, ","))
|
return &Edge{Name: strings.Join(names, ",")}
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function
|
// helper function
|
||||||
@@ -161,7 +169,8 @@ Loop:
|
|||||||
|
|
||||||
for vv1, ee1 := range g1.Adjacency()[v1] {
|
for vv1, ee1 := range g1.Adjacency()[v1] {
|
||||||
vv2 := m[vv1]
|
vv2 := m[vv1]
|
||||||
ee2 := g2.Adjacency()[v2][vv2]
|
ee1 := ee1.(*Edge)
|
||||||
|
ee2 := g2.Adjacency()[v2][vv2].(*Edge)
|
||||||
|
|
||||||
// these are edges from v1 -> vv1 via ee1 (graph 1)
|
// these are edges from v1 -> vv1 via ee1 (graph 1)
|
||||||
// to cmp to edges from v2 -> vv2 via ee2 (graph 2)
|
// to cmp to edges from v2 -> vv2 via ee2 (graph 2)
|
||||||
@@ -240,7 +249,8 @@ func fullPrint(g *pgraph.Graph) (str string) {
|
|||||||
}
|
}
|
||||||
for v1 := range g.Adjacency() {
|
for v1 := range g.Adjacency() {
|
||||||
for v2, e := range g.Adjacency()[v1] {
|
for v2, e := range g.Adjacency()[v1] {
|
||||||
str += fmt.Sprintf("* e: %v -> %v # %v\n", VtoR(v1).GetName(), VtoR(v2).GetName(), e.Name)
|
edge := e.(*Edge)
|
||||||
|
str += fmt.Sprintf("* e: %v -> %v # %v\n", VtoR(v1).GetName(), VtoR(v2).GetName(), edge.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -460,8 +470,8 @@ func TestPgraphGrouping12(t *testing.T) {
|
|||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
g1.AddEdge(a1, b1, e1)
|
g1.AddEdge(a1, b1, e1)
|
||||||
g1.AddEdge(a2, b1, e2)
|
g1.AddEdge(a2, b1, e2)
|
||||||
}
|
}
|
||||||
@@ -469,7 +479,7 @@ func TestPgraphGrouping12(t *testing.T) {
|
|||||||
{
|
{
|
||||||
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
e := pgraph.NewEdge("e1,e2")
|
e := NE("e1,e2")
|
||||||
g2.AddEdge(a, b1, e)
|
g2.AddEdge(a, b1, e)
|
||||||
}
|
}
|
||||||
runGraphCmp(t, g1, g2)
|
runGraphCmp(t, g1, g2)
|
||||||
@@ -485,8 +495,8 @@ func TestPgraphGrouping13(t *testing.T) {
|
|||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
g1.AddEdge(b1, a1, e1)
|
g1.AddEdge(b1, a1, e1)
|
||||||
g1.AddEdge(b1, a2, e2)
|
g1.AddEdge(b1, a2, e2)
|
||||||
}
|
}
|
||||||
@@ -494,7 +504,7 @@ func TestPgraphGrouping13(t *testing.T) {
|
|||||||
{
|
{
|
||||||
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
e := pgraph.NewEdge("e1,e2")
|
e := NE("e1,e2")
|
||||||
g2.AddEdge(b1, a, e)
|
g2.AddEdge(b1, a, e)
|
||||||
}
|
}
|
||||||
runGraphCmp(t, g1, g2)
|
runGraphCmp(t, g1, g2)
|
||||||
@@ -511,9 +521,9 @@ func TestPgraphGrouping14(t *testing.T) {
|
|||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
a3 := pgraph.NewVertex(NewNoopResTest("a3"))
|
a3 := pgraph.NewVertex(NewNoopResTest("a3"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := pgraph.NewEdge("e3")
|
e3 := NE("e3")
|
||||||
g1.AddEdge(a1, b1, e1)
|
g1.AddEdge(a1, b1, e1)
|
||||||
g1.AddEdge(a2, b1, e2)
|
g1.AddEdge(a2, b1, e2)
|
||||||
g1.AddEdge(a3, b1, e3)
|
g1.AddEdge(a3, b1, e3)
|
||||||
@@ -522,7 +532,7 @@ func TestPgraphGrouping14(t *testing.T) {
|
|||||||
{
|
{
|
||||||
a := pgraph.NewVertex(NewNoopResTest("a1,a2,a3"))
|
a := pgraph.NewVertex(NewNoopResTest("a1,a2,a3"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
e := pgraph.NewEdge("e1,e2,e3")
|
e := NE("e1,e2,e3")
|
||||||
g2.AddEdge(a, b1, e)
|
g2.AddEdge(a, b1, e)
|
||||||
}
|
}
|
||||||
runGraphCmp(t, g1, g2)
|
runGraphCmp(t, g1, g2)
|
||||||
@@ -541,10 +551,10 @@ func TestPgraphGrouping15(t *testing.T) {
|
|||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
b2 := pgraph.NewVertex(NewNoopResTest("b2"))
|
b2 := pgraph.NewVertex(NewNoopResTest("b2"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := pgraph.NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := pgraph.NewEdge("e4")
|
e4 := NE("e4")
|
||||||
g1.AddEdge(a1, b1, e1)
|
g1.AddEdge(a1, b1, e1)
|
||||||
g1.AddEdge(a1, b2, e2)
|
g1.AddEdge(a1, b2, e2)
|
||||||
g1.AddEdge(b1, c1, e3)
|
g1.AddEdge(b1, c1, e3)
|
||||||
@@ -555,8 +565,8 @@ func TestPgraphGrouping15(t *testing.T) {
|
|||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
b := pgraph.NewVertex(NewNoopResTest("b1,b2"))
|
b := pgraph.NewVertex(NewNoopResTest("b1,b2"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1,e2")
|
e1 := NE("e1,e2")
|
||||||
e2 := pgraph.NewEdge("e3,e4")
|
e2 := NE("e3,e4")
|
||||||
g2.AddEdge(a1, b, e1)
|
g2.AddEdge(a1, b, e1)
|
||||||
g2.AddEdge(b, c1, e2)
|
g2.AddEdge(b, c1, e2)
|
||||||
}
|
}
|
||||||
@@ -578,9 +588,9 @@ func TestPgraphGrouping16(t *testing.T) {
|
|||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := pgraph.NewEdge("e3")
|
e3 := NE("e3")
|
||||||
g1.AddEdge(a1, b1, e1)
|
g1.AddEdge(a1, b1, e1)
|
||||||
g1.AddEdge(b1, c1, e2)
|
g1.AddEdge(b1, c1, e2)
|
||||||
g1.AddEdge(a2, c1, e3)
|
g1.AddEdge(a2, c1, e3)
|
||||||
@@ -590,8 +600,8 @@ func TestPgraphGrouping16(t *testing.T) {
|
|||||||
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1,e3")
|
e1 := NE("e1,e3")
|
||||||
e2 := pgraph.NewEdge("e2,e3") // e3 gets "merged through" to BOTH edges!
|
e2 := NE("e2,e3") // e3 gets "merged through" to BOTH edges!
|
||||||
g2.AddEdge(a, b1, e1)
|
g2.AddEdge(a, b1, e1)
|
||||||
g2.AddEdge(b1, c1, e2)
|
g2.AddEdge(b1, c1, e2)
|
||||||
}
|
}
|
||||||
@@ -611,9 +621,9 @@ func TestPgraphGrouping17(t *testing.T) {
|
|||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
b2 := pgraph.NewVertex(NewNoopResTest("b2"))
|
b2 := pgraph.NewVertex(NewNoopResTest("b2"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := pgraph.NewEdge("e3")
|
e3 := NE("e3")
|
||||||
g1.AddEdge(a1, b1, e1)
|
g1.AddEdge(a1, b1, e1)
|
||||||
g1.AddEdge(b1, c1, e2)
|
g1.AddEdge(b1, c1, e2)
|
||||||
g1.AddEdge(b2, c1, e3)
|
g1.AddEdge(b2, c1, e3)
|
||||||
@@ -623,8 +633,8 @@ func TestPgraphGrouping17(t *testing.T) {
|
|||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
b := pgraph.NewVertex(NewNoopResTest("b1,b2"))
|
b := pgraph.NewVertex(NewNoopResTest("b1,b2"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2,e3")
|
e2 := NE("e2,e3")
|
||||||
g2.AddEdge(a1, b, e1)
|
g2.AddEdge(a1, b, e1)
|
||||||
g2.AddEdge(b, c1, e2)
|
g2.AddEdge(b, c1, e2)
|
||||||
}
|
}
|
||||||
@@ -646,10 +656,10 @@ func TestPgraphGrouping18(t *testing.T) {
|
|||||||
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
b1 := pgraph.NewVertex(NewNoopResTest("b1"))
|
||||||
b2 := pgraph.NewVertex(NewNoopResTest("b2"))
|
b2 := pgraph.NewVertex(NewNoopResTest("b2"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
e3 := pgraph.NewEdge("e3")
|
e3 := NE("e3")
|
||||||
e4 := pgraph.NewEdge("e4")
|
e4 := NE("e4")
|
||||||
g1.AddEdge(a1, b1, e1)
|
g1.AddEdge(a1, b1, e1)
|
||||||
g1.AddEdge(b1, c1, e2)
|
g1.AddEdge(b1, c1, e2)
|
||||||
g1.AddEdge(a2, c1, e3)
|
g1.AddEdge(a2, c1, e3)
|
||||||
@@ -660,8 +670,8 @@ func TestPgraphGrouping18(t *testing.T) {
|
|||||||
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
a := pgraph.NewVertex(NewNoopResTest("a1,a2"))
|
||||||
b := pgraph.NewVertex(NewNoopResTest("b1,b2"))
|
b := pgraph.NewVertex(NewNoopResTest("b1,b2"))
|
||||||
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
c1 := pgraph.NewVertex(NewNoopResTest("c1"))
|
||||||
e1 := pgraph.NewEdge("e1,e3")
|
e1 := NE("e1,e3")
|
||||||
e2 := pgraph.NewEdge("e2,e3,e4") // e3 gets "merged through" to BOTH edges!
|
e2 := NE("e2,e3,e4") // e3 gets "merged through" to BOTH edges!
|
||||||
g2.AddEdge(a, b, e1)
|
g2.AddEdge(a, b, e1)
|
||||||
g2.AddEdge(b, c1, e2)
|
g2.AddEdge(b, c1, e2)
|
||||||
}
|
}
|
||||||
@@ -677,14 +687,14 @@ func TestPgraphGroupingConnected0(t *testing.T) {
|
|||||||
{
|
{
|
||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
g1.AddEdge(a1, a2, e1)
|
g1.AddEdge(a1, a2, e1)
|
||||||
}
|
}
|
||||||
g2, _ := pgraph.NewGraph("g2") // expected result ?
|
g2, _ := pgraph.NewGraph("g2") // expected result ?
|
||||||
{
|
{
|
||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
g2.AddEdge(a1, a2, e1)
|
g2.AddEdge(a1, a2, e1)
|
||||||
}
|
}
|
||||||
runGraphCmp(t, g1, g2)
|
runGraphCmp(t, g1, g2)
|
||||||
@@ -702,8 +712,8 @@ func TestPgraphGroupingConnected1(t *testing.T) {
|
|||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
b := pgraph.NewVertex(NewNoopResTest("b"))
|
b := pgraph.NewVertex(NewNoopResTest("b"))
|
||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
g1.AddEdge(a1, b, e1)
|
g1.AddEdge(a1, b, e1)
|
||||||
g1.AddEdge(b, a2, e2)
|
g1.AddEdge(b, a2, e2)
|
||||||
}
|
}
|
||||||
@@ -712,8 +722,8 @@ func TestPgraphGroupingConnected1(t *testing.T) {
|
|||||||
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
a1 := pgraph.NewVertex(NewNoopResTest("a1"))
|
||||||
b := pgraph.NewVertex(NewNoopResTest("b"))
|
b := pgraph.NewVertex(NewNoopResTest("b"))
|
||||||
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
a2 := pgraph.NewVertex(NewNoopResTest("a2"))
|
||||||
e1 := pgraph.NewEdge("e1")
|
e1 := NE("e1")
|
||||||
e2 := pgraph.NewEdge("e2")
|
e2 := NE("e2")
|
||||||
g2.AddEdge(a1, b, e1)
|
g2.AddEdge(a1, b, e1)
|
||||||
g2.AddEdge(b, a2, e2)
|
g2.AddEdge(b, a2, e2)
|
||||||
}
|
}
|
||||||
|
|||||||
41
resources/edge.go
Normal file
41
resources/edge.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// Mgmt
|
||||||
|
// Copyright (C) 2013-2017+ James Shubin and the project contributors
|
||||||
|
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package resources
|
||||||
|
|
||||||
|
// Edge is a struct that represents a graph's edge.
|
||||||
|
type Edge struct {
|
||||||
|
Name string
|
||||||
|
Notify bool // should we send a refresh notification along this edge?
|
||||||
|
|
||||||
|
refresh bool // is there a notify pending for the dest vertex ?
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is a required method of the Edge interface that we must fulfill.
|
||||||
|
func (obj *Edge) String() string {
|
||||||
|
return obj.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh returns the pending refresh status of this edge.
|
||||||
|
func (obj *Edge) Refresh() bool {
|
||||||
|
return obj.refresh
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRefresh sets the pending refresh status of this edge.
|
||||||
|
func (obj *Edge) SetRefresh(b bool) {
|
||||||
|
obj.refresh = b
|
||||||
|
}
|
||||||
@@ -247,8 +247,10 @@ func (c *GraphConfig) NewGraphFromConfig(hostname string, world resources.World,
|
|||||||
}
|
}
|
||||||
from := lookup[strings.ToLower(e.From.Kind)][e.From.Name]
|
from := lookup[strings.ToLower(e.From.Kind)][e.From.Name]
|
||||||
to := lookup[strings.ToLower(e.To.Kind)][e.To.Name]
|
to := lookup[strings.ToLower(e.To.Kind)][e.To.Name]
|
||||||
edge := pgraph.NewEdge(e.Name)
|
edge := &resources.Edge{
|
||||||
edge.Notify = e.Notify
|
Name: e.Name,
|
||||||
|
Notify: e.Notify,
|
||||||
|
}
|
||||||
graph.AddEdge(from, to, edge)
|
graph.AddEdge(from, to, edge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -293,8 +293,10 @@ func (c *GraphConfig) NewGraphFromConfig(hostname string, world resources.World,
|
|||||||
}
|
}
|
||||||
from := lookup[strings.ToLower(e.From.Kind)][e.From.Name]
|
from := lookup[strings.ToLower(e.From.Kind)][e.From.Name]
|
||||||
to := lookup[strings.ToLower(e.To.Kind)][e.To.Name]
|
to := lookup[strings.ToLower(e.To.Kind)][e.To.Name]
|
||||||
edge := pgraph.NewEdge(e.Name)
|
edge := &resources.Edge{
|
||||||
edge.Notify = e.Notify
|
Name: e.Name,
|
||||||
|
Notify: e.Notify,
|
||||||
|
}
|
||||||
graph.AddEdge(from, to, edge)
|
graph.AddEdge(from, to, edge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user