Struct Graph

Source
pub struct Graph { /* private fields */ }
Expand description

The graph class itself. It holds the static information about the tasks (Nodes) and how they depend on each other by waiting on resources (Assets)

Implementations§

Source§

impl Graph

Source

pub fn new() -> Graph

Examples found in repository?
examples/seq10k.rs (line 7)
6fn main() {
7    let mut g = Graph::new();
8
9    let max = 10000;
10
11    // generate 10000 nodes
12    for i in 1..max {
13        let name: String = format!("task{}", i);
14        g.add_node(create_node!(name: name, ( input : u32) -> (output : u32)
15                                 { 
16                                     output = input +1 ;
17                                 }))
18            .unwrap();
19    }
20
21
22    // add sequential linking
23    for i in 1..max - 1 {
24        let src = format!("task{}::output", i);
25        let sink = format!("task{}::input", i + 1);
26        g.bind_asset(src.as_str(), sink.as_str())
27            .expect("binding must be doable");
28    }
29
30    g.define_freestanding_asset("start", 0u32).expect("could not create asset");
31        g.bind_asset("start", "task1::input")
32            .expect("could not bind first tast to start value");
33
34    let mut cache = ValuesCache::new();
35    let mut solver = GraphSolver::new(&g, &mut cache);
36
37    let last_task = format!("task{}", max-1);
38    solver.execute(last_task.as_str()).expect("this should run");
39}
More examples
Hide additional examples
examples/simple.rs (line 7)
6fn main() {
7    let mut g = Graph::new();
8
9    g.add_node(create_node!(
10                gen_one () -> (one: u32) {
11                    println!("              gen one");
12                    one = 1u32;
13                }
14            )).unwrap();
15
16    g.add_node(create_node!(
17                plus_one (one: u32) -> (plusone : u32) {
18                    println!("              plusone");
19                    plusone = one + 1u32;
20                }
21            )).unwrap();
22
23    g.add_node(create_node!(
24                the_one_task  (one: u32, plusone : u32) ->
25                              (last_value: f32) {
26                    println!("              the one task");
27                    last_value = (one + plusone) as f32;
28                }
29            )).unwrap();
30
31    g.add_node(create_node!(
32                list (list : Vec<u32>) -> () {
33                    println!("             list");
34                }
35            )).unwrap();
36
37    g.bind_asset("gen_one::one", "plus_one::one")
38        .expect("binding must be doable");
39    g.bind_asset("gen_one::one", "the_one_task::one")
40        .expect("binding must be doable");
41    g.bind_asset("plus_one::plusone", "the_one_task::plusone")
42        .expect("binding must be doable");
43
44    let mut cache = ValuesCache::new();
45
46    for _ in 0..10 {
47        {
48            let mut solver = GraphSolver::new(&g, &mut cache);
49            assert!(solver.execute("nop").is_err());
50
51            solver.execute("the_one_task").expect("could not execute");
52
53            println!("{:?}", solver.get_values());
54
55            assert!(
56                solver
57                    .get_value::<u32>("gen_one::one")
58                    .expect("never created?") == 1
59            );
60            assert!(
61                solver
62                    .get_value::<u32>("plus_one::plusone")
63                    .expect("never created?") == 2
64            );
65            assert!(
66                (solver
67                    .get_value::<f32>("the_one_task::last_value")
68                    .expect("not cached?") - 3.0)
69                    .abs() < 0.01
70            );
71        }
72
73        assert!(cache.get_value::<u32>("gen_one::one").expect("not cached?") == 1);
74        assert!(
75            cache
76                .get_value::<u32>("plus_one::plusone")
77                .expect("not cached?") == 2
78        );
79        assert!(
80            (cache
81                .get_value::<f32>("the_one_task::last_value")
82                .expect("not cached?") - 3.0)
83                .abs() < 0.01
84        );
85    }
86}
Source

pub fn add_node<F>(&mut self, node: Node<F>) -> Result<(), GraphError>
where F: Fn(&mut GraphSolver<'_, '_>) -> Result<SolverStatus, SolverError> + 'static,

