Graph

Struct 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 _resources_mut(&mut self) -> &mut TypeMap

Source

pub fn node<Input, Output, F>(f: F) -> Node<Function, TypeKey>
where F: IsGraphNode<Input, Output>,

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 Graph

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 Graph

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 with_subgraph(self, rhs: Graph) -> Graph

Proxy for Graph::add_subgraph with self chaining.

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>>, ) -> Graph

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

Add a node to the graph.

Source

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

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>(&self) -> bool
where T: Any + Send + Sync,

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

Source

pub fn with_resource<T>(self, t: T) -> Graph
where T: Any + Send + Sync,

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>(&mut self, t: T)
where T: Any + Send + Sync,

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

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>) -> Graph
where Input: Edges + Any + Send + Sync, Output: NodeResults + Any + Send + Sync,

Source

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

Reschedule the graph only if there are unscheduled nodes.

Returns an error if a schedule cannot be built.

Source

pub fn batches(&mut self) -> Batches<'_>

Return an iterator over prepared schedule-batches.

The graph should be scheduled ahead of calling this function.

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>(&mut self) -> Result<Option<T>, GraphError>
where T: Any + Send + Sync,

Remove a resource from the graph.

Returns an error if the requested resource is loaned, and cannot be removed.

Source

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

Get a reference to a resource in the graph.

If the resource does not exist Ok(None) will be returned.

Source

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

Get a mutable reference to a resource in the graph.

If the resource does not exist Ok(None) will be returned.

Source

pub fn visit<T, S>(&mut self, f: impl FnOnce(T) -> S) -> Result<S, GraphError>
where T: Edges,

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 _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>

Source

pub fn node_len(&self) -> usize

Source

pub fn take_next_batch_of_nodes( &mut self, ) -> Option<Vec<Node<Function, TypeKey>>>

Pop off the next batch of nodes from the schedule.

The graph must be scheduled first.

Trait Implementations§

Source§

impl Default for Graph

Source§

fn default() -> Graph

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Graph

§

impl !RefUnwindSafe for Graph

§

impl !Send for Graph

§

impl !Sync for Graph

§

impl Unpin for Graph

§

impl !UnwindSafe for Graph

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

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

§

type Error = Infallible

The type returned in the event of a conversion error.
§

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

Performs the conversion.
§

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

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

Performs the conversion.
Source§

impl<T> SatisfyTraits<dyn None> for T