jubako 0.3.0

The reference implementation of the Jubako container format
Documentation
use crate::bases::*;
use crate::common::ContentInfo;
use crate::creator::InputReader;

pub(super) struct ClusterCreator {
    compressed: bool,
    pub index: ClusterIdx,
    pub data: Vec<Box<dyn InputReader>>,
    pub offsets: Vec<u64>,
}

pub(crate) const CLUSTER_SIZE: Size = Size::new(1024 * 1024 * 4);
const MAX_BLOBS_PER_CLUSTER: usize = 0xFFF;

impl ClusterCreator {
    pub fn new(index: ClusterIdx, compressed: bool) -> Self {
        ClusterCreator {
            compressed,
            index,
            data: Vec::with_capacity(MAX_BLOBS_PER_CLUSTER),
            offsets: vec![],
        }
    }

    pub fn data_size(&self) -> Size {
        Size::from(*self.offsets.last().unwrap_or(&0))
    }

    pub fn is_full(&self, size: Size) -> bool {
        if self.offsets.len() == MAX_BLOBS_PER_CLUSTER {
            return true;
        }
        self.compressed && !self.offsets.is_empty() && self.data_size() + size > CLUSTER_SIZE
    }

    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    pub fn add_content(&mut self, content: Box<dyn InputReader>) -> Result<ContentInfo> {
        assert!(self.offsets.len() < MAX_BLOBS_PER_CLUSTER);
        let content_size = content.size();
        let idx = self.offsets.len() as u16;
        let new_offset = self.offsets.last().unwrap_or(&0) + content_size.into_u64();
        self.data.push(content);
        self.offsets.push(new_offset);
        Ok(ContentInfo::new(self.index, BlobIdx::from(idx)))
    }
}