1use serde::Deserialize;
21use serde::Serialize;
22
23use crate::constants::Weight;
24use crate::constants::{EdgeId, NodeId, INVALID_EDGE};
25
26#[derive(Serialize, Deserialize, Debug, Clone)]
27pub struct FastGraph {
28 num_nodes: usize,
29 pub(crate) ranks: Vec<usize>,
30 pub(crate) edges_fwd: Vec<FastGraphEdge>,
31 pub(crate) first_edge_ids_fwd: Vec<EdgeId>,
32
33 pub(crate) edges_bwd: Vec<FastGraphEdge>,
34 pub(crate) first_edge_ids_bwd: Vec<EdgeId>,
35}
36
37impl FastGraph {
38 pub fn new(num_nodes: usize) -> Self {
39 FastGraph {
40 ranks: vec![0; num_nodes],
41 num_nodes,
42 edges_fwd: vec![],
43 first_edge_ids_fwd: vec![0; num_nodes + 1],
44 edges_bwd: vec![],
45 first_edge_ids_bwd: vec![0; num_nodes + 1],
46 }
47 }
48
49 pub fn get_node_ordering(&self) -> Vec<NodeId> {
50 let mut ordering = vec![0; self.ranks.len()];
51 for i in 0..self.ranks.len() {
52 ordering[self.ranks[i]] = i;
53 }
54 ordering
55 }
56
57 pub fn get_num_nodes(&self) -> usize {
58 self.num_nodes
59 }
60
61 pub fn get_num_out_edges(&self) -> usize {
62 self.edges_fwd.len()
63 }
64
65 pub fn get_num_in_edges(&self) -> usize {
66 self.edges_bwd.len()
67 }
68
69 pub fn begin_in_edges(&self, node: NodeId) -> usize {
70 self.first_edge_ids_bwd[self.ranks[node]]
71 }
72
73 pub fn end_in_edges(&self, node: NodeId) -> usize {
74 self.first_edge_ids_bwd[self.ranks[node] + 1]
75 }
76
77 pub fn begin_out_edges(&self, node: NodeId) -> usize {
78 self.first_edge_ids_fwd[self.ranks[node]]
79 }
80
81 pub fn end_out_edges(&self, node: NodeId) -> usize {
82 self.first_edge_ids_fwd[self.ranks[node] + 1]
83 }
84}
85
86#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
87pub struct FastGraphEdge {
88 pub base_node: NodeId,
93 pub adj_node: NodeId,
94 pub weight: Weight,
95 pub replaced_in_edge: EdgeId,
96 pub replaced_out_edge: EdgeId,
97}
98
99impl FastGraphEdge {
100 pub fn new(
101 base_node: NodeId,
102 adj_node: NodeId,
103 weight: Weight,
104 replaced_edge1: EdgeId,
105 replaced_edge2: EdgeId,
106 ) -> Self {
107 FastGraphEdge {
108 base_node,
109 adj_node,
110 weight,
111 replaced_in_edge: replaced_edge1,
112 replaced_out_edge: replaced_edge2,
113 }
114 }
115
116 pub fn is_shortcut(&self) -> bool {
117 assert!(
118 (self.replaced_in_edge == INVALID_EDGE && self.replaced_out_edge == INVALID_EDGE)
119 || (self.replaced_in_edge != INVALID_EDGE
120 && self.replaced_out_edge != INVALID_EDGE)
121 );
122 self.replaced_in_edge != INVALID_EDGE
123 }
124}