pub(crate) fn split_columns_into<T: ColumnRow>(
rows: &[T],
columns: &mut [&mut Vec<u32>],
field_names: &[&'static str],
) -> Result<(), String> {
assert_eq!(columns.len(), T::N, "column count mismatch");
assert_eq!(field_names.len(), T::N, "field name count mismatch");
let stable_len = columns.iter().all(|c| c.len() == rows.len());
for (col, name) in columns.iter_mut().zip(field_names.iter()) {
crate::staging_reserve::reserve_vec(col, rows.len(), name)?;
}
if stable_len {
for (index, row) in rows.iter().enumerate() {
row.write_into(index, columns);
}
} else {
for col in columns.iter_mut() {
col.clear();
}
for row in rows {
row.push_into(columns);
}
}
Ok(())
}
pub(crate) trait ColumnRow: Copy {
const N: usize;
fn write_into(&self, index: usize, columns: &mut [&mut Vec<u32>]);
fn push_into(&self, columns: &mut [&mut Vec<u32>]);
}
impl ColumnRow for (u32, u32, u32) {
const N: usize = 3;
fn write_into(&self, index: usize, columns: &mut [&mut Vec<u32>]) {
columns[0][index] = self.0;
columns[1][index] = self.1;
columns[2][index] = self.2;
}
fn push_into(&self, columns: &mut [&mut Vec<u32>]) {
columns[0].push(self.0);
columns[1].push(self.1);
columns[2].push(self.2);
}
}
impl ColumnRow for (u32, u32, u32, u32) {
const N: usize = 4;
fn write_into(&self, index: usize, columns: &mut [&mut Vec<u32>]) {
columns[0][index] = self.0;
columns[1][index] = self.1;
columns[2][index] = self.2;
columns[3][index] = self.3;
}
fn push_into(&self, columns: &mut [&mut Vec<u32>]) {
columns[0].push(self.0);
columns[1].push(self.1);
columns[2].push(self.2);
columns[3].push(self.3);
}
}