traitgraph/implementation/subgraphs/
bit_vector_subgraph.rs1use crate::implementation::subgraphs::filter_iterators::{
2 FilterEdgeIndexIterator, FilterNeighborIterator,
3};
4use crate::index::GraphIndex;
5use crate::interface::subgraph::{EmptyConstructibleSubgraph, MutableSubgraph, SubgraphBase};
6use crate::interface::{Edge, GraphBase, ImmutableGraphContainer, NavigableGraph};
7use bitvec::bitvec;
8use bitvec::vec::BitVec;
9
10pub struct BitVectorSubgraph<'a, Graph> {
12 parent_graph: &'a Graph,
13 present_nodes: BitVec,
14 present_edges: BitVec,
15}
16
17impl<'a, Graph: SubgraphBase> BitVectorSubgraph<'a, Graph>
18where
19 Graph::RootGraph: ImmutableGraphContainer,
20{
21 pub fn new_empty(parent_graph: &'a Graph) -> Self {
24 Self {
25 parent_graph,
26 present_nodes: bitvec![0; parent_graph.root().node_count()],
27 present_edges: bitvec![0; parent_graph.root().edge_count()],
28 }
29 }
30}
31
32impl<Graph: GraphBase> GraphBase for BitVectorSubgraph<'_, Graph> {
33 type NodeData = Graph::NodeData;
34 type EdgeData = Graph::EdgeData;
35 type OptionalNodeIndex = Graph::OptionalNodeIndex;
36 type OptionalEdgeIndex = Graph::OptionalEdgeIndex;
37 type NodeIndex = Graph::NodeIndex;
38 type EdgeIndex = Graph::EdgeIndex;
39}
40
41impl<Graph: ImmutableGraphContainer> ImmutableGraphContainer for BitVectorSubgraph<'_, Graph> {
42 type NodeIndices<'a>
43 = std::iter::Filter<Graph::NodeIndices<'a>, Box<dyn 'a + Fn(&Graph::NodeIndex) -> bool>>
44 where
45 Self: 'a,
46 Graph: 'a;
47 type EdgeIndices<'a>
48 = std::iter::Filter<Graph::EdgeIndices<'a>, Box<dyn 'a + Fn(&Graph::EdgeIndex) -> bool>>
49 where
50 Self: 'a,
51 Graph: 'a;
52
53 fn node_indices(&self) -> Self::NodeIndices<'_> {
54 self.parent_graph
55 .node_indices()
56 .filter(Box::new(|&node_index| self.contains_node_index(node_index)))
57 }
58
59 fn edge_indices(&self) -> Self::EdgeIndices<'_> {
60 self.parent_graph
61 .edge_indices()
62 .filter(Box::new(|&edge_index| self.contains_edge_index(edge_index)))
63 }
64 type NodeIndicesCopied = std::vec::IntoIter<Graph::NodeIndex>;
65 type EdgeIndicesCopied = std::vec::IntoIter<Graph::EdgeIndex>;
66 fn node_indices_copied(&self) -> Self::NodeIndicesCopied {
67 self.node_indices().collect::<Vec<_>>().into_iter()
68 }
69
70 fn edge_indices_copied(&self) -> Self::EdgeIndicesCopied {
71 self.edge_indices().collect::<Vec<_>>().into_iter()
72 }
73
74 fn contains_node_index(&self, node_id: Self::NodeIndex) -> bool {
75 debug_assert!(
76 self.parent_graph.contains_node_index(node_id)
77 || !self.present_nodes[node_id.as_usize()]
78 );
79 self.present_nodes[node_id.as_usize()]
80 }
81
82 fn contains_edge_index(&self, edge_id: Self::EdgeIndex) -> bool {
83 debug_assert!(
84 self.parent_graph.contains_edge_index(edge_id)
85 || !self.present_edges[edge_id.as_usize()]
86 );
87 self.present_edges[edge_id.as_usize()]
88 }
89
90 fn node_count(&self) -> usize {
91 self.node_indices().count()
92 }
93
94 fn edge_count(&self) -> usize {
95 self.edge_indices().count()
96 }
97
98 fn node_data(&self, node_id: Self::NodeIndex) -> &Self::NodeData {
99 debug_assert!(self.contains_node_index(node_id));
100 self.parent_graph.node_data(node_id)
101 }
102
103 fn edge_data(&self, edge_id: Self::EdgeIndex) -> &Self::EdgeData {
104 debug_assert!(self.contains_edge_index(edge_id));
105 self.parent_graph.edge_data(edge_id)
106 }
107
108 fn edge_endpoints(&self, edge_id: Self::EdgeIndex) -> Edge<Self::NodeIndex> {
109 debug_assert!(self.contains_edge_index(edge_id));
110 self.parent_graph.edge_endpoints(edge_id)
111 }
112}
113
114impl<Graph: NavigableGraph> NavigableGraph for BitVectorSubgraph<'_, Graph> {
115 type OutNeighbors<'a>
116 = FilterNeighborIterator<'a, <Graph as NavigableGraph>::OutNeighbors<'a>, Self>
117 where
118 Self: 'a;
119 type InNeighbors<'a>
120 = FilterNeighborIterator<'a, <Graph as NavigableGraph>::InNeighbors<'a>, Self>
121 where
122 Self: 'a;
123 type EdgesBetween<'a>
124 = FilterEdgeIndexIterator<'a, <Graph as NavigableGraph>::EdgesBetween<'a>, Self>
125 where
126 Self: 'a;
127
128 fn out_neighbors(&self, node_id: Self::NodeIndex) -> Self::OutNeighbors<'_> {
129 FilterNeighborIterator::new(self.parent_graph.out_neighbors(node_id), self)
130 }
131
132 fn in_neighbors(&self, node_id: Self::NodeIndex) -> Self::InNeighbors<'_> {
133 FilterNeighborIterator::new(self.parent_graph.in_neighbors(node_id), self)
134 }
135
136 fn edges_between(
137 &self,
138 from_node_id: Self::NodeIndex,
139 to_node_id: Self::NodeIndex,
140 ) -> Self::EdgesBetween<'_> {
141 FilterEdgeIndexIterator::new(
142 self.parent_graph.edges_between(from_node_id, to_node_id),
143 self,
144 )
145 }
146}
147
148impl<Graph: SubgraphBase> SubgraphBase for BitVectorSubgraph<'_, Graph> {
149 type RootGraph = Graph::RootGraph;
150
151 fn root(&self) -> &Self::RootGraph {
152 self.parent_graph.root()
153 }
154}
155
156impl<Graph: ImmutableGraphContainer + SubgraphBase> MutableSubgraph for BitVectorSubgraph<'_, Graph>
157where
158 Self: GraphBase<
159 NodeIndex = <Graph as GraphBase>::NodeIndex,
160 EdgeIndex = <Graph as GraphBase>::EdgeIndex,
161 >,
162{
163 fn clear(&mut self) {
164 self.present_nodes.fill(false);
165 self.present_edges.fill(false);
166 }
167
168 fn fill(&mut self) {
169 self.parent_graph
170 .node_indices()
171 .for_each(|node_index| self.enable_node(node_index));
172 self.parent_graph
173 .edge_indices()
174 .for_each(|edge_index| self.enable_edge(edge_index));
175 }
176
177 fn enable_node(
178 &mut self,
179 node_index: <<Self as SubgraphBase>::RootGraph as GraphBase>::NodeIndex,
180 ) {
181 debug_assert!(self.parent_graph.contains_node_index(node_index));
182 self.present_nodes.set(node_index.as_usize(), true);
183 }
184
185 fn enable_edge(
186 &mut self,
187 edge_index: <<Self as SubgraphBase>::RootGraph as GraphBase>::EdgeIndex,
188 ) {
189 debug_assert!(self.parent_graph.contains_edge_index(edge_index));
190 self.present_edges.set(edge_index.as_usize(), true);
191 }
192
193 fn disable_node(
194 &mut self,
195 node_index: <<Self as SubgraphBase>::RootGraph as GraphBase>::NodeIndex,
196 ) {
197 debug_assert!(self.parent_graph.contains_node_index(node_index));
198 self.present_nodes.set(node_index.as_usize(), false);
199 }
200
201 fn disable_edge(
202 &mut self,
203 edge_index: <<Self as SubgraphBase>::RootGraph as GraphBase>::EdgeIndex,
204 ) {
205 debug_assert!(self.parent_graph.contains_edge_index(edge_index));
206 self.present_edges.set(edge_index.as_usize(), false);
207 }
208}
209
210impl<'a, Graph: ImmutableGraphContainer + SubgraphBase> EmptyConstructibleSubgraph<'a>
211 for BitVectorSubgraph<'a, Graph>
212where
213 Self: SubgraphBase<RootGraph = Graph>,
214{
215 fn new_empty(root_graph: &'a <Self as SubgraphBase>::RootGraph) -> Self {
216 Self {
217 parent_graph: root_graph,
218 present_nodes: bitvec![0; root_graph.node_count()],
219 present_edges: bitvec![0; root_graph.edge_count()],
220 }
221 }
222}
223
224#[cfg(test)]
225mod tests {
226 use crate::implementation::petgraph_impl::PetGraph;
227 use crate::implementation::subgraphs::bit_vector_subgraph::BitVectorSubgraph;
228 use crate::interface::subgraph::MutableSubgraph;
229 use crate::interface::{ImmutableGraphContainer, MutableGraphContainer};
230 use bitvec::bitvec;
231
232 #[test]
233 fn test_bitvec_construction() {
234 let bv = bitvec![0; 12];
235 assert_eq!(bv.len(), 12);
236 assert_eq!(bv.iter_ones().sum::<usize>(), 0);
237 assert_eq!(bv.iter_zeros().sum::<usize>(), (0..12).sum());
238 }
239
240 #[test]
241 fn test_clear() {
242 let mut graph = PetGraph::new();
243 let n: Vec<_> = (0..10).map(|i| graph.add_node(i)).collect();
244 let e: Vec<_> = (0..9)
245 .map(|i| graph.add_edge(n[i], n[i + 1], i + 100))
246 .collect();
247 let mut subgraph = BitVectorSubgraph::new_empty(&graph);
248 assert!(subgraph.node_indices().next().is_none());
249 assert!(subgraph.edge_indices().next().is_none());
250
251 subgraph.enable_node(n[2]);
252 subgraph.enable_node(n[3]);
253 subgraph.enable_edge(e[2]);
254 assert_eq!(
255 subgraph.node_indices().collect::<Vec<_>>(),
256 n[2..4].to_vec()
257 );
258 assert_eq!(
259 subgraph.edge_indices().collect::<Vec<_>>(),
260 e[2..3].to_vec()
261 );
262
263 subgraph.clear();
264 assert!(subgraph.node_indices().next().is_none());
265 assert!(subgraph.edge_indices().next().is_none());
266 }
267}