rollblock 0.4.1

A super-fast, block-oriented and rollbackable key-value store.
Documentation
use std::fs::File;
use std::path::PathBuf;

use crate::error::StoreResult;
use crate::types::JournalMeta;

use super::chunk::chunk_file_path;
use super::format::read_journal_block;
use super::JournalBlock;

pub struct JournalIter {
    pub(crate) metas: Vec<JournalMeta>,
    position: usize,
    chunk_dir: PathBuf,
    current_file: Option<(u32, File)>,
    key_bytes: usize,
}

impl JournalIter {
    pub(crate) fn new(chunk_dir: PathBuf, metas: Vec<JournalMeta>, key_bytes: usize) -> Self {
        Self {
            metas,
            position: 0,
            chunk_dir,
            current_file: None,
            key_bytes,
        }
    }

    pub fn next_entry(&mut self) -> Option<StoreResult<JournalBlock>> {
        if self.position >= self.metas.len() {
            return None;
        }

        let meta = self.metas[self.position].clone();
        self.position += 1;

        let key_bytes = self.key_bytes;
        match self.file_for_chunk(meta.chunk_id) {
            Ok(file) => Some(read_journal_block(file, &meta, key_bytes)),
            Err(err) => Some(Err(err)),
        }
    }

    fn file_for_chunk(&mut self, chunk_id: u32) -> StoreResult<&mut File> {
        let needs_open = self
            .current_file
            .as_ref()
            .map(|(open_id, _)| *open_id != chunk_id)
            .unwrap_or(true);

        if needs_open {
            let path = chunk_file_path(&self.chunk_dir, chunk_id);
            let file = File::open(&path)?;
            self.current_file = Some((chunk_id, file));
        }

        Ok(self
            .current_file
            .as_mut()
            .map(|(_, file)| file)
            .expect("chunk file opened above"))
    }
}