use super::super::data::{Stream, Type};
use super::super::error::ExecError;
use super::super::exec::{Edge, GraphCx, SelectorCx, conversion_compatible};
use super::super::registry::{GraphFn, GraphId, SelectFn, gid};
#[derive(Debug)]
pub(crate) struct CompressGeneric;
#[derive(Debug)]
pub(crate) struct Compress1;
#[derive(Debug)]
pub(crate) struct SerialCompress;
#[derive(Debug)]
pub(crate) struct StructCompress;
#[derive(Debug)]
pub(crate) struct NumericCompress;
#[derive(Debug)]
pub(crate) struct StringCompress;
#[derive(Debug)]
pub(crate) struct SelectGenericLz;
#[derive(Debug)]
pub(crate) struct SelectNumeric;
#[derive(Debug)]
pub(crate) struct BruteForce;
pub(crate) static COMPRESS_GENERIC: CompressGeneric = CompressGeneric;
pub(crate) static COMPRESS1: Compress1 = Compress1;
pub(crate) static SERIAL_COMPRESS: SerialCompress = SerialCompress;
pub(crate) static STRUCT_COMPRESS: StructCompress = StructCompress;
pub(crate) static NUMERIC_COMPRESS: NumericCompress = NumericCompress;
pub(crate) static STRING_COMPRESS: StringCompress = StringCompress;
pub(crate) static SELECT_GENERIC_LZ: SelectGenericLz = SelectGenericLz;
pub(crate) static SELECT_NUMERIC: SelectNumeric = SelectNumeric;
pub(crate) static BRUTE_FORCE: BruteForce = BruteForce;
const TRANSFORMER_MIN_LEVEL: i32 = 7;
impl GraphFn for CompressGeneric {
fn run(&self, cx: &mut GraphCx<'_, '_, '_>, inputs: &[Edge]) -> Result<(), ExecError> {
for &input in inputs {
cx.set_destination(&[input], gid::COMPRESS1, None)?;
}
Ok(())
}
}
impl SelectFn for Compress1 {
fn select(&self, _: &mut SelectorCx<'_, '_, '_>, input: &Stream<'_>, _: &[GraphId]) -> GraphId {
match input.ty() {
Type::Serial => gid::SERIAL_COMPRESS,
Type::Struct => gid::STRUCT_COMPRESS,
Type::Numeric => gid::NUMERIC_COMPRESS,
Type::String => gid::STRING_COMPRESS,
}
}
}
macro_rules! constant_selector {
($($ty:ty => $graph:expr;)*) => {$(
impl SelectFn for $ty {
fn select(&self, _: &mut SelectorCx<'_, '_, '_>, _: &Stream<'_>, _: &[GraphId]) -> GraphId {
$graph
}
}
)*};
}
constant_selector! {
SerialCompress => gid::ZSTD;
StructCompress => gid::FIELD_LZ;
NumericCompress => gid::SELECT_NUMERIC;
StringCompress => gid::STRING_SEPARATE_COMPRESS;
SelectGenericLz => gid::ZSTD;
}
impl SelectFn for SelectNumeric {
fn select(&self, cx: &mut SelectorCx<'_, '_, '_>, _: &Stream<'_>, _: &[GraphId]) -> GraphId {
if cx.level() < TRANSFORMER_MIN_LEVEL {
gid::STRUCT_COMPRESS
} else {
gid::TRANSFORMER_NUMERIC1
}
}
}
impl SelectFn for BruteForce {
fn select(
&self,
cx: &mut SelectorCx<'_, '_, '_>,
input: &Stream<'_>,
successors: &[GraphId],
) -> GraphId {
let mut best = input.weight();
let mut best_index = None;
for (index, &successor) in successors.iter().enumerate() {
let compatible = cx
.input0_mask(successor)
.is_some_and(|mask| conversion_compatible(input.ty(), mask));
if !compatible {
continue;
}
if let Ok(size) = cx.try_graph(input, successor)
&& size < best
{
best = size;
best_index = Some(index);
}
}
best_index.map_or(gid::STORE, |index| successors[index])
}
}