use super::FnEncoder;
use crate::compressor::core::data::Stream;
use crate::compressor::core::error::NodeError;
use crate::compressor::core::exec::NodeCx;
use crate::shared::bitpack_kernels;
pub(crate) static BITPACK: FnEncoder = FnEncoder(encode_bitpack);
fn encode_bitpack<'a>(cx: &mut NodeCx<'_, 'a>, inputs: &[Stream<'a>]) -> Result<(), NodeError> {
let input = &inputs[0];
let width = input.width();
if !matches!(width, 1 | 2 | 4 | 8) {
return Err(NodeError::InvalidInput(
"Bitpack expects element width of 1, 2, 4 or 8",
));
}
let nb_elts = input.n_elts();
let nb_bits = bitpack_kernels::nb_bits(cx.simd, input.bytes(), width);
let packed = bitpack_kernels::encode(input.bytes(), width, nb_bits);
let max_nb_elts = packed.len() * 8 / nb_bits as usize;
let first = ((width.trailing_zeros() as u8) << 6) | (nb_bits - 1) as u8;
if max_nb_elts > nb_elts {
cx.send_header(&[first, (max_nb_elts - nb_elts) as u8])?;
} else {
cx.send_header(&[first])?;
}
cx.emit(0, 1, packed)?;
Ok(())
}