use std::io::BufRead;
use arrow::array::BinaryArray;
use arrow::error::Error;
use arrow::error::Result;
use arrow::types::Offset;
use byteorder::{LittleEndian, ReadBytesExt};
use crate::compression::integer::OneValue;
use crate::compression::Compression;
use crate::general_err;
use crate::write::WriteOptions;
use super::BinaryCompression;
impl<O: Offset> BinaryCompression<O> for OneValue {
fn to_compression(&self) -> Compression {
Compression::OneValue
}
fn compress_ratio(&self, stats: &super::BinaryStats<O>) -> f64 {
if stats.unique_count <= 1 {
stats.tuple_count as f64
} else {
0.0f64
}
}
fn compress(
&self,
array: &BinaryArray<O>,
_write_options: &WriteOptions,
output_buf: &mut Vec<u8>,
) -> Result<usize> {
let val = array.iter().find(|v| v.is_some());
let val = match val {
Some(Some(v)) => v,
_ => &[],
};
let start = output_buf.len();
output_buf.extend_from_slice(&(val.len() as u32).to_le_bytes());
output_buf.extend_from_slice(val);
Ok(output_buf.len() - start)
}
fn decompress(
&self,
mut input: &[u8],
length: usize,
offsets: &mut Vec<O>,
values: &mut Vec<u8>,
) -> Result<()> {
let len = input.read_u32::<LittleEndian>()? as usize;
if input.len() < len {
return Err(general_err!("data size is less than {}", len));
}
let val = &input[..len];
input.consume(len);
if offsets.is_empty() {
offsets.push(O::zero());
}
offsets.reserve(length);
values.reserve(length * val.len());
for _ in 0..length {
values.extend_from_slice(val);
offsets.push(O::from_usize(values.len()).unwrap());
}
Ok(())
}
}