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