Struct moongraph::Graph

source ยท
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

source

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.

source

pub fn local<Input, Output>() -> Node<Function, TypeKey>
where Input: Edges + Any + Send + Sync, Output: NodeResults + Any + Send + Sync,

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.

source

pub 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.

Merge two graphs, preferring the right in cases of key collisions.

The values of rhs will override those of lhs.

source

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()
);
source

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()
);
source

pub fn reschedule(&mut self) -> Result<(), GraphError>

Reschedule all functions.

If the functions were already scheduled this will unscheduled them first.

source

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.

source

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.

source

pub fn nodes(&self) -> impl Iterator<Item = &Node<Function, TypeKey>>

An iterator over all nodes.

source

pub fn nodes_mut( &mut self ) -> impl Iterator<Item = &mut Node<Function, TypeKey>>

A mutable iterator over all nodes.

source

pub fn with_nodes( self, nodes: impl IntoIterator<Item = Node<Function, TypeKey>> ) -> Self

Add multiple nodes to this graph.

source

pub fn add_node(&mut self, node: Node<Function, TypeKey>)

Add a node to the graph.

source

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.

source

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.

source

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.

source

pub fn with_node(self, node: Node<Function, TypeKey>) -> Self

Add a node to the graph.

source

pub fn with_function<Input, Output>( self, name: impl Into<String>, f: impl IsGraphNode<Input, Output> ) -> Self

Add a named function to the graph.

source

pub fn add_function<Input, Output>( &mut self, name: impl Into<String>, f: impl IsGraphNode<Input, Output> )

Add a named function to the graph.

source

pub fn contains_node(&self, name: impl AsRef<str>) -> bool

Return whether the graph contains a node/function with the given name.

source

pub fn contains_resource<T: Any + Send + Sync>(&self) -> bool

Return whether the graph contains a resource with the parameterized type.

source

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.

source

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.

source

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.

source

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.

source

pub fn get_barrier(&self) -> usize

Return the current barrier.

This will be the barrier for any added nodes.

source

pub fn add_local<Input, Output>(&mut self, name: impl Into<String>)
where Input: Edges + Any + Send + Sync, Output: NodeResults + Any + Send + Sync,

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.

source

pub fn with_local<Input, Output>(self, name: impl Into<String>) -> Self
where Input: Edges + Any + Send + Sync, Output: NodeResults + Any + Send + Sync,

source

pub fn run(&mut self) -> Result<(), GraphError>

Run the graph.

source

pub fn run_with_local<Input, Output, E>( &mut self, f: impl FnOnce(Input) -> Result<Output, E> ) -> Result<(), GraphError>
where Input: Edges + Any + Send + Sync, Output: NodeResults + Any + Send + Sync, E: ToString,

Run the graph with the given local function.

source

pub fn remove_resource<T: Any + Send + Sync>( &mut self ) -> Result<Option<T>, GraphError>

Remove a resource from the graph.

source

pub fn get_resource<T: Any + Send + Sync>( &self ) -> Result<Option<&T>, GraphError>

Get a reference to a resource in the graph.

source

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.

source

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>());
source

pub fn into_parts(self) -> (Execution, TypeMap)

Split the graph into an execution (schedule of functions/nodes) and resources.

source

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).

source

pub fn _add_node_constraint( constraint: &str, i: &mut Node<Function, TypeKey>, j: Option<String> )

Internal function used in the graph! macro.

source

pub fn _last_node(&self) -> Option<String>

Trait Implementationsยง

sourceยง

impl Default for Graph

sourceยง

fn default() -> Graph

Returns the โ€œdefault valueโ€ for a type. Read more

Auto Trait Implementationsยง

Blanket Implementationsยง

sourceยง

impl<T> Any for T
where T: 'static + ?Sized,

sourceยง

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
sourceยง

impl<T> Borrow<T> for T
where T: ?Sized,

sourceยง

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
sourceยง

impl<T> BorrowMut<T> for T
where T: ?Sized,

sourceยง

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
sourceยง

impl<T> From<T> for T

sourceยง

fn from(t: T) -> T

Returns the argument unchanged.

sourceยง

impl<T, U> Into<U> for T
where U: From<T>,

sourceยง

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

ยง

impl<T> Pointable for T

ยง

const ALIGN: usize = _

The alignment of pointer.
ยง

type Init = T

The type for initializers.
ยง

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
ยง

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
ยง

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
ยง

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
sourceยง

impl<T, U> TryFrom<U> for T
where U: Into<T>,

ยง

type Error = Infallible

The type returned in the event of a conversion error.
sourceยง

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
sourceยง

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

ยง

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
sourceยง

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.