use std::mem;
use super::rle::RleEncoder;
use crate::basic::Encoding;
use crate::data_type::AsBytes;
use crate::util::bit_util::{BitWriter, ceil, num_required_bits};
#[inline]
pub fn max_buffer_size(encoding: Encoding, max_level: i16, num_buffered_values: usize) -> usize {
let bit_width = num_required_bits(max_level as u64);
match encoding {
Encoding::RLE => RleEncoder::max_buffer_size(bit_width, num_buffered_values),
#[allow(deprecated)]
Encoding::BIT_PACKED => ceil(num_buffered_values * bit_width as usize, 8),
_ => panic!("Unsupported encoding type {encoding}"),
}
}
pub enum LevelEncoder {
Rle(RleEncoder),
RleV2(RleEncoder),
BitPacked(u8, BitWriter),
}
impl LevelEncoder {
pub fn v1(encoding: Encoding, max_level: i16, capacity: usize) -> Self {
let capacity_bytes = max_buffer_size(encoding, max_level, capacity);
let mut buffer = Vec::with_capacity(capacity_bytes);
let bit_width = num_required_bits(max_level as u64);
match encoding {
Encoding::RLE => {
buffer.extend_from_slice(&[0; 4]);
LevelEncoder::Rle(RleEncoder::new_from_buf(bit_width, buffer))
}
#[allow(deprecated)]
Encoding::BIT_PACKED => {
LevelEncoder::BitPacked(bit_width, BitWriter::new_from_buf(buffer))
}
_ => panic!("Unsupported encoding type {encoding}"),
}
}
pub fn v2(max_level: i16, capacity: usize) -> Self {
let capacity_bytes = max_buffer_size(Encoding::RLE, max_level, capacity);
let buffer = Vec::with_capacity(capacity_bytes);
let bit_width = num_required_bits(max_level as u64);
LevelEncoder::RleV2(RleEncoder::new_from_buf(bit_width, buffer))
}
#[inline]
pub fn put(&mut self, buffer: &[i16]) -> usize {
let mut num_encoded = 0;
match *self {
LevelEncoder::Rle(ref mut encoder) | LevelEncoder::RleV2(ref mut encoder) => {
for value in buffer {
encoder.put(*value as u64);
num_encoded += 1;
}
encoder.flush();
}
LevelEncoder::BitPacked(bit_width, ref mut encoder) => {
for value in buffer {
encoder.put_value(*value as u64, bit_width as usize);
num_encoded += 1;
}
encoder.flush();
}
}
num_encoded
}
#[inline]
pub fn consume(self) -> Vec<u8> {
match self {
LevelEncoder::Rle(encoder) => {
let mut encoded_data = encoder.consume();
let encoded_len = encoded_data.len() - mem::size_of::<i32>();
let len = (encoded_len as i32).to_le();
let len_bytes = len.as_bytes();
encoded_data[0..len_bytes.len()].copy_from_slice(len_bytes);
encoded_data
}
LevelEncoder::RleV2(encoder) => encoder.consume(),
LevelEncoder::BitPacked(_, encoder) => encoder.consume(),
}
}
}