1use std::collections::{HashMap, HashSet};
6use std::fmt::Debug;
7use std::hash::Hash;
8use std::mem;
9
10pub struct DependencyGraph<K: Eq + Hash, V> {
11 nodes: Vec<Node<K, V>>,
13
14 indices: HashMap<K, usize>,
16
17 children: HashMap<usize, HashSet<usize>>,
19
20 parents: HashMap<usize, HashSet<usize>>,
22}
23
24enum Node<K, V> {
25 Root,
27
28 Data(K, V),
30
31 Zombie,
34}
35
36#[derive(Debug, Clone, PartialEq)]
37pub enum DependencyError<K: Clone + Debug + PartialEq> {
38 MissingDependency(K),
39 CircularDependency,
40}
41
42impl<K: Eq + Hash + Clone + Debug, V> DependencyGraph<K, V> {
43 const ROOT_INDEX: usize = 0;
44
45 pub fn new() -> DependencyGraph<K, V> {
47 Self {
48 nodes: vec![Node::Root],
49 indices: HashMap::new(),
50 children: HashMap::new(),
51 parents: HashMap::new(),
52 }
53 }
54
55 pub fn insert_node(&mut self, key: K, data: V) {
59 let index = self.nodes.len();
60 self.nodes.push(Node::Data(key.clone(), data));
61 if let Some(previous) = self.indices.insert(key, index) {
62 self.nodes[previous] = Node::Zombie;
63 }
64 }
65
66 pub fn insert_edge_from_root(&mut self, to: &K) -> Result<(), DependencyError<K>> {
70 let to_index = self.get_index(to)?;
71 self.children.entry(Self::ROOT_INDEX).or_insert(HashSet::new()).insert(to_index);
72 self.parents.entry(to_index).or_insert(HashSet::new()).insert(Self::ROOT_INDEX);
73 Ok(())
74 }
75
76 pub fn insert_edge(&mut self, from: &K, to: &K) -> Result<(), DependencyError<K>> {
81 let from_index = self.get_index(from)?;
82 let to_index = self.get_index(to)?;
83 self.children.entry(from_index).or_insert(HashSet::new()).insert(to_index);
84 self.parents.entry(to_index).or_insert(HashSet::new()).insert(from_index);
85 Ok(())
86 }
87
88 pub fn resolve(mut self) -> Result<Vec<V>, DependencyError<K>> {
95 self.prune_orphans()?;
99
100 let mut result = vec![];
101 let mut next_indices = vec![Self::ROOT_INDEX];
102 while let Some(index) = next_indices.pop() {
103 if let Some(data) = self.remove(index) {
104 result.push(data);
105 }
106
107 for child_index in self.children.entry(index).or_default().clone() {
108 self.remove_edge(index, child_index)?;
109 if self.is_orphaned(&self.nodes[child_index]) {
110 next_indices.push(child_index);
111 }
112 }
113 }
114 if self.is_empty() {
115 Ok(result)
116 } else {
117 Err(DependencyError::CircularDependency)
118 }
119 }
120}
121
122impl<K: Eq + Hash + Clone + Debug, V> DependencyGraph<K, V> {
123 fn get_index(&self, key: &K) -> Result<usize, DependencyError<K>> {
124 let index = self.indices.get(key).ok_or(DependencyError::MissingDependency(key.clone()))?;
125 Ok(*index)
126 }
127
128 fn remove_edge(
129 &mut self,
130 from_index: usize,
131 to_index: usize,
132 ) -> Result<(), DependencyError<K>> {
133 let to_parents =
134 self.parents.get_mut(&to_index).expect("remove_edge called with invalid to_index");
135 to_parents.remove(&from_index);
136 let from_children =
137 self.children.get_mut(&from_index).expect("remove_edge called with invalid from_index");
138 from_children.remove(&to_index);
139 Ok(())
140 }
141
142 fn is_orphaned(&self, node: &Node<K, V>) -> bool {
143 match node {
144 Node::Data(key, _) => {
145 let index = self.indices.get(key).expect("Key exists in node but not in graph");
146 self.parents.get(index).map(|vs| vs.is_empty()).unwrap_or(true)
147 }
148 Node::Root => false,
149 Node::Zombie => false,
150 }
151 }
152
153 fn remove(&mut self, index: usize) -> Option<V> {
154 match mem::replace(&mut self.nodes[index], Node::Zombie) {
156 Node::Data(_, data) => Some(data),
157 _ => None,
158 }
159 }
160
161 fn prune_orphans(&mut self) -> Result<(), DependencyError<K>> {
164 while let Some((index, _)) =
165 self.nodes.iter().enumerate().find(|(_, node)| self.is_orphaned(node))
166 {
167 self.remove(index);
168
169 let child_indices = self.children.entry(index).or_default().clone();
171 for child_index in child_indices {
172 self.remove_edge(index, child_index)?;
173 }
174 }
175
176 Ok(())
177 }
178
179 fn is_empty(&self) -> bool {
180 self.children.values().all(|xs| xs.is_empty())
181 && self.parents.values().all(|xs| xs.is_empty())
182 }
183}
184
185#[cfg(test)]
186mod test {
187 use super::*;
188
189 #[test]
190 fn simple() {
191 let mut graph = DependencyGraph::new();
192
193 graph.insert_node(1, "one");
194 graph.insert_node(2, "two");
195 graph.insert_node(3, "three");
196
197 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
198 assert_eq!(graph.insert_edge(&1, &2), Ok(()));
199 assert_eq!(graph.insert_edge(&2, &3), Ok(()));
200
201 assert_eq!(graph.resolve(), Ok(vec!["one", "two", "three",]));
202 }
203
204 #[test]
205 fn empty() {
206 let graph: DependencyGraph<usize, usize> = DependencyGraph::new();
207 assert!(graph.resolve().unwrap().is_empty());
208 }
209
210 #[test]
211 fn insert_replaces() {
212 let mut graph = DependencyGraph::new();
213
214 graph.insert_node(1, "one");
215 graph.insert_node(1, "two");
216
217 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
218
219 assert_eq!(graph.resolve(), Ok(vec!["two"]));
220 }
221
222 #[test]
223 fn branching_edges_from_root() {
224 let mut graph = DependencyGraph::new();
225
226 graph.insert_node(1, "one");
227 graph.insert_node(2, "two");
228 graph.insert_node(3, "three");
229 graph.insert_node(4, "four");
230
231 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
232 assert_eq!(graph.insert_edge_from_root(&2), Ok(()));
233
234 assert_eq!(graph.insert_edge(&1, &3), Ok(()));
235 assert_eq!(graph.insert_edge(&2, &4), Ok(()));
236
237 let result = graph.resolve().unwrap();
238 assert!(result.contains(&"one"));
239 assert!(result.contains(&"two"));
240 assert!(result.contains(&"three"));
241 assert!(result.contains(&"four"));
242 assert!(
243 result.iter().position(|&x| x == "one") < result.iter().position(|&x| x == "three")
244 );
245 assert!(result.iter().position(|&x| x == "two") < result.iter().position(|&x| x == "four"));
246 }
247
248 #[test]
249 fn branching_edges() {
250 let mut graph = DependencyGraph::new();
251
252 graph.insert_node(1, "one");
253 graph.insert_node(2, "two");
254 graph.insert_node(3, "three");
255 graph.insert_node(4, "four");
256 graph.insert_node(5, "five");
257
258 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
259
260 assert_eq!(graph.insert_edge(&1, &2), Ok(()));
261 assert_eq!(graph.insert_edge(&2, &3), Ok(()));
262
263 assert_eq!(graph.insert_edge(&1, &4), Ok(()));
264 assert_eq!(graph.insert_edge(&4, &5), Ok(()));
265
266 let result = graph.resolve().unwrap();
267 assert!(result.contains(&"one"));
268 assert!(result.contains(&"two"));
269 assert!(result.contains(&"three"));
270 assert!(result.contains(&"four"));
271 assert!(result.contains(&"five"));
272 assert_eq!(result[0], "one");
273 assert!(
274 result.iter().position(|&x| x == "two") < result.iter().position(|&x| x == "three")
275 );
276 assert!(
277 result.iter().position(|&x| x == "four") < result.iter().position(|&x| x == "five")
278 );
279 }
280
281 #[test]
282 fn multiple_incoming_edges() {
283 let mut graph = DependencyGraph::new();
284
285 graph.insert_node(1, "one");
286 graph.insert_node(2, "two");
287 graph.insert_node(3, "three");
288
289 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
290
291 assert_eq!(graph.insert_edge(&1, &2), Ok(()));
292 assert_eq!(graph.insert_edge(&1, &3), Ok(()));
293 assert_eq!(graph.insert_edge(&2, &3), Ok(()));
294
295 assert_eq!(graph.resolve(), Ok(vec!["one", "two", "three",]));
296 }
297
298 #[test]
299 fn prunes_disconnected_graph() {
300 let mut graph = DependencyGraph::new();
301
302 graph.insert_node(1, "one");
303 graph.insert_node(2, "two");
304 graph.insert_node(3, "three");
305
306 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
307
308 assert_eq!(graph.insert_edge(&2, &3), Ok(()));
309
310 assert_eq!(graph.resolve(), Ok(vec!["one"]));
311 }
312
313 #[test]
314 fn circular_dependency() {
315 let mut graph = DependencyGraph::new();
316
317 graph.insert_node(1, "one");
318 graph.insert_node(2, "two");
319 graph.insert_node(3, "three");
320
321 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
322
323 assert_eq!(graph.insert_edge(&1, &2), Ok(()));
324 assert_eq!(graph.insert_edge(&2, &3), Ok(()));
325 assert_eq!(graph.insert_edge(&3, &1), Ok(()));
326
327 assert_eq!(graph.resolve(), Err(DependencyError::CircularDependency));
328 }
329
330 #[test]
331 fn missing_root_dependency() {
332 let mut graph: DependencyGraph<usize, usize> = DependencyGraph::new();
333
334 assert_eq!(graph.insert_edge_from_root(&1), Err(DependencyError::MissingDependency(1)));
335 }
336
337 #[test]
338 fn missing_dependency() {
339 let mut graph = DependencyGraph::new();
340
341 graph.insert_node(1, "one");
342
343 assert_eq!(graph.insert_edge_from_root(&1), Ok(()));
344
345 assert_eq!(graph.insert_edge(&1, &2), Err(DependencyError::MissingDependency(2)));
346 assert_eq!(graph.insert_edge(&2, &1), Err(DependencyError::MissingDependency(2)));
347 }
348}