diff --git a/src/lib.rs b/src/lib.rs index a209620..5cb581c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,8 +12,9 @@ use iter::Iter; pub mod no_flash; mod test; +/// Backend interface for `Store` pub trait StoreBackend { - type Data: Sized + AsRef<[u8]> + Clone; + type Data: Sized + AsRef<[u8]>; /// Memory-mapped fn data(&self) -> &Self::Data; @@ -22,10 +23,17 @@ pub trait StoreBackend { } type Error; + /// erase flash fn erase(&mut self) -> Result<(), Self::Error>; + /// program flash fn program(&mut self, offset: usize, payload: &[u8]) -> Result<(), Self::Error>; /// called after repeated `program()` invocations to allow for eg. cache flushing fn program_done(&mut self) {} + + /// need for automatic compaction + /// + /// leaves memory management to the implementer + fn backup_space(&self) -> &'static mut [u8]; } /// Simple Flash Key Value Store @@ -114,7 +122,8 @@ impl Store { } fn compact(&mut self) -> Result<(), Error> { - let old_data = self.backend.data().clone(); + let old_data = self.backend.backup_space(); + old_data.copy_from_slice(self.backend.data().as_ref()); self.erase()?; diff --git a/src/no_flash.rs b/src/no_flash.rs index 8324461..ba7ca33 100644 --- a/src/no_flash.rs +++ b/src/no_flash.rs @@ -30,4 +30,8 @@ impl StoreBackend for NoFlash { fn program(&mut self, _: usize, _: &[u8]) -> Result<(), Self::Error> { Err(NoFlashError) } + + fn backup_space(&self) -> &'static mut [u8] { + &mut [] + } } diff --git a/src/test.rs b/src/test.rs index d7a914b..ec13047 100644 --- a/src/test.rs +++ b/src/test.rs @@ -3,6 +3,7 @@ use crate::{Error, no_flash, Store, StoreBackend, WriteError}; const SIZE: usize = 1024; +static mut BACKUP_SPACE: [u8; SIZE] = [0; SIZE]; pub struct TestBackend { data: [u8; SIZE], @@ -39,6 +40,11 @@ impl StoreBackend for TestBackend { self.data[offset..end].copy_from_slice(payload); Ok(()) } + + + fn backup_space(&self) -> &'static mut [u8] { + unsafe { &mut BACKUP_SPACE } + } } fn make_store() -> Store {