Examples found in repository?
examples/seq10k.rs (lines 14-17)
6fn main() {
7    let mut g = Graph::new();
8
9    let max = 10000;
10
11    // generate 10000 nodes
12    for i in 1..max {
13        let name: String = format!("task{}", i);
14        g.add_node(create_node!(name: name, ( input : u32) -> (output : u32)
15                                 { 
16                                     output = input +1 ;
17                                 }))
18            .unwrap();
19    }
20
21
22    // add sequential linking
23    for i in 1..max - 1 {
24        let src = format!("task{}::output", i);
25        let sink = format!("task{}::input", i + 1);
26        g.bind_asset(src.as_str(), sink.as_str())
27            .expect("binding must be doable");
28    }
29
30    g.define_freestanding_asset("start", 0u32).expect("could not create asset");
31        g.bind_asset("start", "task1::input")
32            .expect("could not bind first tast to start value");
33
34    let mut cache = ValuesCache::new();
35    let mut solver = GraphSolver::new(&g, &mut cache);
36
37    let last_task = format!("task{}", max-1);
38    solver.execute(last_task.as_str()).expect("this should run");
39}
More examples
Hide additional examples
examples/simple.rs (lines 9-14)
6fn main() {
7    let mut g = Graph::new();
8
9    g.add_node(create_node!(
10                gen_one () -> (one: u32) {
11                    println!("              gen one");
12                    one = 1u32;
13                }
14            )).unwrap();
15
16    g.add_node(create_node!(
17                plus_one (one: u32) -> (plusone : u32) {
18                    println!("              plusone");
19                    plusone = one + 1u32;
20                }
21            )).unwrap();
22
23    g.add_node(create_node!(
24                the_one_task  (one: u32, plusone : u32) ->
25                              (last_value: f32) {
26                    println!("              the one task");
27                    last_value = (one + plusone) as f32;
28                }
29            )).unwrap();
30
31    g.add_node(create_node!(
32                list (list : Vec<u32>) -> () {
33                    println!("             list");
34                }
35            )).unwrap();
36
37    g.bind_asset("gen_one::one", "plus_one::one")
38        .expect("binding must be doable");
39    g.bind_asset("gen_one::one", "the_one_task::one")
40        .expect("binding must be doable");
41    g.bind_asset("plus_one::plusone", "the_one_task::plusone")
42        .expect("binding must be doable");
43
44    let mut cache = ValuesCache::new();
45
46    for _ in 0..10 {
47        {
48            let mut solver = GraphSolver::new(&g, &mut cache);
49            assert!(solver.execute("nop").is_err());
50
51            solver.execute("the_one_task").expect("could not execute");
52
53            println!("{:?}", solver.get_values());
54
55            assert!(
56                solver
57                    .get_value::<u32>("gen_one::one")
58                    .expect("never created?") == 1
59            );
60            assert!(
61                solver
62                    .get_value::<u32>("plus_one::plusone")
63                    .expect("never created?") == 2
64            );
65            assert!(
66                (solver
67                    .get_value::<f32>("the_one_task::last_value")
68                    .expect("not cached?") - 3.0)
69                    .abs() < 0.01
70            );
71        }
72
73        assert!(cache.get_value::<u32>("gen_one::one").expect("not cached?") == 1);
74        assert!(
75            cache
76                .get_value::<u32>("plus_one::plusone")
77                .expect("not cached?") == 2
78        );
79        assert!(
80            (cache
81                .get_value::<f32>("the_one_task::last_value")
82                .expect("not cached?") - 3.0)
83                .abs() < 0.01
84        );
85    }
86}
Source

pub fn get_node(&self, name: &str) -> Option<&dyn NodeRunner>

Source

pub fn get_terminals(&self) -> &[Rc<dyn NodeRunner>]

Source

pub fn get_binding(&self, name: &String) -> Option<&String>

Source

pub fn get_binding_str(&self, name: &str) -> Option<&String>

Source

pub fn define_freestanding_asset<T: 'static + Clone>( &mut self, name: &str, val: T, ) -> Result<(), GraphError>

declares and initializes a freestanding asset, this assets are defined as global inputs to the graph and can be used to feed initial values in the system

