Skip to content

Commit 48bc63a

Browse files
authored
fix: Arrays with negative values cannot be encoded like bitpacked arrays (#2917)
1 parent ba96b2f commit 48bc63a

File tree

3 files changed

+8
-5
lines changed

3 files changed

+8
-5
lines changed

encodings/fastlanes/src/bitpacking/compress.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn bitpack_encode(array: &PrimitiveArray, bit_width: u8) -> VortexResult<Bit
3232
// Check array contains no negative values.
3333
if array.ptype().is_signed_int() {
3434
let has_negative_values = match_each_integer_ptype!(array.ptype(), |$P| {
35-
array.statistics().compute_min::<Option<$P>>().unwrap_or_default().unwrap_or_default() < 0
35+
array.statistics().compute_min::<$P>().unwrap_or_default() < 0
3636
});
3737
if has_negative_values {
3838
vortex_bail!("cannot bitpack_encode array containing negative integers")

encodings/fastlanes/src/bitpacking/serde.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,10 @@ impl EncodingVTable for BitPackedEncoding {
115115
None => find_best_bit_width(&parray)?,
116116
};
117117

118-
let array = if bit_width as usize == parray.ptype().bit_width() {
118+
let array = if bit_width as usize == parray.ptype().bit_width()
119+
|| parray.ptype().is_signed_int()
120+
&& parray.statistics().compute_min::<i64>().unwrap_or_default() < 0
121+
{
119122
parray.into_array()
120123
} else {
121124
bitpack_encode(&parray, bit_width)?.into_array()

vortex-file/src/strategy.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ impl LayoutWriter for BtrBlocksCompressedWriter {
139139
else if let Some(prev_compression) = self.previous_chunk.as_ref() {
140140
let prev_chunk = prev_compression.chunk.clone();
141141
let canonical_chunk = chunk.to_canonical()?;
142+
let canonical_nbytes = canonical_chunk.as_ref().nbytes();
142143

143144
if let Some(encoded_chunk) =
144-
encode_children_like(canonical_chunk.clone().into_array(), prev_chunk)?
145+
encode_children_like(canonical_chunk.into_array(), prev_chunk)?
145146
{
146-
let ratio =
147-
canonical_chunk.as_ref().nbytes() as f64 / encoded_chunk.nbytes() as f64;
147+
let ratio = canonical_nbytes as f64 / encoded_chunk.nbytes() as f64;
148148

149149
// Make sure the ratio is within the expected drift, if it isn't we fall back to the compressor.
150150
if ratio > prev_compression.ratio / COMPRESSION_DRIFT_THRESHOLD {

0 commit comments

Comments
 (0)