persy 1.5.2

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>>>,
    limit: Option<u64>,
}
impl MemoryDevice {
    pub fn new(limit: Option<u64>) -> PERes<MemoryDevice> {
        Ok(MemoryDevice {
            data: Mutex::new(Cursor::new(Vec::new())),
            limit,
        })
    }
}

impl Device for MemoryDevice {
    fn load_free_page(&self, page: u64) -> PERes<FreePage> {
        load_free_page(&mut *self.data.lock().expect("memory device lock not poisoned"), page)
    }

    fn flush_free_page(&self, page: &FreePage) -> PERes<()> {
        flush_free_page(&mut *self.data.lock().expect("memory device lock not poisoned"), page)
    }

    fn load_page(&self, page: u64) -> PERes<ReadPage> {
        load_page(&mut *self.data.lock().expect("memory device lock not poisoned"), page)
    }

    fn load_page_if_exists(&self, page: u64) -> PERes<Option<ReadPage>> {
        let mut data = self.data.lock().expect("memory device lock not poisoned");
        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().expect("memory device lock not poisoned"),
            page,
            size_exp,
        )
    }

    fn flush_page(&self, page: &Page) -> PERes<()> {
        flush_page(&mut *self.data.lock().expect("memory device lock not poisoned"), page)
    }

    fn create_page_raw(&self, exp: u8) -> PERes<u64> {
        create_page_raw(
            &mut *self.data.lock().expect("memory device lock not poisoned"),
            exp,
            self.limit,
        )
    }

    fn create_page(&self, exp: u8) -> PERes<Page> {
        create_page(
            &mut *self.data.lock().expect("memory device lock not poisoned"),
            exp,
            self.limit,
        )
    }

    fn mark_allocated(&self, page: u64) -> PERes<u64> {
        mark_allocated(&mut *self.data.lock().expect("memory device lock not poisoned"), 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().expect("memory device lock not poisoned"),
            page,
            update_list,
        )
    }

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

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