func (g *dataDirected) HasDataArc(arc DataArc) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if data, exists := g.list[arc.Source()][arc.Target()]; exists {
		return data == arc.Data()
	}
	return false
}
Indicates whether or not the given data arc is present in the graph.
It will only match if the provided DataEdge has the same data as
the edge contained in the graph.
package al
import (
	"sync"
	. "github.com/sdboyer/gogl"
	"gopkg.in/fatih/set.v0"
)
type baseData struct {
	list map[Vertex]map[Vertex]interface{}
	size int
	mu   sync.RWMutex
}
func (g *baseData) Vertices(f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for v := range g.list {
		if f(v) {
			return
		}
	}
}
func (g *baseData) HasVertex(vertex Vertex) (exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	exists = g.hasVertex(vertex)
	return
}
func (g *baseData) hasVertex(vertex Vertex) (exists bool) {
	_, exists = g.list[vertex]
	return
}
func (g *baseData) Order() int {
	g.mu.RLock()
	defer g.mu.RUnlock()
	return len(g.list)
}
func (g *baseData) Size() int {
	return g.size
}
func (g *baseData) EnsureVertex(vertices ...Vertex) {
	if len(vertices) == 0 {
		return
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	g.ensureVertex(vertices...)
}
func (g *baseData) ensureVertex(vertices ...Vertex) {
	for _, vertex := range vertices {
		if !g.hasVertex(vertex) {
			g.list[vertex] = make(map[Vertex]interface{}, 10)
		}
	}
	return
}
type dataDirected struct {
	baseData
}
func (g *dataDirected) OutDegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if exists = g.hasVertex(vertex); exists {
		degree = len(g.list[vertex])
	}
	return
}
func (g *dataDirected) InDegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	return inDegreeOf(g, vertex)
}
func (g *dataDirected) DegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	indegree, exists := inDegreeOf(g, vertex)
	outdegree, exists := g.OutDegreeOf(vertex)
	return indegree + outdegree, exists
}
func (g *dataDirected) IncidentTo(v Vertex, f EdgeStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachEdgeIncidentToDirected(g, v, f)
}
func (g *dataDirected) AdjacentTo(start Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	g.IncidentTo(start, func(e Edge) bool {
		u, v := e.Both()
		if u == start {
			return f(v)
		} else {
			return f(u)
		}
	})
}
func (g *dataDirected) ArcsFrom(v Vertex, f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if !g.hasVertex(v) {
		return
	}
	for adjacent, data := range g.list[v] {
		if f(NewDataArc(v, adjacent, data)) {
			return
		}
	}
}
func (g *dataDirected) SuccessorsOf(v Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachVertexInAdjacencyList(g.list, v, f)
}
func (g *dataDirected) ArcsTo(v Vertex, f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if !g.hasVertex(v) {
		return
	}
	for candidate, adjacent := range g.list {
		for target, data := range adjacent {
			if target == v {
				if f(NewDataArc(candidate, target, data)) {
					return
				}
			}
		}
	}
}
func (g *dataDirected) PredecessorsOf(v Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachPredecessorOf(g.list, v, f)
}
func (g *dataDirected) Edges(f EdgeStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for source, adjacent := range g.list {
		for target, data := range adjacent {
			if f(NewDataEdge(source, target, data)) {
				return
			}
		}
	}
}
func (g *dataDirected) Arcs(f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for source, adjacent := range g.list {
		for target, data := range adjacent {
			if f(NewDataArc(source, target, data)) {
				return
			}
		}
	}
}
func (g *dataDirected) HasEdge(edge Edge) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	u, v := edge.Both()
	_, exists := g.list[u][v]
	if !exists {
		_, exists = g.list[v][u]
	}
	return exists
}
func (g *dataDirected) HasArc(arc Arc) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	_, exists := g.list[arc.Source()][arc.Target()]
	return exists
}
func (g *dataDirected) HasDataEdge(edge DataEdge) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	u, v := edge.Both()
	if data, exists := g.list[u][v]; exists {
		return data == edge.Data()
	} else if data, exists = g.list[v][u]; exists {
		return data == edge.Data()
	}
	return false
}