pub(super) struct CsrGraph {
pub(super) offsets: Vec<u32>,
pub(super) neighbors: Vec<u32>,
pub(super) vertex_weights: Vec<u32>,
pub(super) edge_weights: Vec<u32>,
}
impl CsrGraph {
pub(super) fn num_vertices(&self) -> usize {
self.offsets.len() - 1
}
pub(super) fn pass_units(&self) -> u64 {
(self.offsets.len() as u64).saturating_add(self.neighbors.len() as u64)
}
pub(super) fn neighbors(&self, v: usize) -> &[u32] {
let start = self.offsets[v] as usize;
let end = self.offsets[v + 1] as usize;
&self.neighbors[start..end]
}
}
pub(super) fn build_csr(n: usize, edges: &[(u32, u32)]) -> CsrGraph {
let mut adj_list: Vec<Vec<u32>> = vec![Vec::new(); n];
for &(u, v) in edges {
let (u, v) = (u as usize, v as usize);
assert!(u < n && v < n, "partition edge endpoint outside 0..{n}");
if u != v {
adj_list[u].push(v as u32);
adj_list[v].push(u as u32);
}
}
for list in &mut adj_list {
list.sort_unstable();
list.dedup();
}
let mut offsets = Vec::with_capacity(n + 1);
let mut neighbors = Vec::new();
offsets.push(0u32);
for list in &adj_list {
neighbors.extend_from_slice(list);
offsets.push(neighbors.len() as u32);
}
let edge_weights = vec![1u32; neighbors.len()];
let vertex_weights = vec![1u32; n];
CsrGraph {
offsets,
neighbors,
vertex_weights,
edge_weights,
}
}