From c837cdb214677472b9c18ad02e1d0c36a3da1a47 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 5 Jul 2024 18:02:53 +0200 Subject: [PATCH] persistence: update load/save workflow --- src/persistence/fs.rs | 53 +++++++++++++++++++++++---------------- src/persistence/memory.rs | 34 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/persistence/fs.rs b/src/persistence/fs.rs index 002adf22..22640d1a 100644 --- a/src/persistence/fs.rs +++ b/src/persistence/fs.rs @@ -33,7 +33,7 @@ pub trait LoadFs: Sized { } pub trait StoreFs { - fn store(&self, path: impl AsRef) -> Result<(), SerializeError>; + fn store(&self) -> Result<(), SerializeError>; } impl LoadFs for Stock @@ -58,11 +58,10 @@ where H: StoreFs, I: StoreFs, { - fn store(&self, path: impl AsRef) -> Result<(), SerializeError> { - let path = path.as_ref(); - self.as_stash_provider().store(path)?; - self.as_state_provider().store(path)?; - self.as_index_provider().store(path)?; + fn store(&self) -> Result<(), SerializeError> { + self.as_stash_provider().store()?; + self.as_state_provider().store()?; + self.as_index_provider().store()?; Ok(()) } @@ -72,15 +71,19 @@ impl LoadFs for MemStash { fn load(path: impl AsRef) -> Result { let mut file = path.as_ref().to_owned(); file.push("stash.dat"); - Self::strict_deserialize_from_file::(file) + let mut me = Self::strict_deserialize_from_file::(&file)?; + me.set_filename(file); + Ok(me) } } impl StoreFs for MemStash { - fn store(&self, path: impl AsRef) -> Result<(), SerializeError> { - let mut file = path.as_ref().to_owned(); - file.push("stash.dat"); - self.strict_serialize_to_file::(file) + fn store(&self) -> Result<(), SerializeError> { + if self.is_dirty() { + self.strict_serialize_to_file::(&self.filename()) + } else { + Ok(()) + } } } @@ -88,15 +91,19 @@ impl LoadFs for MemState { fn load(path: impl AsRef) -> Result { let mut file = path.as_ref().to_owned(); file.push("state.dat"); - Self::strict_deserialize_from_file::(file) + let mut me = Self::strict_deserialize_from_file::(&file)?; + me.set_filename(file); + Ok(me) } } impl StoreFs for MemState { - fn store(&self, path: impl AsRef) -> Result<(), SerializeError> { - let mut file = path.as_ref().to_owned(); - file.push("state.dat"); - self.strict_serialize_to_file::(file) + fn store(&self) -> Result<(), SerializeError> { + if self.is_dirty() { + self.strict_serialize_to_file::(&self.filename()) + } else { + Ok(()) + } } } @@ -104,14 +111,18 @@ impl LoadFs for MemIndex { fn load(path: impl AsRef) -> Result { let mut file = path.as_ref().to_owned(); file.push("index.dat"); - Self::strict_deserialize_from_file::(file) + let mut me = Self::strict_deserialize_from_file::(&file)?; + me.set_filename(file); + Ok(me) } } impl StoreFs for MemIndex { - fn store(&self, path: impl AsRef) -> Result<(), SerializeError> { - let mut file = path.as_ref().to_owned(); - file.push("index.dat"); - self.strict_serialize_to_file::(file) + fn store(&self) -> Result<(), SerializeError> { + if self.is_dirty() { + self.strict_serialize_to_file::(&self.filename()) + } else { + Ok(()) + } } } diff --git a/src/persistence/memory.rs b/src/persistence/memory.rs index 0ef64bb6..c0797cdc 100644 --- a/src/persistence/memory.rs +++ b/src/persistence/memory.rs @@ -21,6 +21,8 @@ use std::collections::BTreeSet; use std::convert::Infallible; +#[cfg(feature = "fs")] +use std::path::{Path, PathBuf}; use aluvm::library::{Lib, LibId}; use amplify::confinement::{ @@ -60,7 +62,11 @@ use crate::LIB_NAME_RGB_STD; #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] pub struct MemStash { + #[strict_type(skip)] dirty: bool, + #[cfg(feature = "fs")] + #[strict_type(skip)] + filename: PathBuf, schemata: TinyOrdMap, ifaces: TinyOrdMap, @@ -82,6 +88,12 @@ impl StrictDeserialize for MemStash {} impl MemStash { pub fn new() -> Self { MemStash::default() } + + pub(crate) fn is_dirty(&self) -> bool { self.dirty } + #[cfg(feature = "fs")] + pub(crate) fn filename(&self) -> &Path { &self.filename } + #[cfg(feature = "fs")] + pub(crate) fn set_filename(&mut self, filename: PathBuf) { self.filename = filename } } impl StoreTransaction for MemStash { @@ -422,7 +434,12 @@ impl From for StateUpdateError { #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] pub struct MemState { + #[strict_type(skip)] dirty: bool, + #[cfg(feature = "fs")] + #[strict_type(skip)] + filename: PathBuf, + history: TinyOrdMap, } @@ -431,6 +448,12 @@ impl StrictDeserialize for MemState {} impl MemState { pub fn new() -> Self { MemState::default() } + + pub(crate) fn is_dirty(&self) -> bool { self.dirty } + #[cfg(feature = "fs")] + pub(crate) fn filename(&self) -> &Path { &self.filename } + #[cfg(feature = "fs")] + pub(crate) fn set_filename(&mut self, filename: PathBuf) { self.filename = filename } } impl StoreTransaction for MemState { @@ -521,7 +544,12 @@ pub struct ContractIndex { #[derive(StrictType, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] pub struct MemIndex { + #[strict_type(skip)] dirty: bool, + #[cfg(feature = "fs")] + #[strict_type(skip)] + filename: PathBuf, + op_bundle_index: MediumOrdMap, bundle_contract_index: MediumOrdMap, bundle_witness_index: MediumOrdMap, @@ -534,6 +562,12 @@ impl StrictDeserialize for MemIndex {} impl MemIndex { pub fn new() -> Self { MemIndex::default() } + + pub(crate) fn is_dirty(&self) -> bool { self.dirty } + #[cfg(feature = "fs")] + pub(crate) fn filename(&self) -> &Path { &self.filename } + #[cfg(feature = "fs")] + pub(crate) fn set_filename(&mut self, filename: PathBuf) { self.filename = filename } } impl StoreTransaction for MemIndex {