1use std::collections::HashSet;
2
3use anyhow::{Context, Result};
4
5use crate::{
6 graph::error::Error,
7 provide::{Edges, Graph, Neighbors, Vertices},
8};
9
10use super::{AsFrozenSubgraph, AsSubgraph, Subgraph};
11use crate::graph::{Edge, EdgeDir};
12
13pub struct MultiRootSubgraph<'a, W, E, Dir, G>
25where
26 E: Edge<W>,
27 Dir: EdgeDir,
28 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors,
29{
30 roots: Vec<usize>,
31 subgraph: Subgraph<'a, W, E, Dir, G>,
32}
33
34impl<'a, W, E, Dir, G> MultiRootSubgraph<'a, W, E, Dir, G>
35where
36 E: Edge<W>,
37 Dir: EdgeDir,
38 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors + Vertices,
39{
40 pub fn init(
49 graph: &'a G,
50 edges: Vec<(usize, usize, usize)>,
51 vertices: HashSet<usize>,
52 roots: Vec<usize>,
53 ) -> Self {
54 MultiRootSubgraph {
55 roots,
56 subgraph: Subgraph::init(graph, edges, vertices),
57 }
58 }
59
60 pub fn roots(&self) -> &Vec<usize> {
66 &self.roots
67 }
68
69 pub fn is_root(&self, vertex_id: usize) -> bool {
79 self.roots.contains(&vertex_id)
80 }
81
82 pub fn add_root(&mut self, vertex_id: usize) -> Result<()> {
93 if self.is_root(vertex_id) {
94 Err(Error::new_rae(vertex_id)).with_context(|| "MultiRootSubgraph failed")?
95 } else {
96 self.add_vertex_from_graph(vertex_id)?;
97
98 self.roots.push(vertex_id);
99
100 Ok(())
101 }
102 }
103
104 pub fn add_root_unchecked(&mut self, vertex_id: usize) {
109 self.add_vertex_from_graph_unchecked(vertex_id);
110
111 self.roots.push(vertex_id);
112 }
113}
114
115impl<'a, W, E, Dir, G> Neighbors for MultiRootSubgraph<'a, W, E, Dir, G>
117where
118 E: Edge<W>,
119 Dir: EdgeDir,
120 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors,
121{
122 fn neighbors(&self, src_id: usize) -> anyhow::Result<Vec<usize>> {
123 self.subgraph.neighbors(src_id)
124 }
125
126 fn neighbors_unchecked(&self, src_id: usize) -> Vec<usize> {
127 self.subgraph.neighbors_unchecked(src_id)
128 }
129}
130
131impl<'a, W, E, Dir, G> Vertices for MultiRootSubgraph<'a, W, E, Dir, G>
133where
134 E: Edge<W>,
135 Dir: EdgeDir,
136 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors,
137{
138 fn vertices(&self) -> Vec<usize> {
139 self.subgraph.vertices()
140 }
141
142 fn contains_vertex(&self, vertex_id: usize) -> bool {
143 self.subgraph.contains_vertex(vertex_id)
144 }
145}
146
147impl<'a, W, E, Dir, G> Edges<W, E> for MultiRootSubgraph<'a, W, E, Dir, G>
149where
150 E: Edge<W>,
151 Dir: EdgeDir,
152 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors,
153{
154 fn edges_from(&self, src_id: usize) -> anyhow::Result<Vec<(usize, &E)>> {
155 self.subgraph.edges_from(src_id)
156 }
157
158 fn edges_from_unchecked(&self, src_id: usize) -> Vec<(usize, &E)> {
159 self.subgraph.edges_from_unchecked(src_id)
160 }
161
162 fn edges_between(&self, src_id: usize, dst_id: usize) -> anyhow::Result<Vec<&E>> {
163 self.subgraph.edges_between(src_id, dst_id)
164 }
165
166 fn edges_between_unchecked(&self, src_id: usize, dst_id: usize) -> Vec<&E> {
167 self.subgraph.edges_between_unchecked(src_id, dst_id)
168 }
169
170 fn edge_between(&self, src_id: usize, dst_id: usize, edge_id: usize) -> anyhow::Result<&E> {
171 self.subgraph.edge_between(src_id, dst_id, edge_id)
172 }
173
174 fn edge_between_unchecked(&self, src_id: usize, dst_id: usize, edge_id: usize) -> &E {
175 self.subgraph
176 .edge_between_unchecked(src_id, dst_id, edge_id)
177 }
178
179 fn edge(&self, edge_id: usize) -> anyhow::Result<&E> {
180 self.subgraph.edge(edge_id)
181 }
182
183 fn edge_unchecked(&self, edge_id: usize) -> &E {
184 self.subgraph.edge_unchecked(edge_id)
185 }
186
187 fn has_any_edge(&self, src_id: usize, dst_id: usize) -> anyhow::Result<bool> {
188 self.subgraph.has_any_edge(src_id, dst_id)
189 }
190
191 fn has_any_edge_unchecked(&self, src_id: usize, dst_id: usize) -> bool {
192 self.subgraph.has_any_edge_unchecked(src_id, dst_id)
193 }
194
195 fn edges(&self) -> Vec<(usize, usize, &E)> {
196 self.subgraph.edges()
197 }
198
199 fn as_directed_edges(&self) -> Vec<(usize, usize, &E)> {
200 self.subgraph.as_directed_edges()
201 }
202
203 fn edges_count(&self) -> usize {
204 self.subgraph.edges_count()
205 }
206
207 fn contains_edge(&self, edge_id: usize) -> bool {
208 self.subgraph.contains_edge(edge_id)
209 }
210}
211
212impl<'a, W, E, Dir, G> AsFrozenSubgraph<W, E> for MultiRootSubgraph<'a, W, E, Dir, G>
213where
214 E: Edge<W>,
215 Dir: EdgeDir,
216 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors,
217{
218}
219
220impl<'a, W, E, Dir, G> AsSubgraph<W, E> for MultiRootSubgraph<'a, W, E, Dir, G>
222where
223 E: Edge<W>,
224 Dir: EdgeDir,
225 G: Graph<W, E, Dir> + Edges<W, E> + Neighbors + Vertices,
226{
227 fn remove_edge(&mut self, src_id: usize, dst_id: usize, edge_id: usize) -> Result<()> {
228 self.subgraph.remove_edge(src_id, dst_id, edge_id)
229 }
230
231 fn remove_edge_unchecked(&mut self, src_id: usize, dst_id: usize, edge_id: usize) {
232 self.subgraph.remove_edge_unchecked(src_id, dst_id, edge_id)
233 }
234
235 fn remove_vertex(&mut self, vertex_id: usize) -> Result<()> {
236 self.subgraph.remove_vertex(vertex_id)?;
237
238 self.roots.retain(|v_id| *v_id != vertex_id);
239
240 Ok(())
241 }
242
243 fn remove_vertex_unchecked(&mut self, vertex_id: usize) {
244 self.subgraph.remove_vertex_unchecked(vertex_id);
245
246 self.roots.retain(|v_id| *v_id != vertex_id);
247 }
248
249 fn add_vertex_from_graph(&mut self, vertex_id: usize) -> Result<()> {
250 self.subgraph.add_vertex_from_graph(vertex_id)
251 }
252
253 fn add_vertex_from_graph_unchecked(&mut self, vertex_id: usize) {
254 self.subgraph.add_vertex_from_graph_unchecked(vertex_id)
255 }
256
257 fn add_edge_from_graph(&mut self, src_id: usize, dst_id: usize, edge_id: usize) -> Result<()> {
258 self.subgraph.add_edge_from_graph(src_id, dst_id, edge_id)
259 }
260
261 fn add_edge_from_graph_unchecked(&mut self, src_id: usize, dst_id: usize, edge_id: usize) {
262 self.subgraph
263 .add_edge_from_graph_unchecked(src_id, dst_id, edge_id)
264 }
265}