1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use holochain_persistence_api::{ cas::{ content::{Address, AddressableContent, Content}, storage::ContentAddressableStorage, }, error::PersistenceResult, reporting::ReportStorage, }; use std::{ collections::HashMap, sync::{Arc, RwLock}, }; use uuid::Uuid; #[derive(Clone, Debug)] pub struct MemoryStorage { storage: Arc<RwLock<HashMap<Address, Content>>>, id: Uuid, } impl PartialEq for MemoryStorage { fn eq(&self, other: &MemoryStorage) -> bool { self.id == other.id } } impl Default for MemoryStorage { fn default() -> MemoryStorage { MemoryStorage { storage: Arc::new(RwLock::new(HashMap::new())), id: Uuid::new_v4(), } } } impl MemoryStorage { pub fn new() -> MemoryStorage { Default::default() } } impl ContentAddressableStorage for MemoryStorage { fn add(&mut self, content: &dyn AddressableContent) -> PersistenceResult<()> { let mut map = self.storage.write()?; map.insert(content.address().clone(), content.content().clone()); Ok(()) } fn contains(&self, address: &Address) -> PersistenceResult<bool> { let map = self.storage.read()?; Ok(map.contains_key(address)) } fn fetch(&self, address: &Address) -> PersistenceResult<Option<Content>> { let map = self.storage.read()?; Ok(map.get(address).cloned()) } fn get_id(&self) -> Uuid { self.id } } impl ReportStorage for MemoryStorage {} #[cfg(test)] pub mod tests { use crate::cas::memory::MemoryStorage; use holochain_json_api::json::RawString; use holochain_persistence_api::cas::{ content::{ExampleAddressableContent, OtherExampleAddressableContent}, storage::StorageTestSuite, }; pub fn test_memory_storage() -> MemoryStorage { MemoryStorage::new() } #[test] fn memory_round_trip() { let test_suite = StorageTestSuite::new(test_memory_storage()); test_suite.round_trip_test::<ExampleAddressableContent, OtherExampleAddressableContent>( RawString::from("foo").into(), RawString::from("bar").into(), ); } }