changeset 84:868eb5c58450

Add functionality for flushing the entire memoization cache (#16)
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 21 Oct 2022 19:05:50 +0200
parents fa483417e99f
children fbf408e00f17
files README.md examples/full_featured.rs examples/trivial.rs inner/src/lib.rs
diffstat 4 files changed, 26 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/README.md	Tue Aug 09 10:16:54 2022 +0200
+++ b/README.md	Fri Oct 21 19:05:50 2022 +0200
@@ -118,6 +118,11 @@
 The cached value will never be older than duration provided and instead
 recalculated on the next request.
 
+### Flushing
+
+If you memoize a function `f`, there will be a function called
+`memoized_flush_f()` that allows you to clear the memoization cache.
+
 ## Contributions
 
 ...are always welcome! This being my first procedural-macros crate, I am
--- a/examples/full_featured.rs	Tue Aug 09 10:16:54 2022 +0200
+++ b/examples/full_featured.rs	Fri Oct 21 19:05:50 2022 +0200
@@ -2,6 +2,7 @@
 use std::thread;
 use std::time::{Duration, Instant};
 
+#[allow(dead_code)]
 #[derive(Debug, Clone)]
 struct ComplexStruct {
     s: String,
@@ -25,12 +26,16 @@
     {
         println!("result: {:?}", hello("ABC".to_string()));
         println!("result: {:?}", hello("DEF".to_string()));
-        println!("result: {:?}", hello("ABC".to_string())); //Same as first
+        println!("result: {:?}", hello("ABC".to_string())); // Same as first
         thread::sleep(core::time::Duration::from_millis(2100));
+        println!("result: {:?}", hello("ABC".to_string()));
+        println!("result: {:?}", hello("DEF".to_string()));
+        println!("result: {:?}", hello("ABC".to_string())); // Same as first
+        memoized_flush_hello();
         println!("result: {:?}", hello("EFG".to_string()));
-        println!("result: {:?}", hello("ABC".to_string())); //Refreshed
-        println!("result: {:?}", hello("EFG".to_string())); //Same as first
-        println!("result: {:?}", hello("ABC".to_string())); //Same as refreshed
+        println!("result: {:?}", hello("ABC".to_string())); // Refreshed
+        println!("result: {:?}", hello("EFG".to_string())); // Same as first
+        println!("result: {:?}", hello("ABC".to_string())); // Same as refreshed
         println!("result: {:?}", memoized_original_hello("ABC".to_string()));
     }
 }
--- a/examples/trivial.rs	Tue Aug 09 10:16:54 2022 +0200
+++ b/examples/trivial.rs	Fri Oct 21 19:05:50 2022 +0200
@@ -12,4 +12,5 @@
     assert!(!hello("World".to_string(), 0));
     // Sometimes one might need the original function.
     assert!(!memoized_original_hello("World".to_string(), 0));
+    memoized_flush_hello();
 }
--- a/inner/src/lib.rs	Tue Aug 09 10:16:54 2022 +0200
+++ b/inner/src/lib.rs	Fri Oct 21 19:05:50 2022 +0200
@@ -198,6 +198,9 @@
  *
  * This mechanism can, in principle, be extended (in the source code) to any other cache mechanism.
  *
+ * `memoized_flush_<function name>()` allows you to clear the underlying memoization cache of a
+ * function. This function is generated with the same visibility as the memoized function.
+ *
  */
 #[proc_macro_attribute]
 pub fn memoize(attr: TokenStream, item: TokenStream) -> TokenStream {
@@ -206,6 +209,7 @@
 
     let fn_name = &sig.ident.to_string();
     let renamed_name = format!("memoized_original_{}", fn_name);
+    let flush_name = syn::Ident::new(format!("memoized_flush_{}", fn_name).as_str(), sig.span());
     let map_name = format!("memoized_mapping_{}", fn_name);
 
     // Extracted from the function signature.
@@ -313,9 +317,15 @@
 
     let vis = &func.vis;
 
+    let flusher = quote::quote! {
+        #vis fn #flush_name() {
+            #store_ident.with(|hm| hm.borrow_mut().clear());
+        }
+    };
+
     quote::quote! {
         #renamed_fn
-
+        #flusher
         #store
 
         #[allow(unused_variables)]