ch_router/ch/
storage.rs

1use std::{fs::File, io, path::Path};
2
3use super::{unfolding::AllEdges, ContractionHierarchy, Edge, ShortcutVia};
4
5impl ContractionHierarchy {
6    pub fn save(&self, path: impl AsRef<Path>) -> Result<(), io::Error> {
7        self.write(&mut io::BufWriter::new(File::create(path)?))
8    }
9
10    pub fn load(path: impl AsRef<Path>) -> Result<Self, io::Error> {
11        Self::read(&mut io::BufReader::new(File::open(path)?))
12    }
13
14    pub fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
15        writer.write_all(&(self.forward_edges.len() as u32).to_le_bytes())?;
16
17        let mut write_edges = |edges: &[Vec<Edge>]| -> io::Result<()> {
18            for edges in edges {
19                writer.write_all(&(edges.len() as u32).to_le_bytes())?;
20                for edge in edges {
21                    writer.write_all(&edge.to.to_le_bytes())?;
22                    writer.write_all(&edge.weight.to_le_bytes())?;
23                    edge.shortcut_via.write(writer)?;
24                }
25            }
26            Ok(())
27        };
28
29        write_edges(&self.forward_edges)?;
30        write_edges(&self.backward_edges)?;
31
32        self.all_edges.write(writer)?;
33
34        Ok(())
35    }
36
37    pub fn read(reader: &mut impl io::Read) -> io::Result<Self> {
38        let mut bytes = [0u8; 4];
39
40        reader.read_exact(&mut bytes)?;
41        let nodes_len = u32::from_le_bytes(bytes);
42
43        let mut read_edges = || -> io::Result<_> {
44            let mut edges_for_node = Vec::with_capacity(nodes_len as usize);
45
46            for _ in 0..nodes_len {
47                reader.read_exact(&mut bytes)?;
48                let edges_len = u32::from_le_bytes(bytes);
49
50                let mut edges = Vec::with_capacity(edges_len as usize);
51
52                for _ in 0..edges_len {
53                    reader.read_exact(&mut bytes)?;
54                    let to = u32::from_le_bytes(bytes);
55
56                    reader.read_exact(&mut bytes)?;
57                    let weight = f32::from_le_bytes(bytes);
58
59                    let shortcut_via = ShortcutVia::read(&mut bytes, reader)?;
60
61                    edges.push(Edge {
62                        to,
63                        weight,
64                        shortcut_via,
65                    });
66                }
67
68                edges_for_node.push(edges);
69            }
70
71            Ok(edges_for_node)
72        };
73
74        let forward_edges = read_edges()?;
75        let backward_edges = read_edges()?;
76
77        let all_edges = AllEdges::read(&mut bytes, reader)?;
78
79        Ok(Self {
80            forward_edges,
81            backward_edges,
82            all_edges,
83        })
84    }
85}