1#![allow(dead_code)] use std::{
7 cmp::Ordering,
8 fmt,
9 hash::{self, Hash},
10 iter::Cloned,
11 marker::PhantomData,
12 ops::Deref,
13 slice::Iter,
14};
15
16use indexmap::{
17 map::{Iter as IndexMapIter, IterMut as IndexMapIterMut, Keys},
18 IndexMap,
19};
20use petgraph::{
21 graph::{node_index, Graph},
22 visit::{
23 GraphBase, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers, NodeCount,
24 NodeIndexable, Visitable,
25 },
26 Directed, Direction, EdgeType, Incoming, IntoWeightedEdge, Outgoing, Undirected,
27};
28use rustc_hash::{FxBuildHasher, FxHashSet};
29
30pub type FastDiGraphMap<N, E> = FastGraphMap<N, E, Directed>;
35
36#[derive(Clone)]
61pub struct FastGraphMap<N, E, Ty> {
62 nodes: IndexMap<N, Vec<(N, CompactDirection)>, FxBuildHasher>,
63 edges: IndexMap<(N, N), E, FxBuildHasher>,
64 ty: PhantomData<Ty>,
65}
66
67impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType> fmt::Debug for FastGraphMap<N, E, Ty> {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 self.nodes.fmt(f)
70 }
71}
72
73pub trait NodeTrait: Copy + Ord + Hash {}
75impl<N> NodeTrait for N where N: Copy + Ord + Hash {}
76
77#[derive(Copy, Clone, Debug, PartialEq, Eq)]
79enum CompactDirection {
80 Outgoing,
81 Incoming,
82}
83
84impl From<Direction> for CompactDirection {
85 fn from(d: Direction) -> Self {
86 match d {
87 Outgoing => CompactDirection::Outgoing,
88 Incoming => CompactDirection::Incoming,
89 }
90 }
91}
92
93impl PartialEq<Direction> for CompactDirection {
94 fn eq(&self, rhs: &Direction) -> bool {
95 (*self as usize) == (*rhs as usize)
96 }
97}
98
99impl<N, E, Ty> FastGraphMap<N, E, Ty>
100where
101 N: NodeTrait,
102 Ty: EdgeType,
103{
104 pub fn new() -> Self {
106 Self::default()
107 }
108
109 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
111 FastGraphMap {
112 nodes: IndexMap::with_capacity_and_hasher(nodes, Default::default()),
113 edges: IndexMap::with_capacity_and_hasher(edges, Default::default()),
114 ty: PhantomData,
115 }
116 }
117
118 pub fn capacity(&self) -> (usize, usize) {
120 (self.nodes.capacity(), self.edges.capacity())
121 }
122
123 #[inline]
126 fn edge_key(a: N, b: N) -> (N, N) {
127 if Ty::is_directed() || a <= b {
128 (a, b)
129 } else {
130 (b, a)
131 }
132 }
133
134 pub fn is_directed(&self) -> bool {
136 Ty::is_directed()
137 }
138
139 pub fn from_edges<I>(iterable: I) -> Self
159 where
160 I: IntoIterator,
161 I::Item: IntoWeightedEdge<E, NodeId = N>,
162 {
163 Self::from_iter(iterable)
164 }
165
166 pub fn node_count(&self) -> usize {
168 self.nodes.len()
169 }
170
171 pub fn edge_count(&self) -> usize {
173 self.edges.len()
174 }
175
176 pub fn clear(&mut self) {
178 self.nodes.clear();
179 self.edges.clear();
180 }
181
182 pub fn add_node(&mut self, n: N) -> N {
184 self.nodes.entry(n).or_default();
185 n
186 }
187
188 pub fn remove_node(&mut self, n: N) -> bool {
192 let links = match self.nodes.swap_remove(&n) {
193 None => return false,
194 Some(sus) => sus,
195 };
196 for (succ, _) in links {
197 self.remove_single_edge(&succ, &n, Incoming);
199 self.edges.swap_remove(&Self::edge_key(n, succ));
201 }
202 true
203 }
204
205 pub fn contains_node(&self, n: N) -> bool {
207 self.nodes.contains_key(&n)
208 }
209
210 pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> {
232 if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) {
233 old
234 } else {
235 self.nodes
237 .entry(a)
238 .or_insert_with(|| Vec::with_capacity(1))
239 .push((b, CompactDirection::Outgoing));
240 if a != b {
241 self.nodes
243 .entry(b)
244 .or_insert_with(|| Vec::with_capacity(1))
245 .push((a, CompactDirection::Incoming));
246 }
247 None
248 }
249 }
250
251 fn remove_single_edge(&mut self, a: &N, b: &N, dir: Direction) -> bool {
255 match self.nodes.get_mut(a) {
256 None => false,
257 Some(sus) => {
258 if Ty::is_directed() {
259 match sus
260 .iter()
261 .position(|elt| elt == &(*b, CompactDirection::from(dir)))
262 {
263 Some(index) => {
264 sus.swap_remove(index);
265 true
266 }
267 None => false,
268 }
269 } else {
270 match sus.iter().position(|elt| &elt.0 == b) {
271 Some(index) => {
272 sus.swap_remove(index);
273 true
274 }
275 None => false,
276 }
277 }
278 }
279 }
280 }
281
282 pub fn remove_edge(&mut self, a: N, b: N) -> Option<E> {
298 let exist1 = self.remove_single_edge(&a, &b, Outgoing);
299 let exist2 = if a != b {
300 self.remove_single_edge(&b, &a, Incoming)
301 } else {
302 exist1
303 };
304 let weight = self.edges.shift_remove(&Self::edge_key(a, b));
305 debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
306 weight
307 }
308
309 pub fn contains_edge(&self, a: N, b: N) -> bool {
312 self.edges.contains_key(&Self::edge_key(a, b))
313 }
314
315 pub fn nodes(&self) -> Nodes<N> {
319 Nodes {
320 iter: self.nodes.keys().cloned(),
321 }
322 }
323
324 pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> {
332 Neighbors {
333 iter: match self.nodes.get(&a) {
334 Some(neigh) => neigh.iter(),
335 None => [].iter(),
336 },
337 ty: self.ty,
338 }
339 }
340
341 pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> {
353 NeighborsDirected {
354 iter: match self.nodes.get(&a) {
355 Some(neigh) => neigh.iter(),
356 None => [].iter(),
357 },
358 start_node: a,
359 dir,
360 ty: self.ty,
361 }
362 }
363
364 pub fn edges(&self, from: N) -> Edges<N, E, Ty> {
373 Edges {
374 from,
375 iter: self.neighbors(from),
376 edges: &self.edges,
377 }
378 }
379
380 pub fn edge_weight(&self, a: N, b: N) -> Option<&E> {
383 self.edges.get(&Self::edge_key(a, b))
384 }
385
386 pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> {
389 self.edges.get_mut(&Self::edge_key(a, b))
390 }
391
392 pub fn all_edges(&self) -> AllEdges<N, E, Ty> {
397 AllEdges {
398 inner: self.edges.iter(),
399 ty: self.ty,
400 }
401 }
402
403 pub fn all_edges_mut(&mut self) -> AllEdgesMut<N, E, Ty> {
408 AllEdgesMut {
409 inner: self.edges.iter_mut(),
410 ty: self.ty,
411 }
412 }
413
414 pub fn into_graph<Ix>(self) -> Graph<N, E, Ty, Ix>
426 where
427 Ix: petgraph::graph::IndexType,
428 {
429 let mut gr = Graph::with_capacity(self.node_count(), self.edge_count());
431 for (&node, _) in &self.nodes {
432 gr.add_node(node);
433 }
434 for ((a, b), edge_weight) in self.edges {
435 let (ai, _, _) = self.nodes.get_full(&a).unwrap();
436 let (bi, _, _) = self.nodes.get_full(&b).unwrap();
437 gr.add_edge(node_index(ai), node_index(bi), edge_weight);
438 }
439 gr
440 }
441}
442
443impl<N, E, Ty, Item> FromIterator<Item> for FastGraphMap<N, E, Ty>
445where
446 Item: IntoWeightedEdge<E, NodeId = N>,
447 N: NodeTrait,
448 Ty: EdgeType,
449{
450 fn from_iter<I>(iterable: I) -> Self
451 where
452 I: IntoIterator<Item = Item>,
453 {
454 let iter = iterable.into_iter();
455 let (low, _) = iter.size_hint();
456 let mut g = Self::with_capacity(0, low);
457 g.extend(iter);
458 g
459 }
460}
461
462impl<N, E, Ty, Item> Extend<Item> for FastGraphMap<N, E, Ty>
466where
467 Item: IntoWeightedEdge<E, NodeId = N>,
468 N: NodeTrait,
469 Ty: EdgeType,
470{
471 fn extend<I>(&mut self, iterable: I)
472 where
473 I: IntoIterator<Item = Item>,
474 {
475 let iter = iterable.into_iter();
476 let (low, _) = iter.size_hint();
477 self.edges.reserve(low);
478
479 for elt in iter {
480 let (source, target, weight) = elt.into_weighted_edge();
481 self.add_edge(source, target, weight);
482 }
483 }
484}
485
486macro_rules! iterator_wrap {
487 ($name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
488 item: $item: ty,
489 iter: $iter: ty,
490 ) => (
491 pub struct $name <$($typarm),*> where $($bounds)* {
492 iter: $iter,
493 }
494 impl<$($typarm),*> Iterator for $name <$($typarm),*>
495 where $($bounds)*
496 {
497 type Item = $item;
498 #[inline]
499 fn next(&mut self) -> Option<Self::Item> {
500 self.iter.next()
501 }
502
503 #[inline]
504 fn size_hint(&self) -> (usize, Option<usize>) {
505 self.iter.size_hint()
506 }
507 }
508 );
509}
510
511iterator_wrap! {
512 Nodes <'a, N> where { N: 'a + NodeTrait }
513 item: N,
514 iter: Cloned<Keys<'a, N, Vec<(N, CompactDirection)>>>,
515}
516
517pub struct Neighbors<'a, N, Ty = Undirected>
518where
519 N: 'a,
520 Ty: EdgeType,
521{
522 iter: Iter<'a, (N, CompactDirection)>,
523 ty: PhantomData<Ty>,
524}
525
526impl<N, Ty> Iterator for Neighbors<'_, N, Ty>
527where
528 N: NodeTrait,
529 Ty: EdgeType,
530{
531 type Item = N;
532
533 fn next(&mut self) -> Option<N> {
534 if Ty::is_directed() {
535 (&mut self.iter)
536 .filter_map(|&(n, dir)| if dir == Outgoing { Some(n) } else { None })
537 .next()
538 } else {
539 self.iter.next().map(|&(n, _)| n)
540 }
541 }
542}
543
544pub struct NeighborsDirected<'a, N, Ty>
545where
546 N: 'a,
547 Ty: EdgeType,
548{
549 iter: Iter<'a, (N, CompactDirection)>,
550 start_node: N,
551 dir: Direction,
552 ty: PhantomData<Ty>,
553}
554
555impl<N, Ty> Iterator for NeighborsDirected<'_, N, Ty>
556where
557 N: NodeTrait,
558 Ty: EdgeType,
559{
560 type Item = N;
561
562 fn next(&mut self) -> Option<N> {
563 if Ty::is_directed() {
564 let self_dir = self.dir;
565 let start_node = self.start_node;
566 (&mut self.iter)
567 .filter_map(move |&(n, dir)| {
568 if dir == self_dir || n == start_node {
569 Some(n)
570 } else {
571 None
572 }
573 })
574 .next()
575 } else {
576 self.iter.next().map(|&(n, _)| n)
577 }
578 }
579}
580
581pub struct Edges<'a, N, E: 'a, Ty>
582where
583 N: 'a + NodeTrait,
584 Ty: EdgeType,
585{
586 from: N,
587 edges: &'a IndexMap<(N, N), E, FxBuildHasher>,
588 iter: Neighbors<'a, N, Ty>,
589}
590
591impl<'a, N, E, Ty> Iterator for Edges<'a, N, E, Ty>
592where
593 N: 'a + NodeTrait,
594 E: 'a,
595 Ty: EdgeType,
596{
597 type Item = (N, N, &'a E);
598
599 fn next(&mut self) -> Option<Self::Item> {
600 match self.iter.next() {
601 None => None,
602 Some(b) => {
603 let a = self.from;
604 match self.edges.get(&FastGraphMap::<N, E, Ty>::edge_key(a, b)) {
605 None => unreachable!(),
606 Some(edge) => Some((a, b, edge)),
607 }
608 }
609 }
610 }
611}
612
613pub struct AllEdges<'a, N, E: 'a, Ty>
614where
615 N: 'a + NodeTrait,
616{
617 inner: IndexMapIter<'a, (N, N), E>,
618 ty: PhantomData<Ty>,
619}
620
621impl<'a, N, E, Ty> Iterator for AllEdges<'a, N, E, Ty>
622where
623 N: 'a + NodeTrait,
624 E: 'a,
625 Ty: EdgeType,
626{
627 type Item = (N, N, &'a E);
628
629 fn next(&mut self) -> Option<Self::Item> {
630 self.inner.next().map(|(&(a, b), v)| (a, b, v))
631 }
632
633 fn size_hint(&self) -> (usize, Option<usize>) {
634 self.inner.size_hint()
635 }
636
637 fn count(self) -> usize {
638 self.inner.count()
639 }
640
641 fn nth(&mut self, n: usize) -> Option<Self::Item> {
642 self.inner
643 .nth(n)
644 .map(|(&(n1, n2), weight)| (n1, n2, weight))
645 }
646
647 fn last(self) -> Option<Self::Item> {
648 self.inner
649 .last()
650 .map(|(&(n1, n2), weight)| (n1, n2, weight))
651 }
652}
653
654impl<'a, N, E, Ty> DoubleEndedIterator for AllEdges<'a, N, E, Ty>
655where
656 N: 'a + NodeTrait,
657 E: 'a,
658 Ty: EdgeType,
659{
660 fn next_back(&mut self) -> Option<Self::Item> {
661 self.inner
662 .next_back()
663 .map(|(&(n1, n2), weight)| (n1, n2, weight))
664 }
665}
666
667pub struct AllEdgesMut<'a, N, E: 'a, Ty>
668where
669 N: 'a + NodeTrait,
670{
671 inner: IndexMapIterMut<'a, (N, N), E>,
672 ty: PhantomData<Ty>,
673}
674
675impl<'a, N, E, Ty> Iterator for AllEdgesMut<'a, N, E, Ty>
676where
677 N: 'a + NodeTrait,
678 E: 'a,
679 Ty: EdgeType,
680{
681 type Item = (N, N, &'a mut E);
682
683 fn next(&mut self) -> Option<Self::Item> {
684 self.inner
685 .next()
686 .map(|(&(n1, n2), weight)| (n1, n2, weight))
687 }
688
689 fn size_hint(&self) -> (usize, Option<usize>) {
690 self.inner.size_hint()
691 }
692
693 fn count(self) -> usize {
694 self.inner.count()
695 }
696
697 fn nth(&mut self, n: usize) -> Option<Self::Item> {
698 self.inner
699 .nth(n)
700 .map(|(&(n1, n2), weight)| (n1, n2, weight))
701 }
702
703 fn last(self) -> Option<Self::Item> {
704 self.inner
705 .last()
706 .map(|(&(n1, n2), weight)| (n1, n2, weight))
707 }
708}
709
710impl<'a, N, E, Ty> DoubleEndedIterator for AllEdgesMut<'a, N, E, Ty>
711where
712 N: 'a + NodeTrait,
713 E: 'a,
714 Ty: EdgeType,
715{
716 fn next_back(&mut self) -> Option<Self::Item> {
717 self.inner
718 .next_back()
719 .map(|(&(n1, n2), weight)| (n1, n2, weight))
720 }
721}
722
723impl<N, E, Ty> Default for FastGraphMap<N, E, Ty>
725where
726 N: NodeTrait,
727 Ty: EdgeType,
728{
729 fn default() -> Self {
730 FastGraphMap::with_capacity(0, 0)
731 }
732}
733
734pub struct Ptr<'b, T: 'b>(pub &'b T);
741
742impl<T> Copy for Ptr<'_, T> {}
743impl<T> Clone for Ptr<'_, T> {
744 fn clone(&self) -> Self {
745 *self
746 }
747}
748
749fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
750 a == b
751}
752
753impl<'b, T> PartialEq for Ptr<'b, T> {
754 fn eq(&self, other: &Ptr<'b, T>) -> bool {
756 ptr_eq(self.0, other.0)
757 }
758}
759
760impl<'b, T> PartialOrd for Ptr<'b, T> {
761 fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
762 Some(self.cmp(other))
763 }
764}
765
766impl<'b, T> Ord for Ptr<'b, T> {
767 fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
770 let a: *const T = self.0;
771 let b: *const T = other.0;
772 a.cmp(&b)
773 }
774}
775
776impl<T> Deref for Ptr<'_, T> {
777 type Target = T;
778
779 fn deref(&self) -> &T {
780 self.0
781 }
782}
783
784impl<T> Eq for Ptr<'_, T> {}
785
786impl<T> Hash for Ptr<'_, T> {
787 fn hash<H: hash::Hasher>(&self, st: &mut H) {
788 let ptr = (self.0) as *const T;
789 ptr.hash(st)
790 }
791}
792
793impl<T: fmt::Debug> fmt::Debug for Ptr<'_, T> {
794 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
795 self.0.fmt(f)
796 }
797}
798
799pub struct NodeIdentifiers<'a, N, E: 'a, Ty>
800where
801 N: 'a + NodeTrait,
802{
803 iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
804 ty: PhantomData<Ty>,
805 edge_ty: PhantomData<E>,
806}
807
808impl<'a, N, E, Ty> Iterator for NodeIdentifiers<'a, N, E, Ty>
809where
810 N: 'a + NodeTrait,
811 E: 'a,
812 Ty: EdgeType,
813{
814 type Item = N;
815
816 fn next(&mut self) -> Option<Self::Item> {
817 self.iter.next().map(|(&n, _)| n)
818 }
819}
820
821pub struct NodeReferences<'a, N, E: 'a, Ty>
822where
823 N: 'a + NodeTrait,
824{
825 iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
826 ty: PhantomData<Ty>,
827 edge_ty: PhantomData<E>,
828}
829
830impl<'a, N, E, Ty> Iterator for NodeReferences<'a, N, E, Ty>
831where
832 N: 'a + NodeTrait,
833 E: 'a,
834 Ty: EdgeType,
835{
836 type Item = (N, &'a N);
837
838 fn next(&mut self) -> Option<Self::Item> {
839 self.iter.next().map(|(n, _)| (*n, n))
840 }
841}
842
843impl<N, E, Ty> NodeCount for FastGraphMap<N, E, Ty>
844where
845 N: Copy + PartialEq,
846{
847 fn node_count(&self) -> usize {
848 self.nodes.len()
849 }
850}
851
852impl<N, E, Ty> GraphBase for FastGraphMap<N, E, Ty>
853where
854 N: Copy + PartialEq,
855{
856 type EdgeId = (N, N);
857 type NodeId = N;
858}
859
860impl<N, E, Ty> Visitable for FastGraphMap<N, E, Ty>
861where
862 N: Copy + Ord + Hash,
863 Ty: EdgeType,
864{
865 type Map = FxHashSet<N>;
866
867 fn visit_map(&self) -> FxHashSet<N> {
868 FxHashSet::with_capacity_and_hasher(self.node_count(), Default::default())
869 }
870
871 fn reset_map(&self, map: &mut Self::Map) {
872 map.clear();
873 }
874}
875
876impl<'a, N: 'a, E, Ty> IntoNeighbors for &'a FastGraphMap<N, E, Ty>
877where
878 N: Copy + Ord + Hash,
879 Ty: EdgeType,
880{
881 type Neighbors = Neighbors<'a, N, Ty>;
882
883 fn neighbors(self, n: Self::NodeId) -> Self::Neighbors {
884 self.neighbors(n)
885 }
886}
887
888impl<'a, N: 'a, E, Ty> IntoNeighborsDirected for &'a FastGraphMap<N, E, Ty>
889where
890 N: Copy + Ord + Hash,
891 Ty: EdgeType,
892{
893 type NeighborsDirected = NeighborsDirected<'a, N, Ty>;
894
895 fn neighbors_directed(self, n: N, dir: Direction) -> Self::NeighborsDirected {
896 self.neighbors_directed(n, dir)
897 }
898}
899
900impl<'a, N, E: 'a, Ty> IntoNodeIdentifiers for &'a FastGraphMap<N, E, Ty>
901where
902 N: NodeTrait,
903 Ty: EdgeType,
904{
905 type NodeIdentifiers = NodeIdentifiers<'a, N, E, Ty>;
906
907 fn node_identifiers(self) -> Self::NodeIdentifiers {
908 NodeIdentifiers {
909 iter: self.nodes.iter(),
910 ty: self.ty,
911 edge_ty: PhantomData,
912 }
913 }
914}
915
916impl<N, E, Ty> NodeIndexable for FastGraphMap<N, E, Ty>
917where
918 N: NodeTrait,
919 Ty: EdgeType,
920{
921 fn node_bound(&self) -> usize {
922 self.node_count()
923 }
924
925 fn to_index(&self, ix: Self::NodeId) -> usize {
926 let (i, _, _) = self.nodes.get_full(&ix).unwrap();
927 i
928 }
929
930 fn from_index(&self, ix: usize) -> Self::NodeId {
931 assert!(
932 ix < self.nodes.len(),
933 "The requested index {} is out-of-bounds.",
934 ix
935 );
936 let (&key, _) = self.nodes.get_index(ix).unwrap();
937 key
938 }
939}