wasmtime_environ/graphs/
entity_graph.rs1use super::*;
2use crate::{EntityRef, SecondaryMap, prelude::*};
3use core::{
4 fmt::{self, Debug},
5 iter,
6 ops::Range,
7};
8
9pub struct EntityGraph<Node>
11where
12 Node: EntityRef,
13{
14 edges: SecondaryMap<Node, Range<u32>>,
17
18 edge_elems: Vec<Node>,
20}
21
22impl<Node> Debug for EntityGraph<Node>
23where
24 Node: EntityRef + Debug,
25{
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 struct Edges<'a, Node: EntityRef + Debug>(&'a EntityGraph<Node>);
28
29 impl<'a, Node: EntityRef + Debug> Debug for Edges<'a, Node> {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.debug_map()
32 .entries(
33 self.0
34 .nodes()
35 .map(|n| (n, self.0.successors(n).collect::<Box<[_]>>())),
36 )
37 .finish()
38 }
39 }
40
41 f.debug_struct("Graph")
42 .field("edges", &Edges(self))
43 .finish()
44 }
45}
46
47impl<Node> EntityGraph<Node>
48where
49 Node: EntityRef + Debug,
50{
51 pub fn new<E>(
53 nodes: impl IntoIterator<Item = Node>,
54 mut successors: impl FnMut(Node, &mut Vec<Node>) -> Result<(), E>,
55 ) -> Result<Self, E> {
56 let nodes = nodes.into_iter();
57
58 let (min, max) = nodes.size_hint();
59 let capacity = max.unwrap_or_else(|| 2 * min);
60
61 let mut edges = SecondaryMap::with_capacity(capacity);
62 let mut edge_elems = vec![];
63
64 let mut succs = vec![];
65 for v in nodes {
66 debug_assert!(succs.is_empty());
67 successors(v, &mut succs)?;
68
69 debug_assert_eq!(edges[v], Range::default());
70 edges[v] = extend_with_range(&mut edge_elems, succs.drain(..));
71 }
72
73 Ok(EntityGraph { edges, edge_elems })
74 }
75}
76
77impl<Node> Graph<Node> for EntityGraph<Node>
78where
79 Node: EntityRef,
80{
81 type NodesIter<'a>
82 = cranelift_entity::Keys<Node>
83 where
84 Self: 'a;
85
86 #[inline]
87 fn nodes(&self) -> Self::NodesIter<'_> {
88 self.edges.keys()
89 }
90
91 type SuccessorsIter<'a>
92 = iter::Copied<core::slice::Iter<'a, Node>>
93 where
94 Self: 'a;
95
96 fn successors(&self, node: Node) -> Self::SuccessorsIter<'_> {
97 let Range { start, end } = self.edges[node].clone();
98 let start = usize::try_from(start).unwrap();
99 let end = usize::try_from(end).unwrap();
100 self.edge_elems[start..end].iter().copied()
101 }
102}