use crate::query::dispatch;
use crate::query::fold::{partial_geometry, reduction};
use crate::query::types::{OperationPreviewFields, TetError};
pub(crate) struct ScalarChunkWork {
pub bytes: u64,
pub value: reduction::ValueAccum,
pub arg: reduction::ArgIndexAccum,
}
pub(crate) struct PartialChunkValue {
pub bytes: u64,
pub cells: Vec<reduction::ValueAccum>,
pub saw_any: bool,
}
pub(crate) struct PartialChunkArg {
pub bytes: u64,
pub cells: Vec<reduction::ArgIndexAccum>,
pub saw_any: bool,
}
pub(crate) fn sum_chunk_bytes(bytes: impl IntoIterator<Item = u64>) -> Result<u64, TetError> {
dispatch::sum_chunk_read_bytes(bytes)
}
pub(crate) fn merge_scalar_chunks(
parts: &[ScalarChunkWork],
kind: reduction::ReductionKind,
n: usize,
) -> Result<OperationPreviewFields, TetError> {
match kind {
reduction::ReductionKind::ArgMin | reduction::ReductionKind::ArgMax => {
let mut acc = reduction::ArgIndexAccum::default();
for p in parts {
acc.merge_from(&p.arg, kind);
}
if acc.is_empty() {
return Err(TetError::Validation(
"operation requires at least one decoded value from the read plan".into(),
));
}
Ok(acc.finish_scalar(kind, n).into())
}
_ => {
let mut acc = reduction::ValueAccum::default();
for p in parts {
acc.merge_from(&p.value);
}
if acc.is_empty() {
return Err(TetError::Validation(
"operation requires at least one decoded value from the read plan".into(),
));
}
Ok(acc.finish_scalar(kind).into())
}
}
}
pub(crate) fn merge_partial_value_cells(
dst: &mut [reduction::ValueAccum],
src: &[reduction::ValueAccum],
) {
for (d, s) in dst.iter_mut().zip(src) {
d.merge_from(s);
}
}
pub(crate) fn merge_partial_arg_cells(
dst: &mut [reduction::ArgIndexAccum],
src: &[reduction::ArgIndexAccum],
kind: reduction::ReductionKind,
) {
for (d, s) in dst.iter_mut().zip(src) {
d.merge_from(s, kind);
}
}
pub(crate) use partial_geometry::reduced_cell_index;