pub struct Graph { /* private fields */ }Expand description
An acyclic, directed graph made up of nodes/functions and edges/resources.
Notably nodes may have additional run requirements added to them besides input/output requirements. These include:
- barriers
- run before node
- run after node
See the module documentation for Node for more info on constructing
nodes with granular constraints.
Implementationsยง
sourceยงimpl Graph
impl Graph
sourcepub fn node<Input, Output, F: IsGraphNode<Input, Output>>(
f: F
) -> Node<Function, TypeKey>
pub fn node<Input, Output, F: IsGraphNode<Input, Output>>( f: F ) -> Node<Function, TypeKey>
Creates a graph node from an Fn closure.
A node in the graph is a boxed Rust closure that may do any or all the following:
- Create resources by returning a result that implements
NodeResults. - Consume one or more resources by having a field in the input parameter
wrapped in
Move. The resource will not be available in the graph after the node is run. - Read one or more resources by having a field in the input parameter
wrapped in
View. - Write one or more resources by having a field in the input parameter
wrapped in
ViewMut.
By default IsGraphNode is implemented for functions that take one
parameter implementing Edges and returning a Result where the โokโ
type implements NodeResults.
sourcepub fn local<Input, Output>() -> Node<Function, TypeKey>
pub fn local<Input, Output>() -> Node<Function, TypeKey>
Creates a graph node without a closure, to be supplied later with
Graph::run_with_local.
The returned node may be added to a graph and scheduled, allowing closures with local scope requirements to fit into the graph.
At this time only one local node is allowed.
sourcepub fn merge(lhs: Graph, rhs: Graph) -> Graph
๐Deprecated since 0.3.3: Ambiguous name. Replaced by interleave_subgraph and add_subgraph. Use Graph::interleave_subgraph instead as a direct replacment.
pub fn merge(lhs: Graph, rhs: Graph) -> Graph
interleave_subgraph and add_subgraph. Use Graph::interleave_subgraph instead as a direct replacment.Merge two graphs, preferring the right in cases of key collisions.
The values of rhs will override those of lhs.
sourcepub fn interleave_subgraph(&mut self, rhs: Graph) -> &mut Self
pub fn interleave_subgraph(&mut self, rhs: Graph) -> &mut Self
Add a subgraph, preferring the right in cases of key collisions.
The values of rhs will override those of self.
Barriers in each graph will be considered equal. This has the effect
that after adding the subgraph, nodes in rhs may run at the same
time as nodes in lhs if their barrier matches.
This is analogous to adding each graphโs nodes in an interleaving order, sorted by their barrier.
Example:
use moongraph::{graph, Graph, GraphError, ViewMut};
fn one(_: ()) -> Result<(), GraphError> {
log::trace!("one");
Ok(())
}
fn two(mut an_f32: ViewMut<f32>) -> Result<(), GraphError> {
log::trace!("two");
*an_f32 += 1.0;
Ok(())
}
fn three(_: ()) -> Result<(), GraphError> {
log::trace!("three");
Ok(())
}
fn four(_: ()) -> Result<(), GraphError> {
log::trace!("four");
Ok(())
}
let mut one_two = graph!(one < two).with_barrier();
assert_eq!(1, one_two.get_barrier());
let three_four = graph!(three < four);
assert_eq!(0, three_four.get_barrier());
one_two.interleave_subgraph(three_four);
one_two.reschedule().unwrap();
assert_eq!(
vec![vec!["one", "three"], vec!["four", "two"]],
one_two.get_schedule()
);sourcepub fn add_subgraph(&mut self, rhs: Graph) -> &mut Self
pub fn add_subgraph(&mut self, rhs: Graph) -> &mut Self
Add a subgraph, preferring the right in cases of key collisions.
The values of rhs will override those of self.
Barriers will be kept in place, though barriers in rhs will be
incremented by self.barrier. This has the effect that after adding the
subgraph, nodes in rhs will run after the last barrier in self,
or later if rhs has barriers of its own.
This is analogous to adding all of the nodes in rhs, one by one, to
self - while keeping the constraints of rhs in place.
Example:
use moongraph::{graph, Graph, GraphError, ViewMut};
fn one(_: ()) -> Result<(), GraphError> {
log::trace!("one");
Ok(())
}
fn two(mut an_f32: ViewMut<f32>) -> Result<(), GraphError> {
log::trace!("two");
*an_f32 += 1.0;
Ok(())
}
fn three(_: ()) -> Result<(), GraphError> {
log::trace!("three");
Ok(())
}
fn four(_: ()) -> Result<(), GraphError> {
log::trace!("four");
Ok(())
}
let mut one_two = graph!(one < two).with_barrier();
assert_eq!(1, one_two.get_barrier());
let three_four = graph!(three < four);
assert_eq!(0, three_four.get_barrier());
one_two.add_subgraph(three_four);
one_two.reschedule().unwrap();
assert_eq!(
vec![vec!["one"], vec!["two"], vec!["three"], vec!["four"]],
one_two.get_schedule()
);sourcepub fn reschedule(&mut self) -> Result<(), GraphError>
pub fn reschedule(&mut self) -> Result<(), GraphError>
Reschedule all functions.
If the functions were already scheduled this will unscheduled them first.
sourcepub fn get_schedule(&self) -> Vec<Vec<&str>>
pub fn get_schedule(&self) -> Vec<Vec<&str>>
Return the names of scheduled nodes.
If no nodes have been scheduled this will return an empty vector.
Use Graph::reschedule to manually schedule the nodes before calling
this.
sourcepub fn get_schedule_and_resources(&self) -> Vec<Vec<(&str, Vec<&str>)>>
pub fn get_schedule_and_resources(&self) -> Vec<Vec<(&str, Vec<&str>)>>
Return the names of scheduled nodes along with the names of their resources.
If no nodes have been scheduled this will return an empty vector.
Use Graph::reschedule to manually schedule the nodes before calling
this.
sourcepub fn nodes(&self) -> impl Iterator<Item = &Node<Function, TypeKey>>
pub fn nodes(&self) -> impl Iterator<Item = &Node<Function, TypeKey>>
An iterator over all nodes.
sourcepub fn nodes_mut(
&mut self
) -> impl Iterator<Item = &mut Node<Function, TypeKey>>
pub fn nodes_mut( &mut self ) -> impl Iterator<Item = &mut Node<Function, TypeKey>>
A mutable iterator over all nodes.
sourcepub fn with_nodes(
self,
nodes: impl IntoIterator<Item = Node<Function, TypeKey>>
) -> Self
pub fn with_nodes( self, nodes: impl IntoIterator<Item = Node<Function, TypeKey>> ) -> Self
Add multiple nodes to this graph.
sourcepub fn get_node(
&self,
name: impl AsRef<str>
) -> Option<&Node<Function, TypeKey>>
pub fn get_node( &self, name: impl AsRef<str> ) -> Option<&Node<Function, TypeKey>>
Return a reference to the node with the given name, if possible.
sourcepub fn get_node_mut(
&mut self,
name: impl AsRef<str>
) -> Option<&mut Node<Function, TypeKey>>
pub fn get_node_mut( &mut self, name: impl AsRef<str> ) -> Option<&mut Node<Function, TypeKey>>
Return a mutable reference to the node with the given name, if possible.
sourcepub fn remove_node(
&mut self,
name: impl AsRef<str>
) -> Option<Node<Function, TypeKey>>
pub fn remove_node( &mut self, name: impl AsRef<str> ) -> Option<Node<Function, TypeKey>>
Remove a node from the graph by name.
This leaves the graph in an unscheduled state.
sourcepub fn with_function<Input, Output>(
self,
name: impl Into<String>,
f: impl IsGraphNode<Input, Output>
) -> Self
pub fn with_function<Input, Output>( self, name: impl Into<String>, f: impl IsGraphNode<Input, Output> ) -> Self
Add a named function to the graph.
sourcepub fn add_function<Input, Output>(
&mut self,
name: impl Into<String>,
f: impl IsGraphNode<Input, Output>
)
pub fn add_function<Input, Output>( &mut self, name: impl Into<String>, f: impl IsGraphNode<Input, Output> )
Add a named function to the graph.
sourcepub fn contains_node(&self, name: impl AsRef<str>) -> bool
pub fn contains_node(&self, name: impl AsRef<str>) -> bool
Return whether the graph contains a node/function with the given name.
sourcepub fn contains_resource<T: Any + Send + Sync>(&self) -> bool
pub fn contains_resource<T: Any + Send + Sync>(&self) -> bool
Return whether the graph contains a resource with the parameterized type.
sourcepub fn with_resource<T: Any + Send + Sync>(self, t: T) -> Self
pub fn with_resource<T: Any + Send + Sync>(self, t: T) -> Self
Explicitly insert a resource (an edge) into the graph.
This will overwrite an existing resource of the same type in the graph.
sourcepub fn add_resource<T: Any + Send + Sync>(&mut self, t: T)
pub fn add_resource<T: Any + Send + Sync>(&mut self, t: T)
Explicitly insert a resource (an edge) into the graph.
This will overwrite an existing resource of the same type in the graph.
sourcepub fn add_barrier(&mut self)
pub fn add_barrier(&mut self)
Add a barrier to the graph.
All nodes added after the barrier will run after nodes added before the barrier.
sourcepub fn with_barrier(self) -> Self
pub fn with_barrier(self) -> Self
Add a barrier to the graph.
All nodes added after the barrier will run after nodes added before the barrier.
sourcepub fn get_barrier(&self) -> usize
pub fn get_barrier(&self) -> usize
Return the current barrier.
This will be the barrier for any added nodes.
sourcepub fn add_local<Input, Output>(&mut self, name: impl Into<String>)
pub fn add_local<Input, Output>(&mut self, name: impl Into<String>)
Add a locally run function to the graph by adding its name, input and output params.
There may be only one locally run function.
If a graph contains a local function the graph MUST be run with
Graph::run_with_local.
pub fn with_local<Input, Output>(self, name: impl Into<String>) -> Self
sourcepub fn run(&mut self) -> Result<(), GraphError>
pub fn run(&mut self) -> Result<(), GraphError>
Run the graph.
sourcepub fn run_with_local<Input, Output, E>(
&mut self,
f: impl FnOnce(Input) -> Result<Output, E>
) -> Result<(), GraphError>
pub fn run_with_local<Input, Output, E>( &mut self, f: impl FnOnce(Input) -> Result<Output, E> ) -> Result<(), GraphError>
Run the graph with the given local function.
sourcepub fn remove_resource<T: Any + Send + Sync>(
&mut self
) -> Result<Option<T>, GraphError>
pub fn remove_resource<T: Any + Send + Sync>( &mut self ) -> Result<Option<T>, GraphError>
Remove a resource from the graph.
sourcepub fn get_resource<T: Any + Send + Sync>(
&self
) -> Result<Option<&T>, GraphError>
pub fn get_resource<T: Any + Send + Sync>( &self ) -> Result<Option<&T>, GraphError>
Get a reference to a resource in the graph.
sourcepub fn get_resource_mut<T: Any + Send + Sync>(
&mut self
) -> Result<Option<&mut T>, GraphError>
pub fn get_resource_mut<T: Any + Send + Sync>( &mut self ) -> Result<Option<&mut T>, GraphError>
Get a mutable reference to a resource in the graph.
sourcepub fn visit<T: Edges, S>(
&mut self,
f: impl FnOnce(T) -> S
) -> Result<S, GraphError>
pub fn visit<T: Edges, S>( &mut self, f: impl FnOnce(T) -> S ) -> Result<S, GraphError>
Fetch graph edges and visit them with a closure.
This is like running a one-off graph node, but S does not get packed
into the graph as a result resource, instead it is given back to the
callsite.
Note
By design, visiting the graph with a type that uses Move in one of its
fields will result in the wrapped type of that field being moved
out of the graph. The resource will no longer be available
within the graph.
use moongraph::*;
use snafu::prelude::*;
#[derive(Debug, Snafu)]
enum TestError {}
#[derive(Edges)]
struct Input {
num_usize: View<usize>,
num_f32: ViewMut<f32>,
num_f64: Move<f64>,
}
// pack the graph with resources
let mut graph = Graph::default()
.with_resource(0usize)
.with_resource(0.0f32)
.with_resource(0.0f64);
// visit the graph, reading, modifying and _moving_!
let num_usize = graph.visit(|mut input: Input| {
*input.num_f32 = 666.0;
*input.num_f64 += 10.0;
*input.num_usize
}).unwrap();
// observe we read usize
assert_eq!(0, num_usize);
assert_eq!(0, *graph.get_resource::<usize>().unwrap().unwrap());
// observe we modified f32
assert_eq!(666.0, *graph.get_resource::<f32>().unwrap().unwrap());
// observe we moved f64 out of the graph and it is no longer present
assert!(!graph.contains_resource::<f64>());sourcepub fn into_parts(self) -> (Execution, TypeMap)
pub fn into_parts(self) -> (Execution, TypeMap)
Split the graph into an execution (schedule of functions/nodes) and resources.
sourcepub fn save_graph_dot(&self, path: &str)
pub fn save_graph_dot(&self, path: &str)
Save the graph to the filesystem as a dot file to be visualized with graphiz (or similar).
sourcepub fn _add_node_constraint(
constraint: &str,
i: &mut Node<Function, TypeKey>,
j: Option<String>
)
pub fn _add_node_constraint( constraint: &str, i: &mut Node<Function, TypeKey>, j: Option<String> )
Internal function used in the graph! macro.