use std::io;
use crate::value::{deserialize_vint_u64, ValueReader, ValueWriter};
use crate::vint;
#[derive(Default)]
pub struct U64MonotonicValueReader {
vals: Vec<u64>,
}
impl ValueReader for U64MonotonicValueReader {
type Value = u64;
#[inline(always)]
fn value(&self, idx: usize) -> &Self::Value {
&self.vals[idx]
}
fn load(&mut self, mut data: &[u8]) -> io::Result<usize> {
let original_num_bytes = data.len();
let num_vals = deserialize_vint_u64(&mut data) as usize;
self.vals.clear();
let mut prev_val = 0u64;
for _ in 0..num_vals {
let delta = deserialize_vint_u64(&mut data);
let val = prev_val + delta;
self.vals.push(val);
prev_val = val;
}
Ok(original_num_bytes - data.len())
}
}
#[derive(Default)]
pub struct U64MonotonicValueWriter {
vals: Vec<u64>,
}
impl ValueWriter for U64MonotonicValueWriter {
type Value = u64;
fn write(&mut self, val: &Self::Value) {
self.vals.push(*val);
}
fn serialize_block(&self, output: &mut Vec<u8>) {
let mut prev_val = 0u64;
vint::serialize_into_vec(self.vals.len() as u64, output);
for &val in &self.vals {
let delta = val - prev_val;
vint::serialize_into_vec(delta, output);
prev_val = val;
}
}
fn clear(&mut self) {
self.vals.clear();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_u64_monotonic_reader_writer() {
crate::value::tests::test_value_reader_writer::<
_,
U64MonotonicValueReader,
U64MonotonicValueWriter,
>(&[]);
crate::value::tests::test_value_reader_writer::<
_,
U64MonotonicValueReader,
U64MonotonicValueWriter,
>(&[5]);
crate::value::tests::test_value_reader_writer::<
_,
U64MonotonicValueReader,
U64MonotonicValueWriter,
>(&[1u64, 30u64]);
}
}