Crate cachingmap[][src]

Expand description

This crate provides the CachingMap struct, which is a HashMap accepting insertion of new entries while immutable.

It relies on a regular HashMap hidden behind an UnsafeCell and accessible through Deref and DerefMut. On top of this, the CachingMap::cache allows to insert a new entry in an immutable CachingMap. Safety is maintained by refusing to replace existing entries: all previously returned references remain valid as long as only immutable methods are used.

⚠️ CachingMap is NOT thread safe and should be rejected by the compiler.

Get from cache or compute only if needed

The most convenient use of the caching map is to request a cached value with a closure to compute it if needed. The closure will be called only if the key is missing from the cache. Note that only the first call will execute the closure, all following calls will use the cache, even if the closure is different or not predictable. See CachingMap doc for other uses.

use cachingmap::CachingMap;

// Suppose that we have an expensive function returning predictable results
fn compute_value(seed: &usize) -> String // content skipped

// Create a cache and use closures to compute and cache the result
let mut cache = CachingMap::new();
let ref1 = cache.cached(1, &|v| compute_value(v));

// If we call it on an existing key, the closure is NOT executed
// and we obtain a reference to the previously cached object
let ref1b = cache.cached(1, &|v| compute_value(v));    // same result, skipped
let ref1c = cache.cached(1, &|v| compute_value(&10));   // different result, also skipped

// Only the first inserted a value in the cache. All references borrow the same data
assert!(ref1.is_new() && ref1b.is_old() && ref1c.is_old());
assert!(std::ptr::eq(*ref1, *ref1c));

// Any mutable access to the cache invalidates previous references.
// This allows to clear the full cache, remove or replace individual entries, ...
cache.remove(&1);
let ref1d = cache.cached(1, &|v| compute_value(&10));

// The borrow checker now rejects the use of any previously returned references
// ref1.is_new();  // Does NOT compile after the call to remove

Structs

A HashMap accepting immutable insertion of new entries.

Enums

A reference provided by the cache