Giter VIP home page Giter VIP logo

memoize's Introduction

memoize

Docs.rs Crates.rs CI

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.

NEWS: The crate has been updated so that you don't need to separately import lru, lazy_static, and other dependencies. Now everything should work automatically. Remember to enable the full feature to use LRU caching and other additional features.

Read the documentation (cargo doc --open) for the sparse details, or take a look at the examples/, if you want to know more:

// 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):

std::thread_local! {
  static MEMOIZED_MAPPING_HELLO : RefCell<HashMap<(String, usize), bool>> = RefCell::new(HashMap::new());
}

pub fn memoized_original_hello(arg: String, arg2: usize) -> bool {
  arg.len() % 2 == arg2
}

#[allow(unused_variables)]
fn hello(arg: String, arg2: usize) -> bool {
  let r = MEMOIZED_MAPPING_HELLO.with(|hm| {
    let mut hm = hm.borrow_mut();
    hm.get(&(arg.clone(), arg2.clone())).cloned()
  });
  if let Some(r) = r {
    return r;
  }

  let r = memoized_original_hello(arg.clone(), arg2.clone());

  MEMOIZED_MAPPING_HELLO.with(|hm| {
    let mut hm = hm.borrow_mut();
    hm.insert((arg, arg2), r.clone());
  });

  r
}

Further Functionality

As can be seen in the above example, each thread has its own cache by default. If you would prefer that every thread share the same cache, you can specify the SharedCache option like below to wrap the cache in a std::sync::Mutex. For example:

#[memoize(SharedCache)]
fn hello(key: String) -> ComplexStruct {
  // ...
}

You can choose to use an LRU cache. 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:

// 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, specifying how long a cached value is allowed to live:

#[memoize(Capacity: 123, TimeToLive: Duration::from_secs(2))]

chrono::Duration is also possible, but would have to first be converted to std::time::Duration

#[memoize(TimeToLive: chrono::Duration::hours(3).to_std().unwrap())]

The cached value will never be older than duration provided and instead recalculated on the 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

memoize's People

Contributors

bijij avatar codadillo avatar dermesser avatar inferrna avatar jannic avatar maksimryndin avatar shinmili avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.