1use std::convert::TryFrom;
21
22use serde::Deserialize;
23use serde::Serialize;
24
25use crate::fast_graph::FastGraphEdge;
26use crate::FastGraph;
27
28#[derive(Serialize, Deserialize, Debug, Clone)]
32pub struct FastGraph32 {
33 num_nodes: u32,
34 pub ranks: Vec<u32>,
35 pub edges_fwd: Vec<FastGraphEdge32>,
36 pub first_edge_ids_fwd: Vec<u32>,
37
38 pub edges_bwd: Vec<FastGraphEdge32>,
39 pub first_edge_ids_bwd: Vec<u32>,
40}
41
42impl FastGraph32 {
43 pub fn new(fast_graph: &FastGraph) -> Self {
47 FastGraph32 {
48 num_nodes: usize_to_u32(fast_graph.get_num_nodes()),
49 ranks: usize_to_u32_vec(&fast_graph.ranks),
50 edges_fwd: usize_to_u32_edges(&fast_graph.edges_fwd),
51 first_edge_ids_fwd: usize_to_u32_vec(&fast_graph.first_edge_ids_fwd),
52 edges_bwd: usize_to_u32_edges(&fast_graph.edges_bwd),
53 first_edge_ids_bwd: usize_to_u32_vec(&fast_graph.first_edge_ids_bwd),
54 }
55 }
56
57 pub fn convert_to_usize(self) -> FastGraph {
60 let mut g = FastGraph::new(self.num_nodes as usize);
61 g.ranks = u32_to_usize_vec(&self.ranks);
62 g.edges_fwd = u32_to_usize_edges(&self.edges_fwd);
63 g.first_edge_ids_fwd = u32_to_usize_vec(&self.first_edge_ids_fwd);
64 g.edges_bwd = u32_to_usize_edges(&self.edges_bwd);
65 g.first_edge_ids_bwd = u32_to_usize_vec(&self.first_edge_ids_bwd);
66 g
67 }
68}
69
70#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
72pub struct FastGraphEdge32 {
73 pub base_node: u32,
74 pub adj_node: u32,
75 pub weight: u32,
76 pub replaced_in_edge: u32,
77 pub replaced_out_edge: u32,
78}
79
80fn usize_to_u32(int: usize) -> u32 {
81 if int == std::usize::MAX {
82 usize_to_u32(std::u32::MAX as usize)
83 } else if let Ok(x) = u32::try_from(int) {
84 x
85 } else {
86 panic!("Could not convert {} to a 32-bit integer", int);
87 }
88}
89
90fn usize_to_u32_vec(vec: &[usize]) -> Vec<u32> {
91 vec.iter().map(|i| usize_to_u32(*i)).collect()
92}
93
94fn usize_to_u32_edges(vec: &[FastGraphEdge]) -> Vec<FastGraphEdge32> {
95 vec.iter().map(|e| usize_to_u32_edge(e)).collect()
96}
97
98fn usize_to_u32_edge(edge: &FastGraphEdge) -> FastGraphEdge32 {
99 FastGraphEdge32 {
100 base_node: usize_to_u32(edge.base_node),
101 adj_node: usize_to_u32(edge.adj_node),
102 weight: usize_to_u32(edge.weight),
103 replaced_in_edge: usize_to_u32(edge.replaced_in_edge),
104 replaced_out_edge: usize_to_u32(edge.replaced_out_edge),
105 }
106}
107
108fn u32_to_usize(int: u32) -> usize {
109 if int == std::u32::MAX {
110 std::usize::MAX
111 } else {
112 int as usize
113 }
114}
115
116fn u32_to_usize_vec(vec: &[u32]) -> Vec<usize> {
117 vec.iter().map(|i| u32_to_usize(*i)).collect()
118}
119
120fn u32_to_usize_edges(vec: &[FastGraphEdge32]) -> Vec<FastGraphEdge> {
121 vec.iter().map(|e| u32_to_usize_edge(e)).collect()
122}
123
124fn u32_to_usize_edge(edge: &FastGraphEdge32) -> FastGraphEdge {
125 FastGraphEdge {
126 base_node: u32_to_usize(edge.base_node),
127 adj_node: u32_to_usize(edge.adj_node),
128 weight: u32_to_usize(edge.weight),
129 replaced_in_edge: u32_to_usize(edge.replaced_in_edge),
130 replaced_out_edge: u32_to_usize(edge.replaced_out_edge),
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use crate::fast_graph::FastGraph;
137 use crate::fast_graph::FastGraphEdge;
138
139 use super::*;
140
141 #[test]
142 fn create() {
143 let num_nodes = 5;
144 let ranks = vec![286, 45, 480_001, std::usize::MAX, 4468];
145 let edges_fwd = vec![
146 FastGraphEdge::new(std::usize::MAX, 598, 48, std::usize::MAX, std::usize::MAX),
147 FastGraphEdge::new(
148 std::usize::MAX,
149 std::usize::MAX,
150 std::usize::MAX,
151 4,
152 std::usize::MAX,
153 ),
154 ];
155 let edges_bwd = vec![FastGraphEdge::new(0, 1, 3, 4, std::usize::MAX)];
156 let first_edge_ids_fwd = vec![1, std::usize::MAX, std::usize::MAX];
157 let first_edge_ids_bwd = vec![1, std::usize::MAX, 5, std::usize::MAX, 9, 10];
158
159 let mut g = FastGraph::new(num_nodes);
160 g.ranks = ranks;
161 g.edges_fwd = edges_fwd;
162 g.first_edge_ids_fwd = first_edge_ids_fwd;
163 g.edges_bwd = edges_bwd;
164 g.first_edge_ids_bwd = first_edge_ids_bwd;
165
166 let g32 = FastGraph32::new(&g);
167 assert_eq!(g32.num_nodes, 5);
168
169 assert_eq!(g32.ranks.len(), 5);
170 assert_eq!(g32.ranks[0], 286);
171 assert_eq!(g32.ranks[2], 480_001);
172 assert_eq!(g32.ranks[3], std::u32::MAX);
173
174 assert_eq!(g32.edges_fwd.len(), 2);
175 assert_eq!(g32.edges_fwd[0].base_node, std::u32::MAX);
176 assert_eq!(g32.edges_fwd[0].adj_node, 598);
177 assert_eq!(g32.edges_fwd[0].weight, 48);
178 assert_eq!(g32.edges_fwd[0].replaced_in_edge, std::u32::MAX);
179 assert_eq!(g32.edges_fwd[0].replaced_out_edge, std::u32::MAX);
180
181 assert_eq!(g32.edges_fwd[1].base_node, std::u32::MAX);
182 assert_eq!(g32.edges_fwd[1].adj_node, std::u32::MAX);
183 assert_eq!(g32.edges_fwd[1].weight, std::u32::MAX);
184 assert_eq!(g32.edges_fwd[1].replaced_in_edge, 4);
185 assert_eq!(g32.edges_fwd[1].replaced_out_edge, std::u32::MAX);
186
187 assert_eq!(g32.edges_bwd.len(), 1);
188 assert_eq!(g32.edges_bwd[0].weight, 3);
189 assert_eq!(g32.edges_bwd[0].replaced_out_edge, std::u32::MAX);
190
191 assert_eq!(g32.first_edge_ids_fwd.len(), 3);
192 assert_eq!(g32.first_edge_ids_fwd[1], std::u32::MAX);
193 assert_eq!(g32.first_edge_ids_bwd.len(), 6);
194 assert_eq!(g32.first_edge_ids_bwd[3], std::u32::MAX);
195 assert_eq!(g32.first_edge_ids_bwd[4], 9);
196
197 let g_from32 = g32.convert_to_usize();
199 assert_eq!(g_from32.get_num_nodes(), 5);
200 assert_eq!(
201 g_from32.ranks,
202 vec![286, 45, 480_001, std::usize::MAX, 4468]
203 );
204 assert_eq!(g_from32.first_edge_ids_fwd[2], std::usize::MAX);
205 assert_eq!(g_from32.first_edge_ids_bwd[0], 1);
206 assert_eq!(g_from32.first_edge_ids_bwd[1], std::usize::MAX);
207 assert_eq!(g_from32.edges_fwd[0].base_node, std::usize::MAX);
208 assert_eq!(g_from32.edges_fwd[0].adj_node, 598);
209 assert_eq!(g_from32.edges_fwd[0].weight, 48);
210 assert_eq!(g_from32.edges_bwd[0].replaced_in_edge, 4);
211 }
212
213 #[test]
214 #[should_panic]
215 fn create_fails_with_too_large_numbers() {
216 let num_nodes = 5;
217 let mut g = FastGraph::new(num_nodes);
218 g.ranks = vec![5_000_000_000];
219 FastGraph32::new(&g);
220 }
221}