use glaredb_error::{Result, not_implemented};
use crate::arrays::array::Array;
use crate::arrays::array::array_buffer::AnyArrayBuffer;
use crate::arrays::array::validity::Validity;
use crate::arrays::batch::Batch;
use crate::arrays::compute::copy::copy_rows_raw;
use crate::arrays::datatype::DataType;
use crate::buffer::buffer_manager::AsRawBufferManager;
use crate::storage::projections::{ProjectedColumn, Projections};
#[derive(Debug)]
pub struct ColumnChunk {
pub relative_offset: usize,
pub buffers: Vec<ColumnBuffer>,
pub capacity: usize,
pub filled: usize,
}
impl ColumnChunk {
pub fn try_new(
manager: &impl AsRawBufferManager,
datatypes: &[DataType],
capacity: usize,
) -> Result<Self> {
let mut buffers = Vec::with_capacity(datatypes.len());
for datatype in datatypes {
let buffer = AnyArrayBuffer::new_for_datatype(manager, datatype, capacity)?;
buffers.push(ColumnBuffer {
validity: Validity::new_all_valid(capacity),
buffer,
});
}
Ok(ColumnChunk {
relative_offset: 0,
buffers,
capacity,
filled: 0,
})
}
pub fn make_all_shared(&mut self) {
for buf in &mut self.buffers {
buf.buffer.make_shared();
}
}
pub fn copy_rows(&mut self, src: &[Array], src_offset: usize, count: usize) -> Result<()> {
debug_assert_eq!(self.buffers.len(), src.len());
debug_assert!(count <= self.capacity - self.filled);
for (src, dest) in src.iter().zip(&mut self.buffers) {
dest.copy_rows_from_array(self.filled, src, src_offset, count)?;
}
self.filled += count;
Ok(())
}
pub fn scan(&self, projections: &Projections, output: &mut Batch) -> Result<usize> {
debug_assert!(
projections
.data_indices()
.iter()
.all(|&idx| idx < self.buffers.len())
);
projections.for_each_column(output, &mut |col_idx, output| match col_idx {
ProjectedColumn::Data(idx) => self.buffers[idx].clone_to_array(output),
ProjectedColumn::Metadata(0) => not_implemented!("materialized row id"),
other => panic!("invalid projection: {other:?}"),
})?;
output.set_num_rows(self.filled)?;
Ok(self.filled)
}
}
#[derive(Debug)]
pub struct ColumnBuffer {
pub validity: Validity,
pub buffer: AnyArrayBuffer,
}
impl ColumnBuffer {
pub fn clone_to_array(&self, array: &mut Array) -> Result<()> {
array.validity = self.validity.clone();
array.data = self.buffer.try_clone_shared()?;
Ok(())
}
fn copy_rows_from_array(
&mut self,
dest_offset: usize,
src: &Array,
src_offset: usize,
count: usize,
) -> Result<()> {
let mapping = (src_offset..(src_offset + count)).zip(dest_offset..(dest_offset + count));
copy_rows_raw(
src.datatype(),
&src.data,
&src.validity,
mapping,
&mut self.buffer,
&mut self.validity,
)
}
}