use arrow::array::BooleanArray;
use arrow::bitmap::MutableBitmap;
use arrow::error::Result;
use byteorder::{LittleEndian, ReadBytesExt};
use crate::compression::{integer::RLE, SAMPLE_SIZE};
use crate::compression::{Compression, SAMPLE_COUNT};
use super::{compress_sample_ratio, BooleanCompression, BooleanStats};
impl BooleanCompression for RLE {
fn compress(&self, array: &BooleanArray, output: &mut Vec<u8>) -> Result<usize> {
let size = output.len();
self.compress_integer(
output,
array.values().iter().map(|v| v as u8),
array.validity(),
)?;
Ok(output.len() - size)
}
fn decompress(&self, mut input: &[u8], length: usize, array: &mut MutableBitmap) -> Result<()> {
let mut num_values = 0;
while !input.is_empty() {
let len: u32 = input.read_u32::<LittleEndian>()?;
let t = input.read_u8()? != 0;
for _ in 0..len {
array.push(t);
}
num_values += len as usize;
if num_values >= length {
break;
}
}
Ok(())
}
fn to_compression(&self) -> Compression {
Compression::Rle
}
fn compress_ratio(&self, stats: &BooleanStats) -> f64 {
#[cfg(debug_assertions)]
{
if option_env!("STRAWBOAT_RLE_COMPRESSION") == Some("1") {
return f64::MAX;
}
}
compress_sample_ratio(self, stats, SAMPLE_COUNT, SAMPLE_SIZE)
}
}