func (g *mutableDirected) AddArcs(arcs ...Arc) {
	if len(arcs) == 0 {
		return
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	g.addArcs(arcs...)
}
Adds arcs to the graph.
package al
import (
	. "github.com/sdboyer/gogl"
)
type mutableDirected struct {
	al_basic_mut
}
func (g *mutableDirected) 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 *mutableDirected) InDegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	return inDegreeOf(g, vertex)
}
func (g *mutableDirected) 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 *mutableDirected) Edges(f EdgeStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for source, adjacent := range g.list {
		for target := range adjacent {
			if f(NewEdge(source, target)) {
				return
			}
		}
	}
}
func (g *mutableDirected) Arcs(f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for source, adjacent := range g.list {
		for target := range adjacent {
			if f(NewArc(source, target)) {
				return
			}
		}
	}
}
func (g *mutableDirected) IncidentTo(v Vertex, f EdgeStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachEdgeIncidentToDirected(g, v, f)
}
func (g *mutableDirected) 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 *mutableDirected) ArcsFrom(v Vertex, f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if !g.hasVertex(v) {
		return
	}
	for adjacent := range g.list[v] {
		if f(NewArc(v, adjacent)) {
			return
		}
	}
}
func (g *mutableDirected) SuccessorsOf(v Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachVertexInAdjacencyList(g.list, v, f)
}
func (g *mutableDirected) 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 := range adjacent {
			if target == v {
				if f(NewArc(candidate, target)) {
					return
				}
			}
		}
	}
}
func (g *mutableDirected) PredecessorsOf(v Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachPredecessorOf(g.list, v, f)
}
func (g *mutableDirected) 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 *mutableDirected) HasArc(arc Arc) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	_, exists := g.list[arc.Source()][arc.Target()]
	return exists
}
func (g *mutableDirected) Density() float64 {
	g.mu.RLock()
	defer g.mu.RUnlock()
	order := g.Order()
	return float64(g.Size()) / float64(order*(order-1))
}
func (g *mutableDirected) RemoveVertex(vertices ...Vertex) {
	if len(vertices) == 0 {
		return
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	for _, vertex := range vertices {
		if g.hasVertex(vertex) {
			g.size -= len(g.list[vertex])
			delete(g.list, vertex)
			for _, adjacent := range g.list {
				if _, has := adjacent[vertex]; has {
					delete(adjacent, vertex)
					g.size--
				}
			}
		}
	}
	return
}