1use super::*;
2use log::warn;
3use rayon::prelude::ParallelIterator;
4use smallvec::SmallVec;
5use std::collections::{BTreeMap, HashSet};
6use std::fmt::Debug;
7
8use crate::kosaraju;
9use itertools::Itertools;
10use std::iter;
11
12pub trait DirectedGraphTrait<V, E>: Send + Sync + Sized {
13 fn new() -> Self;
14
15 fn in_neighbours(&self, vertex: i64) -> impl Iterator<Item = i64>;
16 fn num_in_neighbours(&self, vertex: i64) -> Option<usize> {
17 if self.contains_vertex(&vertex) {
18 Some(self.in_neighbours(vertex).count())
19 } else {
20 None
21 }
22 }
23 fn in_edges(&self, vertex: i64) -> impl Iterator<Item = (i64, i64)> {
25 self.in_neighbours(vertex).map(move |nid0| (nid0, vertex))
26 }
27 fn out_neighbours(&self, vertex: i64) -> impl Iterator<Item = i64>;
28 fn out_neighbours_w_prop<'a>(&'a self, from_vertex: i64) -> impl Iterator<Item = (i64, &'a E)>
29 where
30 E: 'a;
31 fn num_out_neighbours(&self, vertex: i64) -> Option<usize> {
32 if self.contains_vertex(&vertex) {
33 Some(self.out_neighbours(vertex).count())
34 } else {
35 None
36 }
37 }
38
39 fn out_edges(&self, vertex: i64) -> impl Iterator<Item = (i64, i64)> {
41 self.out_neighbours(vertex).map(move |nid2| (vertex, nid2))
42 }
43
44 fn edges(&self, vertex: i64) -> impl Iterator<Item = (i64, i64)> {
46 self.in_edges(vertex).chain(self.out_edges(vertex))
47 }
48
49 fn all_connected_edges(&self, edge: &(i64, i64)) -> impl Iterator<Item = (i64, i64)> {
52 self.in_neighbours(edge.0)
53 .map(|v0| (v0, edge.0))
54 .chain(self.out_neighbours(edge.0).map(|v2| (edge.0, v2)))
55 .chain(self.in_neighbours(edge.1).map(|v0| (v0, edge.1)))
56 .chain(self.out_neighbours(edge.1).map(|v2| (edge.1, v2)))
57 .filter(move |new_edge| new_edge != edge)
58 }
59
60 fn contains_edge(&self, from_vertex: impl Into<i64>, to_vertex: impl Into<i64>) -> bool {
61 let to_vertex = to_vertex.into();
62 self.out_neighbours(from_vertex.into())
63 .any(|v| v == to_vertex)
64 }
65
66 fn num_vertexes(&self) -> usize;
67 fn num_edges(&self) -> usize {
68 self.edges_iter().count()
69 }
70 fn contains_vertex(&self, vid: &i64) -> bool;
72
73 fn edges_iter(&self) -> impl Iterator<Item = (i64, i64)> + '_;
75 fn edges_par_iter(&self) -> impl ParallelIterator<Item = (i64, i64)>;
76
77 fn vertexes_and_num_outs(&self) -> impl Iterator<Item = (i64, usize)> + '_;
79
80 fn len(&self) -> (usize, usize) {
81 (self.num_vertexes(), self.num_edges())
82 }
83
84 fn is_empty(&self) -> bool {
85 self.num_vertexes() == 0
86 }
87
88 fn dest_vertexes_jumbled(&self) -> impl ParallelIterator<Item = i64> {
90 self.edges_par_iter().map(|(_src, dest)| dest)
91 }
92 fn src_vertexes_jumbled(&self) -> impl Iterator<Item = i64> {
94 self.edges_iter().map(|(src, _dest)| src)
95 }
96
97 fn vertex_has_outgoing(&self, vid: &i64) -> bool {
99 self.out_neighbours(*vid).next().is_some()
100 }
101
102 fn detailed_size(&self) -> String;
103
104 fn num_ins_zero(&self, vid: &i64) -> bool {
109 self.num_in_neighbours(*vid) == Some(0)
110 }
111
112 fn vertexes_and_num_ins_outs(&self) -> impl Iterator<Item = (i64, usize, usize)> + '_;
114
115 fn vertexes_wo_outgoing_jumbled(&self) -> impl ParallelIterator<Item = i64>
117 where
118 Self: Sync,
119 {
120 self.dest_vertexes_jumbled()
121 .filter(|v| !self.vertex_has_outgoing(v))
122 }
123
124 fn all_in_edges_recursive(
126 &self,
127 nid: i64,
128 incl_nid: impl Fn(&i64) -> bool,
129 nodeid_pos: &impl NodeIdPosition,
130 ) -> impl Iterator<Item = Vec<(f64, f64)>> {
131 let mut frontier: SmallVec<[_; 1]> = smallvec::smallvec![];
132 let mut seen_vertexes = HashSet::new();
133 if incl_nid(&nid) {
134 frontier.push((nid, None));
135 }
136
137 std::iter::from_fn(move || {
141 if frontier.is_empty() {
142 return None;
143 }
144
145 let (mut curr_point, opt_prev_point) = frontier.pop().unwrap();
146 let mut curr_latlng;
147 let mut curr_path = Vec::with_capacity(10);
148
149 if let Some(prev_point) = opt_prev_point {
150 curr_path.push(prev_point);
151 }
152 loop {
153 curr_latlng = nodeid_pos.get(&curr_point).unwrap();
154 curr_path.push(curr_latlng);
155 seen_vertexes.insert(curr_point);
156 let mut ins = self
157 .in_neighbours(curr_point)
158 .filter(|i| !seen_vertexes.contains(i));
159 match ins.next() {
160 Some(nxt) => {
161 frontier.extend(
163 ins.filter(|n| incl_nid(n))
164 .map(|in_nid| (in_nid, Some(curr_latlng))),
165 );
166
167 curr_point = nxt;
168 continue;
169 }
170 _ => {
171 curr_path.reverse();
173 return Some(curr_path);
174 }
175 }
176 }
177 })
178 }
179 fn neighbors_in_xor_out(&mut self, v: &i64) -> bool {
181 (self.num_in_neighbours(*v) == Some(0)) ^ (self.num_out_neighbours(*v) == Some(0))
182 }
183 fn delete_edge(&mut self, vertex1: &i64, vertex2: &i64);
184
185 fn expand_edge(&self, vertex1: i64, vertex2: i64) -> impl Iterator<Item = i64> + '_ {
186 iter::once(vertex1).chain(iter::once(vertex2))
187 }
188
189 fn delete_vertex(&mut self, vertex: &i64);
191
192 fn contract_vertex(&mut self, vertex: &i64, replacement: &i64);
193 fn vertexes(&self) -> impl Iterator<Item = i64> + '_ {
195 self.vertexes_iter()
196 }
197 fn vertexes_iter(&self) -> impl Iterator<Item = i64> + '_;
198 fn vertexes_par_iter(&self) -> impl ParallelIterator<Item = i64>;
199
200 fn add_edge(&mut self, vertex1: i64, vertex2: i64) -> bool;
201 fn add_edge_chain(&mut self, vertexes: &[i64]) -> bool {
203 if vertexes.len() < 2 {
206 return false;
207 }
208 let mut added = false;
209 for w in vertexes.windows(2) {
210 added |= self.add_edge(w[0], w[1]);
211 }
212 added
213 }
214
215 fn into_vertexes_topologically_sorted(self, sorting_nodes_bar: &ProgressBar) -> Vec<i64> {
216 let mut g = self;
217 let mut result = Vec::with_capacity(g.num_vertexes());
218 let mut frontier: Vec<i64> = Vec::new();
219
220 let mut others = SmallNidVec::new();
221 loop {
222 frontier.extend(
223 g.vertexes_and_num_ins_outs().filter_map(
224 |(v, num_ins, _num_outs)| if num_ins == 0 { Some(v) } else { None },
225 ),
226 );
227 if frontier.is_empty() {
228 break;
229 }
230
231 while let Some(v) = frontier.pop() {
232 result.push(v);
233 sorting_nodes_bar.inc(1);
234
235 others.truncate(0);
237 others.extend(g.out_neighbours(v));
238 for other in others.drain(..) {
239 g.delete_edge(&v, &other);
240 if g.num_ins_zero(&other) {
241 frontier.push(other);
242 }
243 }
244 }
245 }
246
247 assert!(
248 g.is_empty(),
249 "num_vertexes = {} ≠ 0, first remaining edge: {:?}",
250 g.num_vertexes(),
251 g.edges_iter().next().unwrap()
252 );
253
254 result
255 }
256
257 fn into_disconnected_graphs(self, progress_bar: &ProgressBar) -> impl Iterator<Item = Self>;
258
259 fn strongly_connected_components(
260 &self,
261 calc_components_bar: &ProgressBar,
262 ) -> Vec<Vec<[i64; 2]>> {
263 if self.is_empty() {
264 return vec![];
265 }
266 let component_for_vertex = kosaraju::kosaraju(self, calc_components_bar);
267
268 debug!(
269 "kosaraju alg finished. Have {} maps of root vertexes, for {} vertexes",
270 component_for_vertex.len(),
271 self.num_vertexes(),
272 );
273 let mut components: HashMap<i64, HashSet<i64>> = HashMap::new();
274 for (v, root_v) in component_for_vertex.iter() {
275 components
276 .entry(*root_v)
277 .or_insert_with(|| std::iter::once(*root_v).collect())
278 .insert(*v);
279 }
280
281 components
283 .into_values()
284 .map(|cycle| {
285 cycle
286 .iter()
287 .flat_map(|nid| self.out_neighbours(*nid).map(move |other| [*nid, other]))
288 .filter(|nids| cycle.contains(&nids[1]))
291 .flat_map(|nids| {
293 self.expand_edge(nids[0], nids[1])
294 .tuple_windows::<(i64, i64)>()
295 })
296 .map(|nid_tuple| [nid_tuple.0, nid_tuple.1])
297 .collect()
298 })
299 .collect()
300 }
301
302 fn delete_vertex_if_unconnected(&mut self, vertex: &i64) {
303 if self.num_in_neighbours(*vertex) == Some(0) && self.num_out_neighbours(*vertex) == Some(0)
304 {
305 self.delete_vertex(vertex);
306 }
307 }
308
309 fn vertex_property(&self, vertex: &i64) -> Option<&V>;
310 fn vertex_property_unchecked(&self, vertex: &i64) -> &V;
311
312 fn set_vertex_property(&mut self, vertex: &i64, property: V);
313 fn vertex_property_mut(&mut self, vertex: &i64) -> &mut V;
314
315 fn edge_property(&self, edge: (i64, i64)) -> Option<&E>;
316 fn edge_property_unchecked(&self, edge: (i64, i64)) -> &E;
317
318 fn set_edge_property(&mut self, edge: (i64, i64), property: E);
319
320 fn edge_property_mut(&mut self, edge: (i64, i64)) -> &mut E;
321
322 fn add_edge_w_prop(&mut self, vertex1: i64, vertex2: i64, eprop: E);
323
324 fn add_vertex_w_prop(&mut self, vertex: i64, vprop: V);
325
326 fn out_edges_w_prop<'a>(&'a self, from_vertex: i64) -> impl Iterator<Item = (i64, i64, &'a E)>
328 where
329 E: 'a;
330 fn out_edges_w_prop_mut<'a>(
331 &'a mut self,
332 from_vertex: i64,
333 ) -> impl Iterator<Item = (i64, i64, &'a mut E)>
334 where
335 E: 'a;
336 fn in_edges_w_prop<'a>(&'a self, to_vertex: i64) -> impl Iterator<Item = (i64, i64, &'a E)>
337 where
338 E: 'a;
339
340 fn edges_iter_w_prop<'a>(&'a self) -> impl Iterator<Item = (i64, i64, &'a E)>
341 where
342 E: 'a;
343 fn edges_iter_w_prop_mut<'a>(&'a mut self) -> impl Iterator<Item = (i64, i64, &'a mut E)>
344 where
345 E: 'a;
346 fn edges_par_iter_w_prop<'a>(&'a self) -> impl ParallelIterator<Item = (i64, i64, &'a E)>
347 where
348 E: 'a;
349
350 fn edges_par_iter_w_prop_mut<'a>(
351 &'a mut self,
352 ) -> impl ParallelIterator<Item = (i64, i64, &'a mut E)>
353 where
354 E: 'a;
355
356 fn assert_consistancy(&self);
357
358 fn remove_vertex(&mut self, vertex: &i64) -> Option<V>;
361
362 fn remove_edge(&mut self, vertex1: &i64, vertex2: &i64) -> Option<E>;
363
364 fn vertexes_w_prop<'a>(&'a self) -> impl Iterator<Item = (i64, &'a V)>
365 where
366 V: 'a;
367 fn vertexes_w_prop_par<'a>(&'a self) -> impl ParallelIterator<Item = (i64, &'a V)>
368 where
369 V: 'a;
370 fn vertexes_w_prop_par_mut<'a>(&'a mut self) -> impl ParallelIterator<Item = (i64, &'a mut V)>
371 where
372 V: 'a;
373
374 fn edges_w_prop_par_mut<'a>(
375 &'a mut self,
376 ) -> impl ParallelIterator<Item = ((i64, i64), &'a mut E)>
377 where
378 E: 'a;
379}
380
381#[derive(Default, Debug, Clone)]
382struct Vertex<V, E> {
383 vprop: V,
384 ins: SmallVec<[i64; 1]>,
385 outs: SmallVec<[(i64, E); 1]>,
386}
387
388impl<V, E> Vertex<V, E> {
389 #[allow(clippy::type_complexity)]
390 fn into_parts(self) -> (V, SmallVec<[i64; 1]>, SmallVec<[(i64, E); 1]>) {
391 (self.vprop, self.ins, self.outs)
392 }
393}
394
395#[derive(Default, Debug, Clone)]
397pub struct DirectedGraph<V, E>
398where
399 V: Send + Default + Clone + Sync + Debug,
400 E: Send + Default + Clone + Sync + Debug,
401{
402 edges: BTreeMap<i64, Vertex<V, E>>,
404}
405
406impl<V, E> DirectedGraph<V, E>
407where
408 V: Send + Default + Clone + Sync + Debug,
409 E: Send + Default + Clone + Sync + Debug,
410{
411}
412
413impl<V, E> DirectedGraphTrait<V, E> for DirectedGraph<V, E>
414where
415 V: Send + Default + Clone + Sync + Debug,
416 E: Send + Default + Clone + Sync + Debug,
417{
418 fn new() -> Self {
419 Default::default()
420 }
421 fn num_in_neighbours(&self, vertex: i64) -> Option<usize> {
422 self.edges.get(&vertex).map(|v| v.ins.len())
423 }
424 fn num_out_neighbours(&self, vertex: i64) -> Option<usize> {
425 self.edges.get(&vertex).map(|v| v.outs.len())
426 }
427
428 fn out_neighbours(&self, from_vertex: i64) -> impl Iterator<Item = i64> {
429 self.edges
430 .get(&from_vertex)
431 .into_iter()
432 .flat_map(|v| v.outs.iter().map(|(nid, _eprop)| nid))
433 .copied()
434 }
435 fn out_neighbours_w_prop<'a>(&'a self, from_vertex: i64) -> impl Iterator<Item = (i64, &'a E)>
436 where
437 E: 'a,
438 {
439 self.edges
440 .get(&from_vertex)
441 .into_iter()
442 .flat_map(|v| v.outs.iter())
443 .map(|(nid2, eprop)| (*nid2, eprop))
444 }
445 fn in_neighbours(&self, from_vertex: i64) -> impl Iterator<Item = i64> {
446 self.edges
447 .get(&from_vertex)
448 .into_iter()
449 .flat_map(|v| v.ins.iter())
450 .copied()
451 }
452
453 fn num_vertexes(&self) -> usize {
454 self.edges.len()
455 }
456 fn num_edges(&self) -> usize {
457 self.edges.values().map(|v| v.outs.len()).sum()
458 }
459 fn contains_vertex(&self, vid: &i64) -> bool {
461 self.edges.contains_key(vid)
462 }
463
464 fn edges_iter(&self) -> impl Iterator<Item = (i64, i64)> {
466 self.edges
467 .iter()
468 .flat_map(move |(nid, v)| v.outs.iter().map(move |(o, _eprop)| (*nid, *o)))
469 }
470 fn edges_par_iter(&self) -> impl ParallelIterator<Item = (i64, i64)> {
471 self.edges_iter().par_bridge()
472 }
473
474 fn vertexes_and_num_outs(&self) -> impl Iterator<Item = (i64, usize)> {
476 self.edges.iter().map(|(nid1, v)| (*nid1, v.outs.len()))
477 }
478
479 fn vertex_has_outgoing(&self, vid: &i64) -> bool {
480 self.edges.get(vid).is_some_and(|v| !v.outs.is_empty())
481 }
482
483 fn detailed_size(&self) -> String {
484 let s = format!(
485 "DirectedGraph: num_vertexes {} num_edges {}",
486 self.num_vertexes(),
487 self.num_edges(),
488 );
489 s
498 }
499
500 fn num_ins_zero(&self, vid: &i64) -> bool {
501 self.edges.get(vid).is_none_or(|v| v.ins.is_empty())
502 }
503
504 fn is_empty(&self) -> bool {
505 self.edges.is_empty()
506 }
507
508 fn vertexes_and_num_ins_outs(&self) -> impl Iterator<Item = (i64, usize, usize)> + '_ {
509 self.edges
510 .iter()
511 .map(|(nid, v)| (*nid, v.ins.len(), v.outs.len()))
512 }
513
514 fn neighbors_in_xor_out(&mut self, v: &i64) -> bool {
515 self.edges
516 .get(v)
517 .is_some_and(|v| !v.ins.is_empty() ^ !v.outs.is_empty())
518 }
519 fn delete_edge(&mut self, vertex1: &i64, vertex2: &i64) {
520 self.remove_edge(vertex1, vertex2);
521 }
522
523 fn delete_vertex(&mut self, vertex: &i64) {
524 self.remove_vertex(vertex);
525 }
526
527 fn contract_vertex(&mut self, vertex: &i64, replacement: &i64) {
528 if vertex == replacement {
529 warn!("Trying to contract a vertex with itself: {}", vertex);
530 return;
531 }
532 if !self.contains_vertex(vertex) && !self.contains_vertex(replacement) {
533 warn!(
534 "Trying to replace the vertex {vertex} with {replacement}, but neither are in the graph"
535 );
536 return;
537 }
538 assert!(
539 self.contains_vertex(vertex),
540 "Vertex to replace {vertex} doesn't exist"
541 );
542 assert!(
543 self.contains_vertex(replacement),
544 "Replacement vertex {replacement} doesn't exist"
545 );
546
547 let mut old = match self.edges.remove(vertex) {
548 None => {
549 return;
550 }
551 Some(old) => old,
552 };
553
554 self.set_vertex_property(replacement, old.vprop);
555
556 for (out_v, eprop) in old.outs.drain(..) {
557 self.edges
558 .get_mut(&out_v)
559 .unwrap()
560 .ins
561 .retain(|in_v| in_v != vertex);
562 self.add_edge_w_prop(*replacement, out_v, eprop);
563 }
564 for in_v in old.ins.iter() {
565 if let Some(eprop) = self.remove_edge(in_v, vertex) {
566 self.add_edge_w_prop(*in_v, *replacement, eprop);
567 }
568 }
569 }
570
571 fn vertexes_iter(&self) -> impl Iterator<Item = i64> + '_ {
572 self.edges.keys().copied()
573 }
574 fn vertexes_par_iter(&self) -> impl ParallelIterator<Item = i64> {
575 self.edges.par_iter().map(|(nid, _)| nid).copied()
576 }
577
578 fn add_edge(&mut self, vertex1: i64, vertex2: i64) -> bool {
580 if vertex1 == vertex2 {
581 return false;
582 }
583 let from_v1 = &mut self.edges.entry(vertex1).or_default().outs;
584 if from_v1.iter().any(|(vid, _eprop)| vid == &vertex2) {
585 return true;
586 } else {
587 from_v1.push((vertex2, E::default()));
588 }
589
590 let other = self.edges.entry(vertex2).or_default();
592 other.ins.push(vertex1);
593 other.ins.sort();
594 false
595 }
596
597 fn into_disconnected_graphs(self, progress_bar: &ProgressBar) -> impl Iterator<Item = Self> {
598 dbg!("here");
599 let mut g = self;
600 let mut vertexes_to_look_at = Vec::new();
601
602 std::iter::from_fn(move || {
603 if g.is_empty() {
604 return None;
605 }
606 let mut new_graph: DirectedGraph<V, E> = DirectedGraph::new();
607 vertexes_to_look_at.truncate(0);
608 vertexes_to_look_at.push(g.vertexes().next().unwrap());
609 let mut num_vertexes = 0;
610
611 while let Some(vertex) = vertexes_to_look_at.pop() {
612 num_vertexes += 1;
613 if !g.contains_vertex(&vertex) {
614 continue;
615 }
616
617 let (vprop, ins, outs) = g.edges.remove(&vertex).unwrap().into_parts();
618 new_graph.add_vertex_w_prop(vertex, vprop);
619
620 for (out_v, eprop) in outs.into_iter() {
621 new_graph.add_edge_w_prop(vertex, out_v, eprop);
622 vertexes_to_look_at.push(out_v);
623 }
624 vertexes_to_look_at.extend(ins.into_iter());
625 }
626
627 progress_bar.inc(num_vertexes as u64);
628 Some(new_graph)
629 })
630 }
631
632 fn vertex_property(&self, vertex: &i64) -> Option<&V> {
633 self.edges.get(vertex).map(|v| &v.vprop)
634 }
635 fn vertex_property_unchecked(&self, vertex: &i64) -> &V {
636 self.vertex_property(vertex).unwrap()
637 }
638
639 fn set_vertex_property(&mut self, vertex: &i64, property: V) {
640 self.edges.entry(*vertex).or_default().vprop = property;
641 }
642 fn vertex_property_mut(&mut self, vertex: &i64) -> &mut V {
643 &mut self.edges.entry(*vertex).or_default().vprop
644 }
645
646 fn edge_property(&self, edge: (i64, i64)) -> Option<&E> {
647 self.edges.get(&edge.0).map(|v| &v.outs).and_then(|outs| {
648 outs.iter()
649 .find(|(vid, _p)| *vid == edge.1)
650 .map(|(_vid, prop)| prop)
651 })
652 }
653 fn edge_property_unchecked(&self, edge: (i64, i64)) -> &E {
654 self.edge_property(edge).unwrap()
655 }
656
657 fn set_edge_property(&mut self, edge: (i64, i64), property: E) {
658 if edge.0 == edge.1 {
659 return;
660 }
661 *self.edge_property_mut(edge) = property;
662 }
663
664 fn edge_property_mut(&mut self, edge: (i64, i64)) -> &mut E {
665 let vertex = self.edges.get_mut(&edge.0).unwrap();
666 let outs = &mut vertex.outs;
667 if !outs.iter().any(|(oid, _eprop)| *oid == edge.1) {
668 outs.push((edge.1, E::default()));
669 }
670
671 outs.iter_mut()
672 .filter(|(oid, _)| *oid == edge.1)
673 .map(|(_, eprop)| eprop)
674 .next()
675 .unwrap()
676 }
677
678 fn add_edge_w_prop(&mut self, vertex1: i64, vertex2: i64, eprop: E) {
679 if vertex1 == vertex2 {
680 return;
681 }
682 self.add_edge(vertex1, vertex2);
683 self.set_edge_property((vertex1, vertex2), eprop);
684 }
685
686 fn add_vertex_w_prop(&mut self, vertex: i64, vprop: V) {
687 self.edges
689 .entry(vertex)
690 .and_modify(|o| o.vprop = vprop.clone())
691 .or_insert(Vertex {
692 vprop,
693 ..Default::default()
694 });
695 }
696
697 fn out_edges_w_prop<'a>(&'a self, from_vertex: i64) -> impl Iterator<Item = (i64, i64, &'a E)>
699 where
700 E: 'a,
701 {
702 self.edges.get(&from_vertex).into_iter().flat_map(move |v| {
703 v.outs
704 .iter()
705 .map(move |(nid2, eprop)| (from_vertex, *nid2, eprop))
706 })
707 }
708 fn out_edges_w_prop_mut<'a>(
710 &'a mut self,
711 from_vertex: i64,
712 ) -> impl Iterator<Item = (i64, i64, &'a mut E)>
713 where
714 E: 'a,
715 {
716 self.edges
717 .get_mut(&from_vertex)
718 .into_iter()
719 .flat_map(move |v| {
720 v.outs
721 .iter_mut()
722 .map(move |(nid2, eprop)| (from_vertex, *nid2, eprop))
723 })
724 }
725 fn in_edges_w_prop<'a>(&'a self, to_vertex: i64) -> impl Iterator<Item = (i64, i64, &'a E)>
726 where
727 E: 'a,
728 {
729 self.in_edges(to_vertex)
730 .map(|(nid1, nid2)| (nid1, nid2, self.edge_property_unchecked((nid1, nid2))))
731 }
732
733 fn edges_iter_w_prop<'a>(&'a self) -> impl Iterator<Item = (i64, i64, &'a E)>
734 where
735 E: 'a,
736 {
737 self.edges
738 .iter()
739 .flat_map(|(nid1, v)| v.outs.iter().map(|(nid2, eprop)| (*nid1, *nid2, eprop)))
740 }
741 fn edges_iter_w_prop_mut<'a>(&'a mut self) -> impl Iterator<Item = (i64, i64, &'a mut E)>
742 where
743 E: 'a,
744 {
745 self.edges
746 .iter_mut()
747 .flat_map(|(nid1, v)| v.outs.iter_mut().map(|(nid2, eprop)| (*nid1, *nid2, eprop)))
748 }
749 fn edges_par_iter_w_prop<'a>(&'a self) -> impl ParallelIterator<Item = (i64, i64, &'a E)>
750 where
751 E: 'a,
752 {
753 self.edges
754 .par_iter()
755 .flat_map(|(nid1, v)| v.outs.par_iter().map(|(nid2, eprop)| (*nid1, *nid2, eprop)))
756 }
757
758 fn edges_par_iter_w_prop_mut<'a>(
759 &'a mut self,
760 ) -> impl ParallelIterator<Item = (i64, i64, &'a mut E)>
761 where
762 E: 'a,
763 {
764 self.edges.par_iter_mut().flat_map(|(nid1, v)| {
765 v.outs
766 .par_iter_mut()
767 .map(|(nid2, eprop)| (*nid1, *nid2, eprop))
768 })
769 }
770
771 fn assert_consistancy(&self) {
772 for (nid1, v) in self.edges.iter() {
773 assert!(!v.ins.contains(nid1));
775 assert!(
776 !v.outs.iter().any(|(nid2, _)| nid1 == nid2),
777 "{:?} {:?}",
778 nid1,
779 v.outs
780 );
781
782 for in_v in v.ins.iter() {
784 assert!(
785 self.edges.contains_key(in_v),
786 "Node {nid1} has an in edge from {in_v}, but there is no data for that vertex {in_v}"
787 );
788 assert!(
789 self.edges
790 .get(in_v)
791 .unwrap()
792 .outs
793 .iter()
794 .any(|(otherv, _eprop)| otherv == nid1),
795 "Graph Data inconsistancy. {nid1} has {in_v} as one of it's in edges, but there is no corresponding out edge from {in_v} to {nid1}"
796 );
797 }
798 for (out_v, _eprop) in v.outs.iter() {
800 assert!(
801 self.edges.contains_key(out_v),
802 "Node {nid1} has an out edge to {out_v}, but there is no data for that vertex {out_v}"
803 );
804 assert!(self.edges.get(out_v).unwrap().ins.contains(nid1));
805 }
806 }
807
808 assert_eq!(
809 self.edges
810 .par_iter()
811 .map(|(_nid2, v)| v.ins.len())
812 .sum::<usize>(),
813 self.edges
814 .par_iter()
815 .map(|(_nid2, v)| v.outs.len())
816 .sum::<usize>()
817 );
818 }
819
820 fn remove_vertex(&mut self, vertex: &i64) -> Option<V> {
823 let (vprop, ins, outs) = self.edges.remove(vertex)?.into_parts();
824 for in_v in ins.iter() {
825 self.delete_edge(in_v, vertex);
826 }
827 for (out_v, _eprop) in outs.iter() {
828 self.delete_edge(vertex, out_v);
829 }
830 Some(vprop)
831 }
832
833 fn remove_edge(&mut self, vertex1: &i64, vertex2: &i64) -> Option<E> {
834 let outs = &mut self.edges.get_mut(vertex1)?.outs;
835 let idx = outs.iter().position(|(v, _eprop)| v == vertex2)?;
836 let (_v2, eprop) = outs.remove(idx);
837
838 if let Some(x) = self.edges.get_mut(vertex2) {
840 x.ins.retain(|v1| v1 != vertex1);
841 }
842
843 self.delete_vertex_if_unconnected(vertex1);
844 self.delete_vertex_if_unconnected(vertex2);
845
846 Some(eprop)
847 }
848
849 fn vertexes_w_prop<'a>(&'a self) -> impl Iterator<Item = (i64, &'a V)>
850 where
851 V: 'a,
852 {
853 self.edges.iter().map(|(nid, v)| (*nid, &v.vprop))
854 }
855
856 fn vertexes_w_prop_par_mut<'a>(&'a mut self) -> impl ParallelIterator<Item = (i64, &'a mut V)>
857 where
858 V: 'a,
859 {
860 self.edges
861 .par_iter_mut()
862 .map(|(nid, v)| (*nid, &mut v.vprop))
863 }
864
865 fn vertexes_w_prop_par<'a>(&'a self) -> impl ParallelIterator<Item = (i64, &'a V)>
866 where
867 V: 'a,
868 {
869 self.edges.par_iter().map(|(nid, v)| (*nid, &v.vprop))
870 }
871
872 fn edges_w_prop_par_mut<'a>(
873 &'a mut self,
874 ) -> impl ParallelIterator<Item = ((i64, i64), &'a mut E)>
875 where
876 E: 'a,
877 {
878 self.edges.par_iter_mut().flat_map(|(nid1, v)| {
879 v.outs
880 .par_iter_mut()
881 .map(|(nid2, eprop)| ((*nid1, *nid2), eprop))
882 })
883 }
884}