1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
use crate::analysis::graph_based_analysis::{get_ast_id, DependencyGraph, NIx, StreamNode}; use crate::parse::NodeId; use petgraph::visit::IntoNodeIdentifiers; use petgraph::Direction; use std::collections::{HashMap, HashSet}; pub(crate) type RequiredInputs = HashMap<NodeId, Vec<NodeId>>; pub(crate) fn determine_required_inputs(dependency_graph: &DependencyGraph) -> RequiredInputs { let mut input_dependencies: RequiredInputs = HashMap::new(); for node in dependency_graph.node_identifiers() { let node_info = dependency_graph.node_weight(node).expect("we iterate over the NIx"); input_dependencies.insert(get_ast_id(node_info), Vec::new()); } for node in dependency_graph.node_identifiers() { let node_info = dependency_graph.node_weight(node).expect("we iterate over the NIx"); let mut visited: HashSet<NIx> = HashSet::new(); let mut stack: Vec<NIx> = Vec::new(); if let StreamNode::ClassicInput(node_id) = node_info { visited.clear(); stack.push(node); visited.insert(node); input_dependencies.get_mut(node_id).unwrap().push(*node_id); bfs_color_reachable(&mut visited, &mut stack, *node_id, &mut input_dependencies, dependency_graph); } } input_dependencies } fn bfs_color_reachable( visited: &mut HashSet<NIx>, stack: &mut Vec<NIx>, node_id: NodeId, input_dependencies: &mut RequiredInputs, dependency_graph: &DependencyGraph, ) { while !stack.is_empty() { let top = stack.pop().expect("We checked for empty stack"); for dependent_stream in dependency_graph.neighbors_directed(top, Direction::Incoming) { if visited.insert(dependent_stream) { let id = get_ast_id(dependency_graph.node_weight(dependent_stream).expect("We just got this NIx")); input_dependencies.get_mut(&id).unwrap().push(node_id); stack.push(dependent_stream) } } } }