use std::cell::RefCell; use std::error::Error; use std::rc::Rc; use crate::storage_entity::StorageEntity; use crate::storage_ptr::{tmp_at_ptr, tmp_count_ptr, StorageEntryPtr, StorageHeadPtr}; use crate::{StorageBackend, StorageReader, StorageTxMut}; pub struct Storage { pub(crate) sb: Rc>, } impl Storage { pub fn new(sb: SB) -> Self { Self { sb: Rc::new(RefCell::new(sb)), } } pub fn set_head>( &mut self, ptr: StorageHeadPtr, value: &SE, ) -> Result<(), Box> { self .sb .borrow_mut() .transaction_mut(Rc::downgrade(&self.sb), |sb| sb.set_head(ptr, value)) } pub fn remove_head(&mut self, ptr: StorageHeadPtr) -> Result<(), Box> { self .sb .borrow_mut() .transaction_mut(Rc::downgrade(&self.sb), |sb| sb.remove_head(ptr)) } pub fn clear_read_cache(&mut self) { self.sb.borrow_mut().get_read_cache().clear() } pub fn store_tmp>( &mut self, value: &SE, ) -> Result> { self .sb .borrow_mut() .transaction_mut(Rc::downgrade(&self.sb), |sb| { let tmp_count = sb.read(tmp_count_ptr())?.unwrap_or(0); let tmp_ptr = tmp_at_ptr(tmp_count); sb.set_head(tmp_ptr, value)?; sb.write(tmp_count_ptr(), Some(&(tmp_count + 1)))?; let ptr = sb.read(tmp_ptr)?.unwrap_or_else(|| panic!("Ptr not found")); Ok(ptr) }) } pub fn clear_tmp(&mut self) -> Result<(), Box> { self .sb .borrow_mut() .transaction_mut(Rc::downgrade(&self.sb), |sb| { let tmp_count = sb.read(tmp_count_ptr())?.unwrap_or(0); for i in 0..tmp_count { sb.remove_head(tmp_at_ptr(i))?; } sb.write(tmp_count_ptr(), None)?; Ok(()) }) } pub fn is_empty(&self) -> bool { self.sb.borrow().is_empty() } #[cfg(test)] pub(crate) fn get_ref_count( &mut self, ptr: StorageEntryPtr, ) -> Result, Box> { self .sb .read(ptr) .map(|entry| entry.map(|entry| entry.ref_count)) } } impl StorageReader for Storage { fn read_bytes( &self, ptr: crate::StoragePtr, ) -> Result>, crate::GenericError> { self.sb.borrow().read_bytes(ptr) } fn get_backend(&self) -> std::rc::Weak> { Rc::downgrade(&self.sb) } }