use std::io::{BufRead, BufReader, BufWriter, LineWriter, Read, Write};
use itertools::Itertools;
use super::graph::Graph;
pub fn export_adjacency_list<W>(buffer: W, graph: &Graph) -> std::io::Result<()>
where
W: Write,
{
let mut writer = LineWriter::new(buffer);
for label in 0..graph.len() {
let mut nbr_iter = graph.get_neighbours(label).iter().copied();
if let Some(first_nbr) = nbr_iter.next() {
write!(writer, "{first_nbr}")?;
}
for nbr in nbr_iter {
write!(writer, ",{nbr}")?;
}
writeln!(writer)?;
}
Ok(())
}
pub fn export_adjacency_list_noduplicates<W>(buffer: W, graph: &Graph) -> std::io::Result<()>
where
W: Write,
{
let mut writer = LineWriter::new(buffer);
for label in 0..graph.len() {
let mut nbr_iter = graph.get_neighbours(label).iter().copied().unique();
if let Some(first_nbr) = nbr_iter.next() {
write!(writer, "{first_nbr}")?;
}
for nbr in nbr_iter {
write!(writer, ",{nbr}")?;
}
writeln!(writer)?;
}
Ok(())
}
pub fn export_compact_adjacency_list<W>(buffer: W, graph: &Graph) -> std::io::Result<()>
where
W: Write,
{
let mut writer = BufWriter::new(buffer);
write!(writer, "{}", 0)?;
for index in graph.get_raw_node_index() {
write!(writer, ",{}", index)?;
}
writeln!(writer)?;
let mut neighbours_iter = graph.get_raw_neighbours().iter();
if let Some(first_nbr) = neighbours_iter.next() {
write!(writer, "{}", first_nbr)?;
}
for nbr in neighbours_iter {
write!(writer, ",{}", nbr)?;
}
writeln!(writer)?;
Ok(())
}
pub fn import_compact_adjacency_list<R>(buffer: R) -> std::io::Result<Graph>
where
R: Read,
{
let reader = BufReader::new(buffer);
let mut lines = reader.lines();
let node_index_line = lines.next().ok_or(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Missing node_index line",
))??;
let node_index = node_index_line
.split(',')
.map(|index| {
index
.trim()
.parse()
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
})
.collect::<Result<_, _>>()?;
let neighbours_line = lines.next().ok_or(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Missing neighbours line",
))??;
let neighbours = neighbours_line
.split(',')
.map(|index| {
index
.trim()
.parse()
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
})
.collect::<Result<_, _>>()?;
let graph = Graph::from_raw_parts(node_index, neighbours).ok_or(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"The compressed graph format was not correct",
))?;
Ok(graph)
}
pub fn import_adjacency_list<R>(buffer: R) -> std::io::Result<Graph>
where
R: Read,
{
let reader = BufReader::new(buffer);
let mut nodes = Vec::new();
for line in reader.lines() {
let line = line?;
let mut nbrs = Vec::with_capacity(10);
for nbr in line.split(',').map(|nbr_str| nbr_str.trim().parse()) {
nbrs.push(nbr.expect("Should be able to parse any entry in adjacency list."));
}
nodes.push(nbrs);
}
Ok(Graph::from_neighbour_slice(nodes.iter()))
}