1use crate::{error::Error, Node};
2
3use std::collections::{HashMap, HashSet};
4use std::fmt;
5use std::hash::Hash;
6use std::sync::{Arc, RwLock};
7
8pub type InnerDependencyMap<I> = HashMap<I, HashSet<I>>;
9pub type DependencyMap<I> = Arc<RwLock<InnerDependencyMap<I>>>;
10
11pub struct DepGraph<I>
13where
14 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
15{
16 pub ready_nodes: Vec<I>,
17 pub deps: DependencyMap<I>,
18 pub rdeps: DependencyMap<I>,
19}
20
21impl<I> DepGraph<I>
22where
23 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
24{
25 pub fn new(nodes: &[Node<I>]) -> Self {
27 let (deps, rdeps, ready_nodes) = DepGraph::parse_nodes(nodes);
28
29 DepGraph {
30 ready_nodes,
31 deps,
32 rdeps,
33 }
34 }
35
36 fn parse_nodes(nodes: &[Node<I>]) -> (DependencyMap<I>, DependencyMap<I>, Vec<I>) {
37 let mut deps = InnerDependencyMap::<I>::default();
38 let mut rdeps = InnerDependencyMap::<I>::default();
39 let mut ready_nodes = Vec::<I>::default();
40
41 for node in nodes {
42 deps.insert(node.id().clone(), node.deps().clone());
43
44 if node.deps().is_empty() {
45 ready_nodes.push(node.id().clone());
46 }
47
48 for node_dep in node.deps() {
49 if !rdeps.contains_key(node_dep) {
50 let mut dep_rdeps = HashSet::new();
51 dep_rdeps.insert(node.id().clone());
52 rdeps.insert(node_dep.clone(), dep_rdeps.clone());
53 } else {
54 let dep_rdeps = rdeps.get_mut(node_dep).unwrap();
55 dep_rdeps.insert(node.id().clone());
56 }
57 }
58 }
59
60 (
61 Arc::new(RwLock::new(deps)),
62 Arc::new(RwLock::new(rdeps)),
63 ready_nodes,
64 )
65 }
66}
67
68impl<I> IntoIterator for DepGraph<I>
69where
70 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
71{
72 type Item = I;
73 type IntoIter = DepGraphIter<I>;
74
75 fn into_iter(self) -> Self::IntoIter {
76 DepGraphIter::<I>::new(self.ready_nodes.clone(), self.deps.clone(), self.rdeps)
77 }
78}
79
80#[derive(Clone)]
81pub struct DepGraphIter<I>
82where
83 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
84{
85 ready_nodes: Vec<I>,
86 deps: DependencyMap<I>,
87 rdeps: DependencyMap<I>,
88}
89
90impl<I> DepGraphIter<I>
91where
92 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
93{
94 pub fn new(ready_nodes: Vec<I>, deps: DependencyMap<I>, rdeps: DependencyMap<I>) -> Self {
95 Self {
96 ready_nodes,
97 deps,
98 rdeps,
99 }
100 }
101}
102
103impl<I> Iterator for DepGraphIter<I>
104where
105 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
106{
107 type Item = I;
108
109 fn next(&mut self) -> Option<Self::Item> {
110 if let Some(id) = self.ready_nodes.pop() {
111 let next_nodes = remove_node_id::<I>(id.clone(), &self.deps, &self.rdeps).unwrap();
113
114 self.ready_nodes.extend_from_slice(&next_nodes);
116
117 Some(id)
119 } else {
120 None
122 }
123 }
124}
125
126pub fn remove_node_id<I>(
129 id: I,
130 deps: &DependencyMap<I>,
131 rdeps: &DependencyMap<I>,
132) -> Result<Vec<I>, Error>
133where
134 I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync + 'static,
135{
136 let rdep_ids = {
137 match rdeps.read().unwrap().get(&id) {
138 Some(node) => node.clone(),
139 None => Default::default(),
142 }
143 };
144
145 let mut deps = deps.write().unwrap();
146 let next_nodes = rdep_ids
147 .iter()
148 .filter_map(|rdep_id| {
149 let rdep = match deps.get_mut(&rdep_id) {
150 Some(rdep) => rdep,
151 None => return None,
152 };
153
154 rdep.remove(&id);
155
156 if rdep.is_empty() {
157 Some(rdep_id.clone())
158 } else {
159 None
160 }
161 })
162 .collect();
163
164 deps.remove(&id);
166
167 Ok(next_nodes)
168}