Remove sync.Once from dag.Graph

dag.Graph is used as a value, but contains a sync data structure. This
prevents copying the value, and is needed if one wants to upgrade a Graph
to an AcyclicGraph.

The sync.Once only guards the init() method, which can be guarded
internally with nil checks on the fields. The init method could be
removed entirely with a proper constructor later on of we so choose.
This commit is contained in:
James Bardin 2016-11-10 18:05:30 -05:00
parent 916d3522b1
commit f37b2fafed
2 changed files with 18 additions and 12 deletions

View File

@ -6,7 +6,6 @@ import (
"fmt"
"io"
"sort"
"sync"
)
// Graph is used to represent a dependency graph.
@ -15,7 +14,6 @@ type Graph struct {
edges *Set
downEdges map[interface{}]*Set
upEdges map[interface{}]*Set
once sync.Once
// JSON encoder for recording debug information
debug *encoder
@ -108,7 +106,7 @@ func (g *Graph) HasEdge(e Edge) bool {
// Add adds a vertex to the graph. This is safe to call multiple time with
// the same Vertex.
func (g *Graph) Add(v Vertex) Vertex {
g.once.Do(g.init)
g.init()
g.vertices.Add(v)
g.debug.Add(v)
return v
@ -165,7 +163,7 @@ func (g *Graph) Replace(original, replacement Vertex) bool {
// RemoveEdge removes an edge from the graph.
func (g *Graph) RemoveEdge(edge Edge) {
g.once.Do(g.init)
g.init()
g.debug.RemoveEdge(edge)
// Delete the edge from the set
@ -182,13 +180,13 @@ func (g *Graph) RemoveEdge(edge Edge) {
// DownEdges returns the outward edges from the source Vertex v.
func (g *Graph) DownEdges(v Vertex) *Set {
g.once.Do(g.init)
g.init()
return g.downEdges[hashcode(v)]
}
// UpEdges returns the inward edges to the destination Vertex v.
func (g *Graph) UpEdges(v Vertex) *Set {
g.once.Do(g.init)
g.init()
return g.upEdges[hashcode(v)]
}
@ -197,7 +195,7 @@ func (g *Graph) UpEdges(v Vertex) *Set {
// verified through pointer equality of the vertices, not through the
// value of the edge itself.
func (g *Graph) Connect(edge Edge) {
g.once.Do(g.init)
g.init()
g.debug.Connect(edge)
source := edge.Source()
@ -312,11 +310,19 @@ func (g *Graph) String() string {
}
func (g *Graph) init() {
if g.vertices == nil {
g.vertices = new(Set)
}
if g.edges == nil {
g.edges = new(Set)
}
if g.downEdges == nil {
g.downEdges = make(map[interface{}]*Set)
}
if g.upEdges == nil {
g.upEdges = make(map[interface{}]*Set)
}
}
// Dot returns a dot-formatted representation of the Graph.
func (g *Graph) Dot(opts *DotOpts) []byte {

View File

@ -175,7 +175,7 @@ func TestGraphJSON_annotations(t *testing.T) {
}
found3 = true
default:
t.Fatalf("unexpected annotation:", va)
t.Fatalf("unexpected annotation: %#v", va)
}
case "EdgeAnnotation":
ea := &edgeAnnotation{}