#[derive(Clone, Debug, Default)]
pub(crate) struct CsrU32 {
data: Vec<u32>,
offsets: Vec<u32>,
}
impl CsrU32 {
fn from_rows_sized<R, I>(rows: R, data_cap: usize, offsets_cap: usize) -> Self
where
R: IntoIterator<Item = I>,
I: IntoIterator<Item = usize>,
{
let mut data = Vec::with_capacity(data_cap);
let mut offsets = Vec::with_capacity(offsets_cap);
offsets.push(0u32);
for row in rows {
for v in row {
data.push(v as u32);
}
offsets.push(data.len() as u32);
}
Self { data, offsets }
}
#[inline]
pub(crate) fn get(&self, i: usize) -> Option<&[u32]> {
let start = *self.offsets.get(i)? as usize;
let end = *self.offsets.get(i + 1)? as usize;
Some(&self.data[start..end])
}
}
impl From<Vec<Vec<usize>>> for CsrU32 {
fn from(rows: Vec<Vec<usize>>) -> Self {
let data_cap: usize = rows.iter().map(Vec::len).sum();
let offsets_cap = rows.len().saturating_add(1);
Self::from_rows_sized(rows, data_cap, offsets_cap)
}
}
impl std::ops::Index<usize> for CsrU32 {
type Output = [u32];
#[inline]
fn index(&self, i: usize) -> &[u32] {
let start = self.offsets[i] as usize;
let end = self.offsets[i + 1] as usize;
&self.data[start..end]
}
}