Skip to main content

vortex_btrblocks/schemes/float/
rle.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Run-length float encoding.
5
6use vortex_array::ArrayRef;
7use vortex_array::Canonical;
8use vortex_array::ExecutionCtx;
9use vortex_compressor::estimate::CompressionEstimate;
10use vortex_compressor::estimate::DeferredEstimate;
11use vortex_compressor::estimate::EstimateVerdict;
12use vortex_compressor::scheme::AncestorExclusion;
13use vortex_compressor::scheme::DescendantExclusion;
14use vortex_error::VortexResult;
15
16use crate::ArrayAndStats;
17use crate::CascadingCompressor;
18use crate::CompressorContext;
19use crate::Scheme;
20use crate::schemes::integer::RUN_LENGTH_THRESHOLD;
21use crate::schemes::integer::rle_compress;
22use crate::schemes::rle_ancestor_exclusions;
23use crate::schemes::rle_descendant_exclusions;
24
25/// RLE scheme for float arrays.
26#[derive(Debug, Copy, Clone, PartialEq, Eq)]
27pub struct FloatRLEScheme;
28
29impl Scheme for FloatRLEScheme {
30    fn scheme_name(&self) -> &'static str {
31        "vortex.float.rle"
32    }
33
34    fn matches(&self, canonical: &Canonical) -> bool {
35        canonical.dtype().is_float()
36    }
37
38    /// Children: values=0, indices=1, offsets=2.
39    fn num_children(&self) -> usize {
40        3
41    }
42
43    fn descendant_exclusions(&self) -> Vec<DescendantExclusion> {
44        rle_descendant_exclusions()
45    }
46
47    fn ancestor_exclusions(&self) -> Vec<AncestorExclusion> {
48        rle_ancestor_exclusions()
49    }
50
51    fn expected_compression_ratio(
52        &self,
53        data: &ArrayAndStats,
54        compress_ctx: CompressorContext,
55        exec_ctx: &mut ExecutionCtx,
56    ) -> CompressionEstimate {
57        // RLE is only useful when we cascade it with another encoding.
58        if compress_ctx.finished_cascading() {
59            return CompressionEstimate::Verdict(EstimateVerdict::Skip);
60        }
61
62        if data.float_stats(exec_ctx).average_run_length() < RUN_LENGTH_THRESHOLD {
63            return CompressionEstimate::Verdict(EstimateVerdict::Skip);
64        }
65
66        CompressionEstimate::Deferred(DeferredEstimate::Sample)
67    }
68
69    fn compress(
70        &self,
71        compressor: &CascadingCompressor,
72        data: &ArrayAndStats,
73        compress_ctx: CompressorContext,
74        exec_ctx: &mut ExecutionCtx,
75    ) -> VortexResult<ArrayRef> {
76        rle_compress(self, compressor, data, compress_ctx, exec_ctx)
77    }
78}