vortex_btrblocks/schemes/integer/
zigzag.rs1use vortex_array::ArrayId;
7use vortex_array::ArrayRef;
8use vortex_array::Canonical;
9use vortex_array::ExecutionCtx;
10use vortex_array::IntoArray;
11use vortex_array::VTable;
12use vortex_array::arrays::PrimitiveArray;
13use vortex_compressor::builtins::BinaryDictScheme;
14use vortex_compressor::builtins::FloatDictScheme;
15use vortex_compressor::builtins::IntDictScheme;
16use vortex_compressor::builtins::StringDictScheme;
17use vortex_compressor::scheme::AncestorExclusion;
18use vortex_compressor::scheme::ChildSelection;
19use vortex_compressor::scheme::CompressionEstimate;
20use vortex_compressor::scheme::DeferredEstimate;
21use vortex_compressor::scheme::DescendantExclusion;
22use vortex_compressor::scheme::EstimateVerdict;
23use vortex_error::VortexResult;
24use vortex_zigzag::ZigZag;
25use vortex_zigzag::ZigZagArraySlotsExt;
26use vortex_zigzag::zigzag_encode;
27
28use super::RunEndScheme;
29use super::SparseScheme;
30use crate::ArrayAndStats;
31use crate::CascadingCompressor;
32use crate::CompressorContext;
33use crate::Scheme;
34use crate::SchemeExt;
35
36#[derive(Debug, Copy, Clone, PartialEq, Eq)]
38pub struct ZigZagScheme;
39
40impl Scheme for ZigZagScheme {
41 fn scheme_name(&self) -> &'static str {
42 "vortex.int.zigzag"
43 }
44
45 fn matches(&self, canonical: &Canonical) -> bool {
46 canonical.dtype().is_int()
47 }
48
49 fn produced_encodings(&self) -> Vec<ArrayId> {
50 vec![ZigZag.id()]
51 }
52
53 fn num_children(&self) -> usize {
55 1
56 }
57
58 fn descendant_exclusions(&self) -> Vec<DescendantExclusion> {
62 vec![
63 DescendantExclusion {
64 excluded: IntDictScheme.id(),
65 children: ChildSelection::All,
66 },
67 DescendantExclusion {
68 excluded: RunEndScheme.id(),
69 children: ChildSelection::All,
70 },
71 DescendantExclusion {
72 excluded: SparseScheme.id(),
73 children: ChildSelection::All,
74 },
75 ]
76 }
77
78 fn ancestor_exclusions(&self) -> Vec<AncestorExclusion> {
80 vec![
81 AncestorExclusion {
82 ancestor: IntDictScheme.id(),
83 children: ChildSelection::One(1),
84 },
85 AncestorExclusion {
86 ancestor: FloatDictScheme.id(),
87 children: ChildSelection::One(1),
88 },
89 AncestorExclusion {
90 ancestor: StringDictScheme.id(),
91 children: ChildSelection::One(1),
92 },
93 AncestorExclusion {
94 ancestor: BinaryDictScheme.id(),
95 children: ChildSelection::One(1),
96 },
97 ]
98 }
99
100 fn expected_compression_ratio(
101 &self,
102 data: &ArrayAndStats,
103 compress_ctx: CompressorContext,
104 exec_ctx: &mut ExecutionCtx,
105 ) -> CompressionEstimate {
106 if compress_ctx.finished_cascading() {
109 return CompressionEstimate::Verdict(EstimateVerdict::Skip);
110 }
111 let stats = data.integer_stats(exec_ctx);
112
113 if !stats.erased().min_is_negative() {
115 return CompressionEstimate::Verdict(EstimateVerdict::Skip);
116 }
117
118 CompressionEstimate::Deferred(DeferredEstimate::Sample)
119 }
120
121 fn compress(
122 &self,
123 compressor: &CascadingCompressor,
124 data: &ArrayAndStats,
125 compress_ctx: CompressorContext,
126 exec_ctx: &mut ExecutionCtx,
127 ) -> VortexResult<ArrayRef> {
128 let zag = zigzag_encode(data.array_as_primitive())?;
130 let encoded = zag.encoded().clone().execute::<PrimitiveArray>(exec_ctx)?;
131
132 let compressed = compressor.compress_child(
133 &encoded.into_array(),
134 &compress_ctx,
135 self.id(),
136 0,
137 exec_ctx,
138 )?;
139
140 Ok(ZigZag::try_new(compressed)?.into_array())
141 }
142}