Documentation ¶
Index ¶
- func StronglyConnected(g *Graph) [][]Vertex
- func VertexName(raw Vertex) string
- type AcyclicGraph
- func (g *AcyclicGraph) Ancestors(v Vertex) (*Set, error)
- func (g *AcyclicGraph) Cycles() [][]Vertex
- func (g *AcyclicGraph) DepthFirstWalk(start []Vertex, f DepthWalkFunc) error
- func (g *AcyclicGraph) DepthFirstWalkWithOptionalSort(start []Vertex, sorted bool, f DepthWalkFunc) error
- func (g *AcyclicGraph) Descendents(v Vertex) (*Set, error)
- func (g *AcyclicGraph) DirectedGraph() Grapher
- func (g *AcyclicGraph) Isolate(start Vertex) *AcyclicGraph
- func (g *AcyclicGraph) ReverseDepthFirstWalk(start []Vertex, f DepthWalkFunc) error
- func (g *AcyclicGraph) Root() (Vertex, error)
- func (g *AcyclicGraph) TopologicalSort(start Vertex) []Vertex
- func (g *AcyclicGraph) TransitiveReduction()
- func (g *AcyclicGraph) Validate() error
- func (g *AcyclicGraph) Walk(cb WalkFunc) tfdiags.Diagnostics
- func (g AcyclicGraph) WalkWithErr(walk WalkFuncWithErr) error
- type ByVertexName
- type DebugOperationEnd
- type DepthWalkFunc
- type DotNode
- type DotOpts
- type Edge
- type Graph
- func (g *Graph) Add(v Vertex) Vertex
- func (g *Graph) Connect(edge Edge)
- func (g *Graph) DebugEdgeInfo(e Edge, info string)
- func (g *Graph) DebugOperation(operation string, info string) DebugOperationEnd
- func (g *Graph) DebugVertexInfo(v Vertex, info string)
- func (g *Graph) DebugVisitInfo(v Vertex, info string)
- func (g *Graph) DirectedGraph() Grapher
- func (g *Graph) Dot(opts *DotOpts) []byte
- func (g *Graph) DownEdges(v Vertex) *Set
- func (g *Graph) Edges() []Edge
- func (g *Graph) EdgesFrom(v Vertex) []Edge
- func (g *Graph) EdgesTo(v Vertex) []Edge
- func (g *Graph) HasEdge(e Edge) bool
- func (g *Graph) HasVertex(v Vertex) bool
- func (g *Graph) MarshalJSON() ([]byte, error)
- func (g *Graph) Remove(v Vertex) Vertex
- func (g *Graph) RemoveEdge(edge Edge)
- func (g *Graph) Replace(original, replacement Vertex) bool
- func (g *Graph) SetDebugWriter(w io.Writer)
- func (g *Graph) String() string
- func (g *Graph) StringWithNodeTypes() string
- func (g *Graph) UpEdges(v Vertex) *Set
- func (g *Graph) Vertices() []Vertex
- type GraphNodeDotter
- type Grapher
- type Hashable
- type NamedVertex
- type Set
- func (s *Set) Add(v interface{})
- func (s *Set) Delete(v interface{})
- func (s *Set) Difference(other *Set) *Set
- func (s *Set) Filter(cb func(interface{}) bool) *Set
- func (s *Set) Include(v interface{}) bool
- func (s *Set) Intersection(other *Set) *Set
- func (s *Set) Len() int
- func (s *Set) List() []interface{}
- type Subgrapher
- type Vertex
- type WalkFunc
- type WalkFuncWithErr
- type Walker
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StronglyConnected ¶
StronglyConnected returns the list of strongly connected components within the Graph g. This information is primarily used by this package for cycle detection, but strongly connected components have widespread use.
Types ¶
type AcyclicGraph ¶
type AcyclicGraph struct {
Graph
}
AcyclicGraph is a specialization of Graph that cannot have cycles. With this property, we get the property of sane graph traversal.
func (*AcyclicGraph) Ancestors ¶
func (g *AcyclicGraph) Ancestors(v Vertex) (*Set, error)
Ancestors returns a Set that includes every Vertex yielded by walking down from the provided starting Vertex v.
func (*AcyclicGraph) Cycles ¶
func (g *AcyclicGraph) Cycles() [][]Vertex
Cycles detects a strongly connected graph and returns a set of cycles if present
func (*AcyclicGraph) DepthFirstWalk ¶
func (g *AcyclicGraph) DepthFirstWalk(start []Vertex, f DepthWalkFunc) error
DepthFirstWalkWithOptionalSort does a depth-first walk of the graph starting from the vertices in start.
func (*AcyclicGraph) DepthFirstWalkWithOptionalSort ¶
func (g *AcyclicGraph) DepthFirstWalkWithOptionalSort(start []Vertex, sorted bool, f DepthWalkFunc) error
DepthFirstWalkWithOptionalSort This internal method provides the option of not sorting the vertices during the walk, which we use for the Transitive reduction. Some configurations can lead to fully-connected subgraphs, which makes our transitive reduction algorithm O(n^3). This is still passable for the size of our graphs, but the additional n^2 sort operations would make this uncomputable in a reasonable amount of time.
func (*AcyclicGraph) Descendents ¶
func (g *AcyclicGraph) Descendents(v Vertex) (*Set, error)
Descendents returns a Set that includes every Vertex yielded by walking up from the provided starting Vertex v.
func (*AcyclicGraph) DirectedGraph ¶
func (g *AcyclicGraph) DirectedGraph() Grapher
func (*AcyclicGraph) Isolate ¶
func (g *AcyclicGraph) Isolate(start Vertex) *AcyclicGraph
Isolate returns an isolated sub graph from the starting vertex
func (*AcyclicGraph) ReverseDepthFirstWalk ¶
func (g *AcyclicGraph) ReverseDepthFirstWalk(start []Vertex, f DepthWalkFunc) error
ReverseDepthFirstWalk does a depth-first walk _up_ the graph starting from the vertices in start.
func (*AcyclicGraph) Root ¶
func (g *AcyclicGraph) Root() (Vertex, error)
Root returns the root of the DAG, or an error.
Complexity: O(V)
func (*AcyclicGraph) TopologicalSort ¶
func (g *AcyclicGraph) TopologicalSort(start Vertex) []Vertex
TopologicalSort of a directed graph is a linear ordering of its vertices such that for every directed edge uv from vertex u to vertex v, u comes before v in the ordering. This function sorts the vertices by their name to be deterministic.
func (*AcyclicGraph) TransitiveReduction ¶
func (g *AcyclicGraph) TransitiveReduction()
TransitiveReduction performs the transitive reduction of graph g in place. The transitive reduction of a graph is a graph with as few edges as possible with the same reachability as the original graph. This means that if there are three nodes A => B => C, and A connects to both B and C, and B connects to C, then the transitive reduction is the same graph with only a single edge between A and B, and a single edge between B and C.
The graph must be valid for this operation to behave properly. If Validate() returns an error, the behavior is undefined and the results will likely be unexpected.
Complexity: O(V(V+E)), or asymptotically O(VE)
func (*AcyclicGraph) Validate ¶
func (g *AcyclicGraph) Validate() error
Validate validates the DAG. A DAG is valid if it has a single root with no cycles.
func (*AcyclicGraph) Walk ¶
func (g *AcyclicGraph) Walk(cb WalkFunc) tfdiags.Diagnostics
Walk walks the graph, calling your callback as each node is visited. This will walk nodes in parallel if it can. The resulting diagnostics contains problems from all graphs visited, in no particular order.
func (AcyclicGraph) WalkWithErr ¶
func (g AcyclicGraph) WalkWithErr(walk WalkFuncWithErr) error
WalkWithErr an idiomatic wrapper around the terraform walk func that uses diagnostic errors
type ByVertexName ¶
type ByVertexName []Vertex
ByVertexName implements sort.Interface so a list of Vertices can be sorted consistently by their VertexName
func (ByVertexName) Len ¶
func (b ByVertexName) Len() int
func (ByVertexName) Less ¶
func (b ByVertexName) Less(i, j int) bool
func (ByVertexName) Swap ¶
func (b ByVertexName) Swap(i, j int)
type DebugOperationEnd ¶
type DebugOperationEnd func(string)
The DebugOperationEnd func type provides a way to call an End function via a method call, allowing for the chaining of methods in a defer statement.
func (DebugOperationEnd) End ¶
func (e DebugOperationEnd) End(info string)
End calls function e with the info parameter, marking the end of this operation in the logs.
type DepthWalkFunc ¶
DepthWalkFunc is a walk function that also receives the current depth of the walk as an argument
type DotNode ¶
DotNode provides a structure for Vertices to return in order to specify their dot format.
type DotOpts ¶
type DotOpts struct { // Allows some nodes to decide to only show themselves when the user has // requested the "verbose" graph. Verbose bool // Highlight Cycles DrawCycles bool // How many levels to expand modules as we draw MaxDepth int // contains filtered or unexported fields }
DotOpts are the options for generating a dot formatted Graph.
type Graph ¶
type Graph struct {
// contains filtered or unexported fields
}
Graph is used to represent a dependency graph.
func (*Graph) Add ¶
Add adds a vertex to the graph. This is safe to call multiple time with the same Vertex.
func (*Graph) Connect ¶
Connect adds an edge with the given source and target. This is safe to call multiple times with the same value. Note that the same value is verified through pointer equality of the vertices, not through the value of the edge itself.
func (*Graph) DebugEdgeInfo ¶
DebugEdgeInfo encodes arbitrary information about an edge in the graph debug logs.
func (*Graph) DebugOperation ¶
func (g *Graph) DebugOperation(operation string, info string) DebugOperationEnd
DebugOperation marks the start of a set of graph transformations in the debug log, and returns a DebugOperationEnd func, which marks the end of the operation in the log. Additional information can be added to the log via the info parameter.
The returned func's End method allows this method to be called from a single defer statement:
defer g.DebugOperationBegin("OpName", "operating").End("")
The returned function must be called to properly close the logical operation in the logs.
func (*Graph) DebugVertexInfo ¶
DebugVertexInfo encodes arbitrary information about a vertex in the graph debug logs.
func (*Graph) DebugVisitInfo ¶
DebugVisitInfo records a visit to a Vertex during a walk operation.
func (*Graph) DirectedGraph ¶
func (*Graph) MarshalJSON ¶
MarshalJSON returns a JSON representation of the entire Graph.
func (*Graph) Remove ¶
Remove removes a vertex from the graph. This will also remove any edges with this vertex as a source or target.
func (*Graph) RemoveEdge ¶
RemoveEdge removes an edge from the graph.
func (*Graph) Replace ¶
Replace replaces the original Vertex with replacement. If the original does not exist within the graph, then false is returned. Otherwise, true is returned.
func (*Graph) SetDebugWriter ¶
SetDebugWriter sets the io.Writer where the Graph will record debug information. After this is set, the graph will immediately encode itself to the stream, and continue to record all subsequent operations.
func (*Graph) StringWithNodeTypes ¶
StringWithNodeTypes outputs some human-friendly output for the graph structure.
type GraphNodeDotter ¶
type GraphNodeDotter interface { // Dot is called to return the dot formatting for the node. // The first parameter is the title of the node. // The second parameter includes user-specified options that affect the dot // graph. See GraphDotOpts below for details. DotNode(string, *DotOpts) *DotNode }
GraphNodeDotter can be implemented by a node to cause it to be included in the dot graph. The Dot method will be called which is expected to return a representation of this node.
type Grapher ¶
type Grapher interface {
DirectedGraph() Grapher
}
A Grapher is any type that returns a Grapher, mainly used to identify dag.Graph and dag.AcyclicGraph. In the case of Graph and AcyclicGraph, they return themselves.
type Hashable ¶
type Hashable interface {
Hashcode() interface{}
}
Hashable is the interface used by set to get the hash code of a value. If this isn't given, then the value of the item being added to the set itself is used as the comparison value.
type NamedVertex ¶
NamedVertex is an optional interface that can be implemented by Vertex to give it a human-friendly name that is used for outputting the graph.
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is a set data structure.
func (*Set) Difference ¶
Difference returns a set with the elements that s has but other doesn't.
func (*Set) Filter ¶
Filter returns a set that contains the elements from the receiver where the given callback returns true.
func (*Set) Intersection ¶
Intersection computes the set intersection with other.
type Subgrapher ¶
type Subgrapher interface {
Subgraph() Grapher
}
Subgrapher allows a Vertex to be a Graph itself, by returning a Grapher.
type WalkFunc ¶
type WalkFunc func(Vertex) tfdiags.Diagnostics
WalkFunc is the callback used for walking the graph.
type WalkFuncWithErr ¶
WalkFuncWithErr an alias for WalkFunc that returns standard go errors instead of terraform diagnostics
type Walker ¶
type Walker struct { // Callback is what is called for each vertex Callback WalkFunc // Reverse, if true, causes the source of an edge to depend on a target. // When false (default), the target depends on the source. Reverse bool // contains filtered or unexported fields }
Walker is used to walk every vertex of a graph in parallel.
A vertex will only be walked when the dependencies of that vertex have been walked. If two vertices can be walked at the same time, they will be.
Update can be called to update the graph. This can be called even during a walk, changing vertices/edges mid-walk. This should be done carefully. If a vertex is removed but has already been executed, the result of that execution (any error) is still returned by Wait. Changing or re-adding a vertex that has already executed has no effect. Changing edges of a vertex that has already executed has no effect.
Non-parallelism can be enforced by introducing a lock in your callback function. However, the goroutine overhead of a walk will remain. Walker will create V*2 goroutines (one for each vertex, and dependency waiter for each vertex). In general this should be of no concern unless there are a huge number of vertices.
The walk is depth first by default. This can be changed with the Reverse option.
A single walker is only valid for one graph walk. After the walk is complete you must construct a new walker to walk again. State for the walk is never deleted in case vertices or edges are changed.
func (*Walker) Update ¶
func (w *Walker) Update(g *AcyclicGraph)
Update updates the currently executing walk with the given graph. This will perform a diff of the vertices and edges and update the walker. Already completed vertices remain completed (including any errors during their execution).
This returns immediately once the walker is updated; it does not wait for completion of the walk.
Multiple Updates can be called in parallel. Update can be called at any time during a walk.
func (*Walker) Wait ¶
func (w *Walker) Wait() tfdiags.Diagnostics
Wait waits for the completion of the walk and returns diagnostics describing any problems that arose. Update should be called to populate the walk with vertices and edges prior to calling this.
Wait will return as soon as all currently known vertices are complete. If you plan on calling Update with more vertices in the future, you should not call Wait until after this is done.