diff --git a/valuescript_vm/src/val_storage.rs b/valuescript_vm/src/val_storage.rs index 0447297..a181efb 100644 --- a/valuescript_vm/src/val_storage.rs +++ b/valuescript_vm/src/val_storage.rs @@ -399,11 +399,29 @@ fn read_ref_bytecode_from_entry>( tx: &Tx, reader: &mut StorageEntryReader, ) -> Result, GenericError> { + let ref_cell = tx + .get_backend() + .upgrade() + .ok_or(Into::>::into("Storage backend missing"))?; + let ptr = reader.read_ref()?; + + let borrow = ref_cell.borrow(); + let mut read_cache = borrow.get_read_cache(); + + if let Some(cache_box) = read_cache.get(&ptr.data) { + if let Some(cache_val) = cache_box.downcast_ref::>() { + return Ok(cache_val.clone()); + } + } + let entry = tx.read_or_err(ptr)?; - // TODO: Cached reads - Ok(Rc::new(Bytecode::from_storage_entry(tx, entry)?)) + let res = Rc::new(Bytecode::from_storage_entry(tx, entry)?); + + read_cache.insert(ptr.data, Box::new(res.clone())); + + Ok(res) } fn write_ref_bytecode_to_entry>( diff --git a/valuescript_vm/src/vs_storage_ptr.rs b/valuescript_vm/src/vs_storage_ptr.rs index f6f4d22..43c1576 100644 --- a/valuescript_vm/src/vs_storage_ptr.rs +++ b/valuescript_vm/src/vs_storage_ptr.rs @@ -25,7 +25,7 @@ impl ValResolver for StorageValAutoPtr { }; let borrow = sb.borrow(); - let mut read_cache = borrow.get_read_cache(); + let read_cache = borrow.get_read_cache(); if let Some(cache_box) = read_cache.get(&self.ptr.ptr.data) { if let Some(cache_val) = cache_box.downcast_ref::() { @@ -33,9 +33,13 @@ impl ValResolver for StorageValAutoPtr { } } + drop(read_cache); + let entry = sb.read(self.ptr.ptr).unwrap().expect("Unresolved ptr"); let res = Val::from_storage_entry(&sb, entry).expect("Failed to deserialize Val"); + let mut read_cache = borrow.get_read_cache(); + read_cache.insert(self.ptr.ptr.data, Box::new(res.clone())); res @@ -64,6 +68,9 @@ impl VsStoragePtr { pub fn new(auto_ptr: StorageAutoPtr) -> Self { Self { resolver: Box::new(StorageValAutoPtr { ptr: auto_ptr }), + + // TODO: Since there's also caching in the storage backend's read_cache, is it worthwhile to + // cache here too? (Perf test.) cache: RefCell::new(None), } }