1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
//! This crate implements an easy way to cache values for //! a function. If you have a slow running function, this //! can be used to speed up successive runs dramatically. //! It is also quite useful for memoization of recursive //! functions, to prevent calculating the same function //! twice in different calls. //! //! Of particular note, this caching is done without //! cloning or copying, allowing functions to return //! large objects, while the cache only returns a reference //! to them instead of copying them. //! //! # Allowed functions //! This crate attempts to remain fairly flexible with //! the functions it accepts. All of the following should //! be allowed: //! * [fn][fn primitive] types. //! * [Fn] types that have no references. //! * [Fn] + 'static types that take only static references. //! * [Fn] + 'a types that take references of lifetime 'a. //! //! For obvious reasons, [FnMut] and [FnOnce] are not allowed, //! as functions need to be rerunnable and pure. //! //! # Examples //! The following example shows a recursive fibonacci //! implementation, which would be O(2ⁿ) without //! memoization (caching). With memoization, it becomes //! O(n), and can easily be calculated. //! //! ```rust //! use fn_cache::{FnCache, HashCache}; //! //! let mut cache = HashCache::<u8,u128>::new(|cache, x| //! match x { //! 0 => 0, //! 1 => 1, //! _ => *cache.get(x - 1) + *cache.get(x - 2), //! } //! ); //! //! assert_eq!( //! *cache.get(186), //! 332_825_110_087_067_562_321_196_029_789_634_457_848 //! ); //! ``` //! //! For even bigger results, the [num] crate might be employed. //! In order to avoid copying the `BigUint`s while accessing the //! cache twice, you can to change the result to be stored in an //! [Rc]. //! //! ```rust //! use std::rc::Rc; //! use fn_cache::{FnCache, HashCache}; //! use num_bigint::BigUint; //! //! let mut cache = HashCache::<u64,Rc<BigUint>>::new(|cache, x| //! match x { //! 0 => BigUint::new(vec![0]), //! 1 => BigUint::new(vec![1]), //! _ => cache.get(x - 1).clone().as_ref() //! + cache.get(x - 2).clone().as_ref(), //! }.into() //! ); //! //! assert_eq!( //! cache.get(999).clone().as_ref(), //! &BigUint::parse_bytes(b"26863810024485359386146727202142923967616609318986952340123175997617981700247881689338369654483356564191827856161443356312976673642210350324634850410377680367334151172899169723197082763985615764450078474174626", 10).unwrap() //! ); //! ``` //! //! [fn primitive]: https://doc.rust-lang.org/std/primitive.fn.html //! [Fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html //! [FnMut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html //! [FnOnce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html //! [HashCache]: struct.HashCache.html //! [Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html //! [num]: https://docs.rs/num/ mod btree_cache; mod fn_cache; mod hash_cache; mod tests; mod vec_cache; pub use crate::btree_cache::BTreeCache; pub use crate::fn_cache::FnCache; pub use crate::hash_cache::HashCache; pub use crate::vec_cache::VecCache;