#[cfg(test)]
#[macro_use]
pub(crate) mod tests;
pub mod convert;
pub use crate::convert::*;
use bitpacking::{BitPacker, BitPacker1x, BitPacker4x, BitPacker8x};
pub trait BitPackOps {
fn pack(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize;
fn unpack(&self, compressed: &[u8], decompressed: &mut [u32], num_bits: u8) -> usize;
fn pack_m1(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize;
fn unpack_m1(&self, compressed: &[u8], decompressed: &mut [u32], num_bits: u8) -> usize;
fn pack_d1(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize;
fn unpack_d1(
&self,
initial: u32,
compressed: &[u8],
decompressed: &mut [u32],
num_bits: u8,
) -> usize;
fn pack_d1z(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize;
fn unpack_d1z(
&self,
initial: u32,
compressed: &[u8],
decompressed: &mut [u32],
num_bits: u8,
) -> usize;
}
macro_rules! impl_bit_pack_ops {
($bitpacker:ident) => {
impl BitPackOps for $bitpacker {
fn pack(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize {
let num_bits: u8 = match num_bits {
0 => self.num_bits(decompressed),
_ => num_bits,
};
self.compress(decompressed, compressed, num_bits)
}
fn unpack(&self, compressed: &[u8], decompressed: &mut [u32], num_bits: u8) -> usize {
self.decompress(compressed, decompressed, num_bits)
}
fn pack_m1(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize {
let mut tmp = vec![0_u32; decompressed.len()];
vanilla_to_m1(decompressed, tmp.as_mut_slice());
self.pack(tmp.as_slice(), compressed, num_bits)
}
fn unpack_m1(
&self,
compressed: &[u8],
decompressed: &mut [u32],
num_bits: u8,
) -> usize {
let n = self.unpack(compressed, decompressed, num_bits);
let n_decompressed = n * 8 / num_bits as usize;
m1_to_vanilla_self(decompressed.get_mut(0..n_decompressed).unwrap());
return n;
}
fn pack_d1(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize {
let initial = decompressed[0];
let num_bits: u8 = match num_bits {
0 => self.num_bits_sorted(initial, decompressed),
_ => num_bits,
};
self.compress_sorted(initial, decompressed, compressed, num_bits)
}
fn unpack_d1(
&self,
initial: u32,
compressed: &[u8],
decompressed: &mut [u32],
num_bits: u8,
) -> usize {
self.decompress_sorted(initial, compressed, decompressed, num_bits)
}
fn pack_d1z(&self, decompressed: &[u32], compressed: &mut [u8], num_bits: u8) -> usize {
let mut tmp = vec![0_u32; decompressed.len()];
vanilla_to_d1z(decompressed, tmp.as_mut_slice());
self.pack(tmp.as_slice(), compressed, num_bits)
}
fn unpack_d1z(
&self,
initial: u32,
compressed: &[u8],
decompressed: &mut [u32],
num_bits: u8,
) -> usize {
let n = self.decompress(compressed, decompressed, num_bits);
d1z_to_vanilla_self(decompressed, initial);
return n;
}
}
};
}
impl_bit_pack_ops!(BitPacker1x);
impl_bit_pack_ops!(BitPacker4x);
impl_bit_pack_ops!(BitPacker8x);