Examples found in repository?
examples/seq10k.rs (line 30)
6fn main() {
7    let mut g = Graph::new();
8
9    let max = 10000;
10
11    // generate 10000 nodes
12    for i in 1..max {
13        let name: String = format!("task{}", i);
14        g.add_node(create_node!(name: name, ( input : u32) -> (output : u32)
15                                 { 
16                                     output = input +1 ;
17                                 }))
18            .unwrap();
19    }
20
21
22    // add sequential linking
23    for i in 1..max - 1 {
24        let src = format!("task{}::output", i);
25        let sink = format!("task{}::input", i + 1);
26        g.bind_asset(src.as_str(), sink.as_str())
27            .expect("binding must be doable");
28    }
29
30    g.define_freestanding_asset("start", 0u32).expect("could not create asset");
31        g.bind_asset("start", "task1::input")
32            .expect("could not bind first tast to start value");
33
34    let mut cache = ValuesCache::new();
35    let mut solver = GraphSolver::new(&g, &mut cache);
36
37    let last_task = format!("task{}", max-1);
38    solver.execute(last_task.as_str()).expect("this should run");
39}
Source

pub fn bind_asset(&mut self, src: &str, sink: &str) -> Result<(), GraphError>

Binds two nodes. An asset satisfied by a task, will be the input for another task under a different asset name. One output asset can be used in one or more inputs. If the input is already bound, the link will be overwritten

Examples found in repository?
examples/seq10k.rs (line 26)
6fn main() {
7    let mut g = Graph::new();
8
9    let max = 10000;
10
11    // generate 10000 nodes
12    for i in 1..max {
13        let name: String = format!("task{}", i);
14        g.add_node(create_node!(name: name, ( input : u32) -> (output : u32)
15                                 { 
16                                     output = input +1 ;
17                                 }))
18            .unwrap();
19    }
20
21
22    // add sequential linking
23    for i in 1..max - 1 {
24        let src = format!("task{}::output", i);
25        let sink = format!("task{}::input", i + 1);
26        g.bind_asset(src.as_str(), sink.as_str())
27            .expect("binding must be doable");
28    }
29
30    g.define_freestanding_asset("start", 0u32).expect("could not create asset");
31        g.bind_asset("start", "task1::input")
32            .expect("could not bind first tast to start value");
33
34    let mut cache = ValuesCache::new();
35    let mut solver = GraphSolver::new(&g, &mut cache);
36
37    let last_task = format!("task{}", max-1);
38    solver.execute(last_task.as_str()).expect("this should run");
39}
More examples
Hide additional examples
examples/simple.rs (line 37)
6fn main() {
7    let mut g = Graph::new();
8
9    g.add_node(create_node!(
10                gen_one () -> (one: u32) {
11                    println!("              gen one");
12                    one = 1u32;
13                }
14            )).unwrap();
15
16    g.add_node(create_node!(
17                plus_one (one: u32) -> (plusone : u32) {
18                    println!("              plusone");
19                    plusone = one + 1u32;
20                }
21            )).unwrap();
22
23    g.add_node(create_node!(
24                the_one_task  (one: u32, plusone : u32) ->
25                              (last_value: f32) {
26                    println!("              the one task");
27                    last_value = (one + plusone) as f32;
28                }
29            )).unwrap();
30
31    g.add_node(create_node!(
32                list (list : Vec<u32>) -> () {
33                    println!("             list");
34                }
35            )).unwrap();
36
37    g.bind_asset("gen_one::one", "plus_one::one")
38        .expect("binding must be doable");
39    g.bind_asset("gen_one::one", "the_one_task::one")
40        .expect("binding must be doable");
41    g.bind_asset("plus_one::plusone", "the_one_task::plusone")
42        .expect("binding must be doable");
43
44    let mut cache = ValuesCache::new();
45
46    for _ in 0..10 {
47        {
48            let mut solver = GraphSolver::new(&g, &mut cache);
49            assert!(solver.execute("nop").is_err());
50
51            solver.execute("the_one_task").expect("could not execute");
52
53            println!("{:?}", solver.get_values());
54
55            assert!(
56                solver
57                    .get_value::<u32>("gen_one::one")
58                    .expect("never created?") == 1
59            );
60            assert!(
61                solver
62                    .get_value::<u32>("plus_one::plusone")
63                    .expect("never created?") == 2
64            );
65            assert!(
66                (solver
67                    .get_value::<f32>("the_one_task::last_value")
68                    .expect("not cached?") - 3.0)
69                    .abs() < 0.01
70            );
71        }
72
73        assert!(cache.get_value::<u32>("gen_one::one").expect("not cached?") == 1);
74        assert!(
75            cache
76                .get_value::<u32>("plus_one::plusone")
77                .expect("not cached?") == 2
78        );
79        assert!(
80            (cache
81                .get_value::<f32>("the_one_task::last_value")
82                .expect("not cached?") - 3.0)
83                .abs() < 0.01
84        );
85    }
86}
Source

