use super::Pack;
#[derive(Debug)]
pub struct PackGenerator {
max_pack_size: usize,
current_size: usize,
data: Vec<(Vec<u8>, Vec<u8>)>,
packs: Vec<Pack>,
}
impl PackGenerator {
pub fn new(max_pack_size: usize) -> Self {
Self {
max_pack_size,
current_size: 0,
data: vec![],
packs: vec![],
}
}
pub fn extend<T: IntoIterator<Item = (Vec<u8>, Vec<u8>)>>(&mut self, data: T) {
for (key, value) in data {
let size = key.len() + value.len();
if size > (self.max_pack_size * 4) / 5 {
self.packs.push(Pack::new(vec![(key, value)]));
continue;
}
if self.current_size + size > self.max_pack_size {
self.current_size = 0;
let data = std::mem::take(&mut self.data);
self.packs.push(Pack::new(data));
}
self.current_size += size;
self.data.push((key, value));
}
}
pub fn finish(self) -> (Pack, Vec<Pack>) {
(Pack::new(self.data), self.packs)
}
}
#[cfg(test)]
mod test {
use super::PackGenerator;
#[test]
fn test_pack_generator() {
let mut generator = PackGenerator::new(25);
generator.extend((0..9).map(|num| {
(
format!("key{num}").as_bytes().to_vec(),
format!("value{num}").as_bytes().to_vec(),
)
}));
let (hot_pack, packs) = generator.finish();
assert_eq!(packs.len(), 4);
assert_eq!(hot_pack.data.len(), 1);
}
}