1use std::cmp::max;
8use std::ops::{Index, IndexMut};
9
10#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
12#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
13pub struct NodeIndex(u32);
14
15impl NodeIndex {
16 #[inline]
17 pub fn new(x: u32) -> Self {
18 NodeIndex(x)
19 }
20
21 #[inline]
22 pub fn index(self) -> usize {
23 self.0 as usize
24 }
25
26 #[inline]
27 pub fn end() -> Self {
28 NodeIndex(crate::INVALID_U32)
29 }
30
31 fn _into_edge(self) -> EdgeIndex {
32 EdgeIndex(self.0)
33 }
34}
35
36impl From<u32> for NodeIndex {
37 fn from(ix: u32) -> Self {
38 NodeIndex(ix)
39 }
40}
41
42#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
44#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
45pub struct EdgeIndex(u32);
46
47impl EdgeIndex {
48 #[inline]
49 pub fn new(x: u32) -> Self {
50 EdgeIndex(x)
51 }
52
53 #[inline]
54 pub fn index(self) -> usize {
55 self.0 as usize
56 }
57
58 #[inline]
61 pub fn end() -> Self {
62 EdgeIndex(crate::INVALID_U32)
63 }
64
65 fn _into_node(self) -> NodeIndex {
66 NodeIndex(self.0)
67 }
68}
69
70impl From<u32> for EdgeIndex {
71 fn from(ix: u32) -> Self {
72 EdgeIndex(ix)
73 }
74}
75
76#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
77#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
78pub enum Direction {
79 Outgoing = 0,
80 Incoming = 1,
81}
82
83impl Direction {
84 fn opposite(self) -> Direction {
85 match self {
86 Direction::Outgoing => Direction::Incoming,
87 Direction::Incoming => Direction::Outgoing,
88 }
89 }
90}
91
92const DIRECTIONS: [Direction; 2] = [Direction::Outgoing, Direction::Incoming];
93
94#[derive(Debug, Copy, Clone)]
96#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
97pub struct Node<N> {
98 pub weight: N,
100 next: [EdgeIndex; 2],
102}
103
104#[derive(Debug, Copy, Clone)]
106#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
107pub struct Edge<E> {
108 pub weight: E,
110 next: [EdgeIndex; 2],
112 node: [NodeIndex; 2],
114}
115
116impl<E> Edge<E> {
117 pub fn source(&self) -> NodeIndex {
119 self.node[0]
120 }
121
122 pub fn target(&self) -> NodeIndex {
124 self.node[1]
125 }
126}
127
128#[derive(Clone, Debug, Default)]
129#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
130pub struct Graph<N, E> {
131 pub(crate) nodes: Vec<Node<N>>,
132 pub(crate) edges: Vec<Edge<E>>,
133}
134
135enum Pair<T> {
136 Both(T, T),
137 One(T),
138 None,
139}
140
141fn index_twice<T>(arr: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
143 if max(a, b) >= arr.len() {
144 Pair::None
145 } else if a == b {
146 Pair::One(&mut arr[max(a, b)])
147 } else {
148 unsafe {
150 let ar = &mut *(arr.get_unchecked_mut(a) as *mut _);
151 let br = &mut *(arr.get_unchecked_mut(b) as *mut _);
152 Pair::Both(ar, br)
153 }
154 }
155}
156
157impl<N, E> Graph<N, E> {
158 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
160 Graph {
161 nodes: Vec::with_capacity(nodes),
162 edges: Vec::with_capacity(edges),
163 }
164 }
165
166 pub fn add_node(&mut self, weight: N) -> NodeIndex {
175 let node = Node {
176 weight,
177 next: [EdgeIndex::end(), EdgeIndex::end()],
178 };
179 assert!(self.nodes.len() != crate::INVALID_USIZE);
180 let node_idx = NodeIndex::new(self.nodes.len() as u32);
181 self.nodes.push(node);
182 node_idx
183 }
184
185 pub fn node_weight(&self, a: NodeIndex) -> Option<&N> {
189 self.nodes.get(a.index()).map(|n| &n.weight)
190 }
191
192 pub fn edge_weight(&self, a: EdgeIndex) -> Option<&E> {
196 self.edges.get(a.index()).map(|e| &e.weight)
197 }
198
199 pub fn edge_weight_mut(&mut self, a: EdgeIndex) -> Option<&mut E> {
203 self.edges.get_mut(a.index()).map(|e| &mut e.weight)
204 }
205
206 pub fn add_edge(&mut self, a: NodeIndex, b: NodeIndex, weight: E) -> EdgeIndex {
220 assert!(self.edges.len() != crate::INVALID_USIZE);
221 let edge_idx = EdgeIndex::new(self.edges.len() as u32);
222 let mut edge = Edge {
223 weight,
224 node: [a, b],
225 next: [EdgeIndex::end(); 2],
226 };
227 match index_twice(&mut self.nodes, a.index(), b.index()) {
228 Pair::None => panic!("Graph::add_edge: node indices out of bounds"),
229 Pair::One(an) => {
230 edge.next = an.next;
231 an.next[0] = edge_idx;
232 an.next[1] = edge_idx;
233 }
234 Pair::Both(an, bn) => {
235 edge.next = [an.next[0], bn.next[1]];
237 an.next[0] = edge_idx;
238 bn.next[1] = edge_idx;
239 }
240 }
241 self.edges.push(edge);
242 edge_idx
243 }
244
245 pub fn edge_endpoints(&self, e: EdgeIndex) -> Option<(NodeIndex, NodeIndex)> {
247 self.edges
248 .get(e.index())
249 .map(|ed| (ed.source(), ed.target()))
250 }
251
252 pub fn remove_node(&mut self, a: NodeIndex) -> Option<N> {
265 self.nodes.get(a.index())?;
266 for d in &DIRECTIONS {
267 let k = *d as usize;
268
269 loop {
271 let next = self.nodes[a.index()].next[k];
272 if next == EdgeIndex::end() {
273 break;
274 }
275 let ret = self.remove_edge(next);
276 debug_assert!(ret.is_some());
277 let _ = ret;
278 }
279 }
280
281 let node = self.nodes.swap_remove(a.index());
285
286 let swap_edges = match self.nodes.get(a.index()) {
289 None => return Some(node.weight),
290 Some(ed) => ed.next,
291 };
292
293 let old_index = NodeIndex::new(self.nodes.len() as u32);
295 let new_index = a;
296
297 for &d in &DIRECTIONS {
299 let k = d as usize;
300 let mut edges = edges_walker_mut(&mut self.edges, swap_edges[k], d);
301 while let Some(curedge) = edges.next_edge() {
302 debug_assert!(curedge.node[k] == old_index);
303 curedge.node[k] = new_index;
304 }
305 }
306 Some(node.weight)
307 }
308
309 fn change_edge_links(
312 &mut self,
313 edge_node: [NodeIndex; 2],
314 e: EdgeIndex,
315 edge_next: [EdgeIndex; 2],
316 ) {
317 for &d in &DIRECTIONS {
318 let k = d as usize;
319 let node = match self.nodes.get_mut(edge_node[k].index()) {
320 Some(r) => r,
321 None => {
322 debug_assert!(
323 false,
324 "Edge's endpoint dir={:?} index={:?} not found",
325 d, edge_node[k]
326 );
327 return;
328 }
329 };
330 let fst = node.next[k];
331 if fst == e {
332 node.next[k] = edge_next[k];
334 } else {
335 let mut edges = edges_walker_mut(&mut self.edges, fst, d);
336 while let Some(curedge) = edges.next_edge() {
337 if curedge.next[k] == e {
338 curedge.next[k] = edge_next[k];
339 break; }
341 }
342 }
343 }
344 }
345
346 pub fn remove_edge(&mut self, e: EdgeIndex) -> Option<E> {
354 let (edge_node, edge_next) = match self.edges.get(e.index()) {
358 None => return None,
359 Some(x) => (x.node, x.next),
360 };
361 self.change_edge_links(edge_node, e, edge_next);
364 self.remove_edge_adjust_indices(e)
365 }
366
367 fn remove_edge_adjust_indices(&mut self, e: EdgeIndex) -> Option<E> {
368 let edge = self.edges.swap_remove(e.index());
372 let swap = match self.edges.get(e.index()) {
373 None => return Some(edge.weight),
375 Some(ed) => ed.node,
376 };
377 let swapped_e = EdgeIndex::new(self.edges.len() as u32);
378
379 self.change_edge_links(swap, swapped_e, [e, e]);
382 Some(edge.weight)
383 }
384
385 pub fn edges(&self, a: NodeIndex) -> Edges<'_, E> {
393 self.edges_directed(a, Direction::Outgoing)
394 }
395
396 pub fn edges_directed(&self, a: NodeIndex, dir: Direction) -> Edges<'_, E> {
408 Edges {
409 skip_start: a,
410 edges: &self.edges,
411 direction: dir,
412 next: match self.nodes.get(a.index()) {
413 None => [EdgeIndex::end(), EdgeIndex::end()],
414 Some(n) => n.next,
415 },
416 }
417 }
418
419 pub fn find_edge(&self, a: NodeIndex, b: NodeIndex) -> Option<EdgeIndex> {
440 self.find_edge_undirected(a, b).map(|(ix, _)| ix)
441 }
442
443 pub fn find_edge_undirected(
451 &self,
452 a: NodeIndex,
453 b: NodeIndex,
454 ) -> Option<(EdgeIndex, Direction)> {
455 match self.nodes.get(a.index()) {
456 None => None,
457 Some(node) => self.find_edge_undirected_from_node(node, b),
458 }
459 }
460
461 fn find_edge_undirected_from_node(
462 &self,
463 node: &Node<N>,
464 b: NodeIndex,
465 ) -> Option<(EdgeIndex, Direction)> {
466 for &d in &DIRECTIONS {
467 let k = d as usize;
468 let mut edix = node.next[k];
469 while let Some(edge) = self.edges.get(edix.index()) {
470 if edge.node[1 - k] == b {
471 return Some((edix, d));
472 }
473 edix = edge.next[k];
474 }
475 }
476 None
477 }
478
479 pub fn raw_nodes(&self) -> &[Node<N>] {
481 &self.nodes
482 }
483
484 pub fn raw_edges(&self) -> &[Edge<E>] {
486 &self.edges
487 }
488
489 pub fn first_edge(&self, a: NodeIndex, dir: Direction) -> Option<EdgeIndex> {
491 match self.nodes.get(a.index()) {
492 None => None,
493 Some(node) => {
494 let edix = node.next[dir as usize];
495 if edix == EdgeIndex::end() {
496 None
497 } else {
498 Some(edix)
499 }
500 }
501 }
502 }
503
504 pub fn next_edge(&self, e: EdgeIndex, dir: Direction) -> Option<EdgeIndex> {
506 match self.edges.get(e.index()) {
507 None => None,
508 Some(node) => {
509 let edix = node.next[dir as usize];
510 if edix == EdgeIndex::end() {
511 None
512 } else {
513 Some(edix)
514 }
515 }
516 }
517 }
518}
519
520struct EdgesWalkerMut<'a, E: 'a> {
521 edges: &'a mut [Edge<E>],
522 next: EdgeIndex,
523 dir: Direction,
524}
525
526fn edges_walker_mut<E>(
527 edges: &mut [Edge<E>],
528 next: EdgeIndex,
529 dir: Direction,
530) -> EdgesWalkerMut<'_, E> {
531 EdgesWalkerMut { edges, next, dir }
532}
533
534impl<E> EdgesWalkerMut<'_, E> {
535 fn next_edge(&mut self) -> Option<&mut Edge<E>> {
536 self.next().map(|t| t.1)
537 }
538
539 fn next(&mut self) -> Option<(EdgeIndex, &mut Edge<E>)> {
540 let this_index = self.next;
541 let k = self.dir as usize;
542 match self.edges.get_mut(self.next.index()) {
543 None => None,
544 Some(edge) => {
545 self.next = edge.next[k];
546 Some((this_index, edge))
547 }
548 }
549 }
550}
551
552pub struct Edges<'a, E: 'a> {
554 skip_start: NodeIndex,
556 edges: &'a [Edge<E>],
557
558 next: [EdgeIndex; 2],
560
561 direction: Direction,
564}
565
566impl<'a, E> Iterator for Edges<'a, E> {
567 type Item = EdgeReference<'a, E>;
568
569 fn next(&mut self) -> Option<Self::Item> {
570 let (iterate_over, _reverse) = (None, Some(self.direction.opposite()));
580
581 if iterate_over.unwrap_or(Direction::Outgoing) == Direction::Outgoing {
582 let i = self.next[0].index();
583 if let Some(Edge {
584 node: _node,
585 weight,
586 next,
587 }) = self.edges.get(i)
588 {
589 self.next[0] = next[0];
590 return Some(EdgeReference {
591 index: EdgeIndex(i as u32),
592 weight,
598 });
599 }
600 }
601
602 if iterate_over.unwrap_or(Direction::Incoming) == Direction::Incoming {
603 while let Some(Edge { node, weight, next }) = self.edges.get(self.next[1].index()) {
604 let edge_index = self.next[1];
605 self.next[1] = next[1];
606 if iterate_over.is_none() && node[0] == self.skip_start {
609 continue;
610 }
611
612 return Some(EdgeReference {
613 index: edge_index,
614 weight,
620 });
621 }
622 }
623
624 None
625 }
626}
627
628impl<E> Clone for Edges<'_, E> {
634 fn clone(&self) -> Self {
635 Edges {
636 skip_start: self.skip_start,
637 edges: self.edges,
638 next: self.next,
639 direction: self.direction,
640 }
641 }
642}
643
644impl<N, E> Index<NodeIndex> for Graph<N, E> {
648 type Output = N;
649 fn index(&self, index: NodeIndex) -> &N {
650 &self.nodes[index.index()].weight
651 }
652}
653
654impl<N, E> IndexMut<NodeIndex> for Graph<N, E> {
658 fn index_mut(&mut self, index: NodeIndex) -> &mut N {
659 &mut self.nodes[index.index()].weight
660 }
661}
662
663impl<N, E> Index<EdgeIndex> for Graph<N, E> {
667 type Output = E;
668 fn index(&self, index: EdgeIndex) -> &E {
669 &self.edges[index.index()].weight
670 }
671}
672
673impl<N, E> IndexMut<EdgeIndex> for Graph<N, E> {
677 fn index_mut(&mut self, index: EdgeIndex) -> &mut E {
678 &mut self.edges[index.index()].weight
679 }
680}
681
682#[derive(Debug)]
684pub struct EdgeReference<'a, E: 'a> {
685 index: EdgeIndex,
686 weight: &'a E,
688}
689
690impl<'a, E: 'a> EdgeReference<'a, E> {
691 #[inline]
692 pub fn id(&self) -> EdgeIndex {
693 self.index
694 }
695
696 #[inline]
697 pub fn weight(&self) -> &'a E {
698 self.weight
699 }
700}
701
702impl<E> Clone for EdgeReference<'_, E> {
703 fn clone(&self) -> Self {
704 *self
705 }
706}
707
708impl<E> Copy for EdgeReference<'_, E> {}
709
710impl<E> PartialEq for EdgeReference<'_, E>
711where
712 E: PartialEq,
713{
714 fn eq(&self, rhs: &Self) -> bool {
715 self.index == rhs.index && self.weight == rhs.weight
716 }
717}