pub fn what_provides(&self, name: &str) -> AssetProvider<'_>

For a given asset name, identifies which node generates the it

Source

pub fn get_unbound_assets(&self) -> Vec<&String>

reports a collection of input assets which are not currenty bound, this elements are disconnected and will have no value satisfied during execution.

Source

pub fn get_freestanding_assets(&self) -> &Vec<String>

Trait Implementations§

Source§

impl Default for Graph

Source§

fn default() -> Graph

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

impl<'a> GraphWalk<'a, &'a str, (&'a str, &'a str, &'a str, &'a str)> for Graph

Source§

fn nodes(&'a self) -> Nodes<'a, &'a str>

Returns all the nodes in this graph.
Source§

fn edges(&'a self) -> Edges<'a, (&'a str, &'a str, &'a str, &'a str)>

Returns all of the edges in this graph.
Source§

fn source(&self, e: &(&'a str, &'a str, &'a str, &'a str)) -> &'a str

The source node for edge.
Source§

fn target(&self, e: &(&'a str, &'a str, &'a str, &'a str)) -> &'a str

The target node for edge.
Source§

impl<'a> Labeller<'a, &'a str, (&'a str, &'a str, &'a str, &'a str)> for Graph

Source§

fn graph_id(&'a self) -> Id<'a>

Must return a DOT compatible identifier naming the graph.
Source§

fn node_id(&'a self, n: &&'_ str) -> Id<'a>

Maps n to a unique identifier with respect to self. The implementer is responsible for ensuring that the returned name is a valid DOT identifier.
Source§

fn edge_label<'b>( &'b self, edge: &(&'_ str, &'_ str, &'_ str, &'_ str), ) -> LabelText<'b>

Maps e to a label that will be used in the rendered output. The label need not be unique, and may be the empty string; the default is in fact the empty string.
Source§

fn node_shape(&'a self, _node: &N) -> Option<LabelText<'a>>

Maps n to one of the graphviz shape names. If None is returned, no shape attribute is specified.
Source§

fn node_label(&'a self, n: &N) -> LabelText<'a>

Maps n to a label that will be used in the rendered output. The label need not be unique, and may be the empty string; the default is just the output from node_id.
Source§

fn node_style(&'a self, _n: &N) -> Style

Maps n to a style that will be used in the rendered output.
Source§

fn node_color(&'a self, _node: &N) -> Option<LabelText<'a>>

Maps n to one of the graphviz color names. If None is returned, no color attribute is specified.
Source§

fn edge_end_arrow(&'a self, _e: &E) -> Arrow

Maps e to arrow style that will be used on the end of an edge. Defaults to default arrow style.
Source§

fn edge_start_arrow(&'a self, _e: &E) -> Arrow

Maps e to arrow style that will be used on the end of an edge. Defaults to default arrow style.
Source§

fn edge_style(&'a self, _e: &E) -> Style

Maps e to a style that will be used in the rendered output.
Source§

fn edge_color(&'a self, _e: &E) -> Option<LabelText<'a>>

Maps e to one of the graphviz color names. If None is returned, no color attribute is specified.
Source§

fn kind(&self) -> Kind

The kind of graph, defaults to Kind::Digraph.

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§

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.

Source§

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

Source§

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

Source§

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.