pub struct GraphSolver<'a, 'b> { /* private fields */ }
Expand description
The graph solver is a transient object which can execute the tasks described in a graph. It is designed to be generated and dropped on every execution.
Implementations§
Source§impl<'a, 'b> GraphSolver<'a, 'b>
impl<'a, 'b> GraphSolver<'a, 'b>
Sourcepub fn new(
graph: &'a Graph,
last_cache: &'b mut ValuesCache,
) -> GraphSolver<'a, 'b>
pub fn new( graph: &'a Graph, last_cache: &'b mut ValuesCache, ) -> GraphSolver<'a, 'b>
creates a solver for graph ‘graph’, using cache from a previous solve. the cache may be empty.
Examples found in repository?
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
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}
pub fn get_binding(&self, name: &str) -> Result<&String, SolverError>
Sourcepub fn execute(&mut self, name: &str) -> Result<SolverStatus, SolverError>
pub fn execute(&mut self, name: &str) -> Result<SolverStatus, SolverError>
Executes a task by name, all tasks needed to provide Assets are transitively executed
Examples found in repository?
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
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}
pub fn execute_terminals(&mut self) -> Result<SolverStatus, SolverError>
Sourcepub fn input_is_new<T>(&self, new_value: &T, name: &String) -> boolwhere
T: Clone + Comparable + 'static,
pub fn input_is_new<T>(&self, new_value: &T, name: &String) -> boolwhere
T: Clone + Comparable + 'static,
Check if the input is still valid. This function is used to compute if the input of a task has changed over iterations. if all inputs are cached and equal to current values, and a cached output is available. The output will be considered valid and the computation skipped
Sourcepub fn input_is_new_str<T>(&self, new_value: &T, name: &str) -> boolwhere
T: Clone + Comparable + 'static,
pub fn input_is_new_str<T>(&self, new_value: &T, name: &str) -> boolwhere
T: Clone + Comparable + 'static,
Check if the input is still valid. This function is used to compute if the input of a task has changed over iterations. if all inputs are cached and equal to current values, and a cached output is available. The output will be considered valid and the computation skipped
Sourcepub fn use_old_ouput<T: AsRef<str>>(&mut self, ouputs: &[T]) -> bool
pub fn use_old_ouput<T: AsRef<str>>(&mut self, ouputs: &[T]) -> bool
function to decide whenever the set of values is still valid or the producing node of any of the values needs to be executed
Sourcepub fn get_values(&self) -> &ValuesCache
pub fn get_values(&self) -> &ValuesCache
Examples found in repository?
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}