Mercurial > lbo > hg > memoize
view README.md @ 37:39b49b493180
Fx typo in README
author | Илья Ефимов <inferrna@gmail.com> |
---|---|
date | Fri, 11 Dec 2020 01:40:36 +0800 |
parents | 7723677c1a0e |
children | 390b3b7095cc |
line wrap: on
line source
# memoize [![Docs.rs](https://docs.rs/memoize/badge.svg)](https://docs.rs/memoize) [![Crates.rs](https://img.shields.io/crates/v/memoize.svg)](https://crates.io/crates/memoize) A `#[memoize]` attribute for somewhat simple Rust functions: That is, functions with one or more `Clone`-able arguments, and a `Clone`-able return type. That's it. Read the documentation (`cargo doc --open`) for the sparse details, or take a look at the `examples/`, if you want to know more: ```rust // From examples/test2.rs use memoize::memoize; #[memoize] fn hello(arg: String, arg2: usize) -> bool { arg.len()%2 == arg2 } fn main() { // `hello` is only called once here. assert!(! hello("World".to_string(), 0)); assert!(! hello("World".to_string(), 0)); // Sometimes one might need the original function. assert!(! memoized_original_hello("World".to_string(), 0)); } ``` This is expanded into (with a few simplifications): ```rust // This is obviously further expanded before compiling. lazy_static! { static ref MEMOIZED_MAPPING_HELLO : Mutex<HashMap<String, bool>>; } fn memoized_original_hello(arg: String, arg2: usize) -> bool { arg.len() % 2 == arg2 } fn hello(arg: String, arg2: usize) -> bool { let mut hm = &mut MEMOIZED_MAPPING_HELLO.lock().unwrap(); if let Some(r) = hm.get(&(arg.clone(), arg2.clone())) { return r.clone(); } let r = memoized_original_hello(arg.clone(), arg2.clone()); hm.insert((arg, arg2), r.clone()); r } ``` ## Further Functionality You can choose to use an [LRU cache](https://crates.io/crates/lru). In fact, if you know that a memoized function has an unbounded number of different inputs, you should do this! In that case, use the attribute like this: ```rust // From examples/test1.rs // Compile with --features=full use memoize::memoize; #[derive(Debug, Clone)] struct ComplexStruct { // ... } #[memoize(Capacity: 123)] fn hello(key: String) -> ComplexStruct { // ... } ``` Adding more caches and configuration options is relatively simple, and a matter of parsing attribute parameters. Currently, compiling will fail if you use a parameter such as `Capacity` without the feature `full` being enabled. Another parameter is TimeToLive - it's targeting to refresh outdated values. Example: ```rust #[memoize(Capacity: 123, TimeToLive: Duration::from_secs(2))] ``` chrono::Duration is also possible, but have to be converted into std::time::Duration ```rust #[memoize(TimeToLive: chrono::Duration::hours(3).to_std().unwrap())] ``` cached value will be actual no longer than duration provided and refreshed with next request. ## Contributions ...are always welcome! This being my first procedural-macros crate, I am grateful for improvements of functionality and style. Please send a pull request, and don't be discouraged if it takes a while for me to review it; I'm sometimes a bit slow to catch up here :) -- Lewin