persy 1.3.0

Transactional Persistence Engine
Documentation
use crate::{
    device::{
        common::{
            check_and_trim, create_page, create_page_raw, flush_free_page, flush_page, load_free_page, load_page,
            load_page_raw, mark_allocated, trim_or_free_page,
        },
        Device, FreePage, Page, ReadPage, SizeTool, UpdateList,
    },
    error::PERes,
};
use std::{io::Cursor, sync::Mutex};

pub struct MemoryDevice {
    data: Mutex<Cursor<Vec<u8>>>,
}
impl MemoryDevice {
    pub fn new() -> PERes<MemoryDevice> {
        Ok(MemoryDevice {
            data: Mutex::new(Cursor::new(Vec::new())),
        })
    }
}

impl Device for MemoryDevice {
    fn load_free_page(&self, page: u64) -> PERes<FreePage> {
        load_free_page(&mut *self.data.lock()?, page)
    }

    fn flush_free_page(&self, page: &FreePage) -> PERes<()> {
        flush_free_page(&mut *self.data.lock()?, page)
    }

    fn load_page(&self, page: u64) -> PERes<ReadPage> {
        load_page(&mut *self.data.lock()?, page)
    }

    fn load_page_if_exists(&self, page: u64) -> PERes<Option<ReadPage>> {
        let mut data = self.data.lock()?;
        if data.len()? <= page {
            return Ok(None);
        }
        Ok(Some(load_page(&mut *data, page)?))
    }

    fn load_page_raw(&self, page: u64, size_exp: u8) -> PERes<Page> {
        load_page_raw(&mut *self.data.lock()?, page, size_exp)
    }

    fn flush_page(&self, page: &Page) -> PERes<()> {
        flush_page(&mut *self.data.lock()?, page)
    }

    fn create_page_raw(&self, exp: u8) -> PERes<u64> {
        create_page_raw(&mut *self.data.lock()?, exp)
    }

    fn create_page(&self, exp: u8) -> PERes<Page> {
        create_page(&mut *self.data.lock()?, exp)
    }

    fn mark_allocated(&self, page: u64) -> PERes<u64> {
        mark_allocated(&mut *self.data.lock()?, page)
    }

    fn sync(&self) -> PERes<()> {
        Ok(())
    }

    fn trim_or_free_page(&self, page: u64, update_list: &mut dyn UpdateList) -> PERes<()> {
        trim_or_free_page(&mut *self.data.lock()?, page, update_list)
    }

    fn trim_end_pages(&self, update_list: &mut dyn UpdateList) -> PERes<()> {
        while check_and_trim(&mut *self.data.lock()?, update_list, false)? {}
        Ok(())
    }

    #[cfg(test)]
    fn release_file_lock(&self) -> PERes<()> {
        Ok(())
    }
}