### LruCache Debug Example Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Demonstrates how to use the Debug implementation to print the current length and capacity of an LruCache instance. Ensure NonZeroUsize is imported for capacity initialization. ```rust use lru::LruCache; use std::num::NonZeroUsize; let cache = LruCache::new(NonZeroUsize::new(10).unwrap()); println!("{:?}", cache); // LruCache { len: 0, cap: 10 } ``` -------------------------------- ### Rust LRU Cache: Pop Entry Example Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Demonstrates how to remove and retrieve both the key and value for a given key from the LRU cache. The key is borrowed for the operation. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put(1, "one"); assert_eq!(cache.pop_entry(&1), Some((1, "one"))); ``` -------------------------------- ### Instantiate and Use LRU Cache in Rust Source: https://github.com/jeromefroe/lru-rs/blob/master/README.md Demonstrates basic LRU cache operations including instantiation with a capacity, putting and getting key-value pairs, handling cache misses, updating values, and observing eviction. ```rust extern crate lru; use lru::LruCache; use std::num::NonZeroUsize; fn main() { let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put("apple", 3); cache.put("banana", 2); assert_eq!(*cache.get(&"apple").unwrap(), 3); assert_eq!(*cache.get(&"banana").unwrap(), 2); assert!(cache.get(&"pear").is_none()); assert_eq!(cache.put("banana", 4), Some(2)); assert_eq!(cache.put("pear", 5), None); assert_eq!(*cache.get(&"pear").unwrap(), 5); assert_eq!(*cache.get(&"banana").unwrap(), 4); assert!(cache.get(&"apple").is_none()); { let v = cache.get_mut(&"banana").unwrap(); *v = 6; } assert_eq!(*cache.get(&"banana").unwrap(), 6); } ``` -------------------------------- ### Handling Closure Errors with `try_get_or_insert` Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Shows how to handle potential errors returned by the closure passed to `try_get_or_insert`. This example demonstrates caching a successful result and handling an error. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache: LruCache = LruCache::new(NonZeroUsize::new(10).unwrap()); match cache.try_get_or_insert(1, || { if true { Ok("success".to_string()) } else { Err("failure") } }) { Ok(val) => println!("Got: {}", val), Err(e) => println!("Error: {}", e), } ``` -------------------------------- ### Owned Iteration Example Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/Iterators.md Demonstrates consuming the LRU cache using its `IntoIterator` implementation. The cache is consumed and cannot be used after this loop. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap()); cache.put("a", vec![1, 2]); cache.put("b", vec![3, 4]); cache.put("c", vec![5, 6]); // Owned iteration (consumes cache) let mut total = 0; for (_k, v) in cache { // Uses IntoIterator total += v.iter().sum::(); } // cache is now consumed and cannot be used ``` -------------------------------- ### Using `peek` to Avoid LRU Updates Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Illustrates the difference between `peek` and `get`. `peek` allows reading a value without updating its position in the LRU order, which can be faster if LRU updates are not needed. ```rust // Good: fast, doesn't update LRU order if let Some(val) = cache.peek(&key) { println!("{}", val); } // Slower: updates LRU order unnecessarily if let Some(val) = cache.get(&key) { println!("{}", val); } ``` -------------------------------- ### get Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Retrieves a reference to the value associated with a given key. Accessing a key moves it to the most recently used position in the cache. ```APIDOC ## get ### Description Returns a reference to the value for a key, moving it to the head (most recently used). ### Method Signature `pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V>` ### Parameters #### Path Parameters - **k** (&Q) - Required - Key to retrieve. Can be any type that `K` borrows as. ### Return Type `Option<&V>` - Reference to value if key exists, `None` otherwise. ### Behavior - On successful lookup: moves the entry to the head of the LRU list (marks as recently used) - Updates the LRU ordering ### Example ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put(1, "one"); cache.put(2, "two"); assert_eq!(cache.get(&1), Some(&"one")); // Entry 1 is now most recently used assert_eq!(cache.get(&99), None); ``` ``` -------------------------------- ### Insert a key-value pair and get the evicted entry Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `push` to insert a key-value pair. If the cache is full and an entry is evicted, it is returned. This operation also updates the LRU order. ```rust pub fn push(&mut self, k: K, v: V) -> Option<(K, V)> ``` -------------------------------- ### Rust LRU Cache: Pop Value Example Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Demonstrates how to remove and retrieve a value associated with a key from the LRU cache. The key is borrowed for the operation. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put("key", "value"); assert_eq!(cache.pop(&"key"), Some("value")); assert_eq!(cache.pop(&"key"), None); ``` -------------------------------- ### Configure LRU Cache without hashbrown Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/README.md Example TOML configuration for the lru crate to disable the default `hashbrown` feature. This is useful for reducing dependencies or when `hashbrown` is not desired. ```toml [dependencies] lru = { version = "0.18", default-features = false } ``` -------------------------------- ### LRU Cache Retrieval (Updates LRU) Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/INDEX.md Illustrates how to retrieve values from the cache. Accessing an item via `get`, `get_mut`, `get_key_value`, or `get_key_value_mut` updates its position in the LRU order. ```rust cache.get(&k) // Returns Option<&V> cache.get_mut(&k) // Returns Option<&mut V> cache.get_key_value(&k) // Returns Option<(&K, &V)> cache.get_key_value_mut(&k) // Returns Option<(&K, &mut V)> ``` -------------------------------- ### Get or insert a value, creating it if it doesn't exist Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `get_or_insert` to retrieve a value by key. If the key is not present, a new value is created using the provided closure and inserted into the cache. Returns a reference to the value. ```rust pub fn get_or_insert(&mut self, k: K, f: F) -> &V where F: FnOnce() -> V ``` -------------------------------- ### Insert or Get Value Using Key in LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Use `get_or_insert_with_key` when the default value needs to be computed based on the key itself. The provided closure receives a reference to the key. Existing keys are moved to the head of the cache. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); // Closure receives the key let val = cache.get_or_insert_with_key("apple", |k| k.len()); assert_eq!(val, &5); ``` -------------------------------- ### Function Memoization with LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Implement function memoization using an LRU cache to store results of expensive function calls. The `fibonacci` function is used as an example, caching results to avoid redundant computations. ```rust use lru::LruCache; use std::num::NonZeroUsize; fn fibonacci(n: u32, cache: &mut LruCache) -> u64 { if n <= 1 { return n as u64; } cache.get_or_insert_with_key(n, |&n| { fibonacci(n - 1, cache) + fibonacci(n - 2, cache) }).clone() } fn main() { let mut cache = LruCache::new(NonZeroUsize::new(50).unwrap()); for i in 0..20 { let result = fibonacci(i, &mut cache); println!("fib({})", i, result); } } ``` -------------------------------- ### Get or insert a value using a key-dependent closure Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `get_or_insert_with_key` to retrieve a value by key. If the key is not present, a new value is created using a closure that takes the key as an argument. Returns a reference to the value. ```rust pub fn get_or_insert_with_key(&mut self, k: K, f: F) -> &V where F: FnOnce(&K) -> V ``` -------------------------------- ### Insert or Get Default Value in LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Use `get_or_insert` to retrieve a value by key, inserting a default generated by a closure if the key is not present. The closure is only called if the key is missing. Existing keys are moved to the head of the cache. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); // Key doesn't exist, calls closure let val = cache.get_or_insert(1, || "default"); assert_eq!(val, &"default"); // Key exists, closure is not called let val = cache.get_or_insert(1, || "ignored"); assert_eq!(val, &"default"); ``` -------------------------------- ### Insert or Get Value with Borrowed Key in LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Use `get_or_insert_ref` to retrieve a value using a borrowed key, avoiding unnecessary key cloning if the key already exists. The key is only cloned if it needs to be inserted. This is useful for keys that are expensive to clone. ```rust use lru::LruCache; use std::num::NonZeroUsize; use std::rc::Rc; let key1 = Rc::new("key1".to_string()); let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); // First call: key is cloned and inserted assert_eq!(cache.get_or_insert_ref(&key1, || "value1"), "value1"); // Second call: key is NOT cloned again assert_eq!(cache.get_or_insert_ref(&key1, || "ignored"), "value1"); assert_eq!(Rc::strong_count(&key1), 2); // key was only cloned once ``` -------------------------------- ### Choosing LRU Cache Capacity Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Demonstrates how to initialize an LRU cache with different capacities. Select a capacity that balances hit rate and memory usage. ```rust use lru::LruCache; use std::num::NonZeroUsize; // Too small: frequent evictions let small_cache = LruCache::new(NonZeroUsize::new(10).unwrap()); // Too large: waste memory let large_cache = LruCache::new(NonZeroUsize::new(1_000_000).unwrap()); // Right-sized: balance hit rate vs memory let good_cache = LruCache::new(NonZeroUsize::new(10_000).unwrap()); ``` -------------------------------- ### Get a value from the LruCache by key Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `get` to retrieve a reference to the value associated with a key. This operation updates the LRU order for the accessed key. ```rust pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V> where K: Borrow, Q: Hash + Eq + ?Sized ``` -------------------------------- ### Insert or Get Mutable Reference in LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Use `get_or_insert_mut` to get a mutable reference to a value, inserting a default if the key is missing. The closure is called only if the key does not exist. This method allows in-place modification of cache values. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); let v = cache.get_or_insert_mut(1, || vec![]); v.push(42); let v = cache.get_or_insert_mut(1, || vec![]); assert_eq!(v, &vec![42]); ``` -------------------------------- ### Get the capacity of the LRU cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Returns the maximum number of entries the cache can hold. ```rust pub fn cap(&self) -> NonZeroUsize ``` -------------------------------- ### Basic LRU Cache Operations Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Demonstrates creating an LRU cache with a specified capacity, inserting key-value pairs, retrieving values, checking for membership, and removing items. ```rust use lru::LruCache; use std::num::NonZeroUsize; fn main() { // Create a cache that holds up to 10 items let mut cache: LruCache = LruCache::new(NonZeroUsize::new(10).unwrap()); // Insert items cache.put("apple".to_string(), 42); cache.put("banana".to_string(), 123); // Retrieve items match cache.get(&"apple") { Some(val) => println!("Found: {}", val), None => println!("Not found"), } // Check membership if cache.contains(&"cherry") { println!("Cherry exists"); } // Remove items if let Some(val) = cache.pop(&"apple") { println!("Removed: {}", val); } } ``` -------------------------------- ### Get the number of entries in the LRU cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Returns the current number of items stored in the cache. ```rust pub fn len(&self) -> usize ``` -------------------------------- ### LRU Cache Construction Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/INDEX.md Demonstrates various ways to construct an LRU cache, including bounded, unbounded, and with custom hashers. ```rust LruCache::new(cap) // Bounded cache LruCache::unbounded() // Unbounded cache LruCache::with_hasher(cap, builder) // Custom hasher LruCache::unbounded_with_hasher(builder) // Custom hasher, unbounded ``` -------------------------------- ### Inspecting the Next Eviction Candidate Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Shows how to use `peek_lru()` to view the least-recently-used item that will be evicted next if a new item is inserted. This allows for inspection without modifying the cache state. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put(1, "a"); cache.put(2, "b"); // See what's next to be evicted if let Some((key, val)) = cache.peek_lru() { println!("About to evict: {} -> {}", key, val); } // Actually insert and trigger eviction cache.put(3, "c"); // Confirm it was evicted assert!(!cache.contains(&1)); ``` -------------------------------- ### Get Current Cache Size Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Returns the number of key-value pairs currently stored in the cache. This is useful for monitoring cache usage. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); assert_eq!(cache.len(), 0); cache.put(1, "a"); assert_eq!(cache.len(), 1); cache.put(2, "b"); assert_eq!(cache.len(), 2); cache.put(3, "c"); // Evicts entry 1 assert_eq!(cache.len(), 2); ``` -------------------------------- ### new Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Creates a new bounded LRU cache with the specified capacity. Entries are ordered by recency, and the least recently used entry is evicted when capacity is reached. ```APIDOC ## new ### Description Creates a new bounded LRU cache with the specified capacity. Entries are ordered by recency, and the least recently used entry is evicted when capacity is reached. ### Method `new` ### Parameters #### Path Parameters - `cap` (NonZeroUsize) - Required - Maximum number of entries the cache can hold ### Return Type `LruCache` ### Example ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache: LruCache<&str, i32> = LruCache::new(NonZeroUsize::new(10).unwrap()); cache.put("key1", 42); ``` ``` -------------------------------- ### Get an iterator over mutable references to cache entries Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Returns an iterator that yields mutable references to the key-value pairs in the cache. The order is not guaranteed. ```rust pub fn iter_mut(&mut self) -> IterMut<'_, K, V> ``` -------------------------------- ### promote Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Promotes an existing entry to the front of the cache. Returns true if the key was found and promoted, false otherwise. ```APIDOC ## promote ### Description Promotes an existing entry to the front of the cache. Returns true if the key was found and promoted, false otherwise. ### Method Signature ```rust pub fn promote(&mut self, k: &Q) -> bool where K: Borrow, Q: Hash + Eq + ?Sized ``` ### Parameters - `k: &Q` — Key to promote ### Return - `bool` — `true` if promoted, `false` if not found ``` -------------------------------- ### Get an iterator over immutable references to cache entries Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Returns an iterator that yields immutable references to the key-value pairs in the cache. The order is not guaranteed. ```rust pub fn iter(&self) -> Iter<'_, K, V> ``` -------------------------------- ### Create a new LruCache with a specific capacity Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `new` to create an LruCache with a fixed capacity. The capacity must be a non-zero value. ```rust pub fn new(cap: NonZeroUsize) -> LruCache where K: Hash + Eq ``` -------------------------------- ### Get-or-Insert Methods Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Methods for retrieving a value for a key, or inserting a new value if the key does not exist. ```APIDOC ## get_or_insert ### Description Retrieves a reference to the value for the given key. If the key does not exist, it inserts a new value computed by the provided closure and returns a reference to the newly inserted value. ### Signature ```rust pub fn get_or_insert(&mut self, k: K, f: F) -> &V where F: FnOnce() -> V ``` ### Type Parameters - `K`: Must implement `Hash` and `Eq`. - `V` - `S`: Must implement `BuildHasher`. - `F`: A closure that takes no arguments and returns a value of type `V`. ### Parameters - `k` (K): The key to look up or insert. - `f` (F): A closure that returns the default value to insert if the key is not found. ### Return - `&V`: A reference to the value associated with the key. The lifetime is tied to the cache instance. ``` ```APIDOC ## get_or_insert_with_key ### Description Retrieves a reference to the value for the given key. If the key does not exist, it inserts a new value computed by the provided closure (which receives a reference to the key) and returns a reference to the newly inserted value. ### Signature ```rust pub fn get_or_insert_with_key(&mut self, k: K, f: F) -> &V where F: FnOnce(&K) -> V ``` ### Type Parameters - `K`: Must implement `Hash` and `Eq`. - `V` - `S`: Must implement `BuildHasher`. - `F`: A closure that takes a reference to the key (`&K`) and returns a value of type `V`. ### Parameters - `k` (K): The key to look up or insert. - `f` (F): A closure that takes a reference to the key and returns the default value to insert if the key is not found. ### Return - `&V`: A reference to the value associated with the key. The lifetime is tied to the cache instance. ``` -------------------------------- ### Get the key-value pair from the LruCache by key Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `get_key_value` to retrieve references to both the key and the value associated with a given key. This operation updates the LRU order. ```rust pub fn get_key_value<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a V)> where K: Borrow, Q: Hash + Eq + ?Sized ``` -------------------------------- ### Get or Insert a Value Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/README.md Retrieve a value from the cache by key, or insert a default value if the key is not present. The default value is computed lazily using a closure. ```rust // Insert default if key is missing let val = cache.get_or_insert("key", || "default"); // Using key in the computation let val = cache.get_or_insert_with_key("hello", |k| k.len()); ``` -------------------------------- ### Create a Bounded Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/README.md Instantiate a new LRU cache with a specified capacity. The cache will automatically evict the least recently used entry when the capacity is reached. Ensure the capacity is a non-zero value. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache: LruCache> = LruCache::new(NonZeroUsize::new(100).unwrap()); ``` -------------------------------- ### Batch Operations with LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Shows how to perform batch insertions using `put` or iterate over cache contents efficiently. Batching operations can improve performance compared to individual calls. ```rust // Instead of multiple put/get calls, batch them for (k, v) in batch_data { cache.put(k, v); } // Or iterate once instead of multiple lookups for (k, v) in cache.iter() { process(k, v); } ``` -------------------------------- ### Create a new bounded LruCache with a custom hasher Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Use this to create a new LRU cache with a specified capacity and a custom hash builder for key hashing. ```rust use lru::{LruCache, DefaultHasher}; use std::num::NonZeroUsize; let s = DefaultHasher::default(); let mut cache: LruCache = LruCache::with_hasher(NonZeroUsize::new(100).unwrap(), s); ``` -------------------------------- ### Get a mutable reference to a value in the LruCache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `get_mut` to retrieve a mutable reference to the value associated with a key. This operation updates the LRU order for the accessed key. ```rust pub fn get_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V> where K: Borrow, Q: Hash + Eq + ?Sized ``` -------------------------------- ### Lifetime Rules Summary Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Explanation of lifetime rules and borrow checker implications for LruCache. ```APIDOC ## Lifetime Rules - References returned from `get()`, `get_mut()`, etc. are tied to `self`'s mutability lifetime - The cache cannot be modified while references to entries exist (Rust's borrow checker enforces this) - Iterators hold immutable/mutable borrows preventing concurrent mutations ``` -------------------------------- ### Iterate Over LruCache Entries (Immutable) Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/types.md Use `iter()` to get an immutable iterator over cache entries in MRU to LRU order. This is suitable for read-only access to cache contents. ```rust use std::num::NonZeroUsize; use lru::LruCache; let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap()); cache.put(1, "a"); cache.put(2, "b"); for (k, v) in cache.iter() { println!("{}: {}", k, v); } // Or use methods directly let mut iter = cache.iter(); assert_eq!(iter.next(), Some((&2, &"b"))); assert_eq!(iter.next_back(), Some((&1, &"a"))); ``` -------------------------------- ### Create an Unbounded LruCache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/types.md Instantiate an `LruCache` without a capacity limit. Use this when the cache size is not a concern or should grow dynamically. ```rust use lru::LruCache; // Unbounded cache let cache: LruCache = LruCache::unbounded(); ``` -------------------------------- ### Using `get_or_insert` for Expensive Operations Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Compares a naive approach that might compute values multiple times with the efficient `get_or_insert` method, which computes the value only once. This is useful for caching results of expensive computations. ```rust // Bad: might compute multiple times if !cache.contains(&key) { let value = expensive_computation(&key); cache.put(key.clone(), value); } let value = cache.get(&key).unwrap(); // Good: computes only once let value = cache.get_or_insert(key.clone(), || expensive_computation(&key)); ``` -------------------------------- ### Get a mutable key-value pair from the LruCache by key Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `get_key_value_mut` to retrieve mutable references to both the key and the value associated with a given key. This operation updates the LRU order. ```rust pub fn get_key_value_mut<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a mut V)> where K: Borrow, Q: Hash + Eq + ?Sized ``` -------------------------------- ### Create an LruCache with a specific capacity and custom hasher Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `with_hasher` to create an LruCache with a specified capacity and a custom hash builder. This allows for more control over hashing behavior. ```rust pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache where K: Hash + Eq, S: BuildHasher ``` -------------------------------- ### Create an LruCache with a Custom Hasher Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/types.md Instantiate an `LruCache` with a custom hash builder. This allows for specialized hashing strategies, potentially improving performance or handling specific key types. ```rust use std::num::NonZeroUsize; use lru::{DefaultHasher, LruCache}; // With custom hasher let hasher = DefaultHasher::default(); let cache: LruCache<&str, f64> = LruCache::with_hasher( NonZeroUsize::new(50).unwrap(), hasher ); ``` -------------------------------- ### Rust LRU Cache: Pop Least Recently Used Example Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Demonstrates how to remove and retrieve the least recently used key-value pair from the cache. This operation does not require a key. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put(1, "a"); cache.put(2, "b"); cache.get(&1); // Make 1 most recently used assert_eq!(cache.pop_lru(), Some((2, "b"))); // 2 is LRU assert_eq!(cache.pop_lru(), Some((1, "a"))); assert_eq!(cache.pop_lru(), None); ``` -------------------------------- ### Get or Insert Mutable with Key Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Retrieves a mutable reference to a value associated with a key. If the key is not present, it computes a default value using a closure that takes the key and inserts it into the cache. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); let v = cache.get_or_insert_mut_with_key("hello", |k| k.len()); assert_eq!(v, &5); *v = 10; ``` -------------------------------- ### DNS Cache Implementation Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Create a DNS cache using `LruCache` to store domain name to IP address mappings. It resolves DNS entries only when they are not present in the cache. ```rust use lru::LruCache; use std::num::NonZeroUsize; type IpAddr = String; // Simplified let mut dns_cache: LruCache = LruCache::new(NonZeroUsize::new(1000).unwrap()); fn resolve_dns(domain: &str) -> Result { // Simulate DNS lookup Ok(format!("192.168.1.1{}", domain.len())) } fn lookup(domain: &str) -> Result { dns_cache.get_or_insert_ref(domain, || { resolve_dns(domain).unwrap_or_else(|_| "0.0.0.0".to_string()) }); Ok(dns_cache.peek(&domain.to_string()).unwrap().clone()) } ``` -------------------------------- ### Inspecting LRU Cache State Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Demonstrates how to inspect the internal state of an LRU cache using `println!("{:?}", cache)` and methods like `len()`, `cap()`, `peek_lru()`, and `peek_mru()`. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(10).unwrap()); cache.put(1, "a"); cache.put(2, "b"); cache.put(3, "c"); // Print debug representation println!("{:?}", cache); // LruCache { len: 3, cap: 10 } // Check size println!("Entries: {}", cache.len()); println!("Capacity: {}", cache.cap().get()); // View eviction order if let Some((lru_key, _)) = cache.peek_lru() { println!("Next to evict: {:?}", lru_key); } if let Some((mru_key, _)) = cache.peek_mru() { println!("Most recent: {:?}", mru_key); } ``` -------------------------------- ### Create a Bounded LruCache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/types.md Instantiate a new `LruCache` with a specified capacity. This is useful for managing a fixed-size cache. ```rust use std::num::NonZeroUsize; use lru::LruCache; // Simple bounded cache let cache: LruCache> = LruCache::new(NonZeroUsize::new(100).unwrap()); ``` -------------------------------- ### LruCache Constructor Methods Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Methods for creating new instances of LruCache. ```APIDOC ## new ### Description Creates a new LruCache with a specified capacity. ### Signature ```rust pub fn new(cap: NonZeroUsize) -> LruCache where K: Hash + Eq ``` ### Type Parameters - `K`: Must implement `Hash` and `Eq`. - `V` ### Parameters - `cap` (NonZeroUsize): The capacity of the cache. ``` ```APIDOC ## unbounded ### Description Creates a new LruCache with no capacity limit. ### Signature ```rust pub fn unbounded() -> LruCache where K: Hash + Eq ``` ### Type Parameters - `K`: Must implement `Hash` and `Eq`. - `V` ### Parameters None. ``` ```APIDOC ## with_hasher ### Description Creates a new LruCache with a specified capacity and a custom hash builder. ### Signature ```rust pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache where K: Hash + Eq, S: BuildHasher ``` ### Type Parameters - `K`: Must implement `Hash` and `Eq`. - `V` - `S`: Must implement `BuildHasher`. ### Parameters - `cap` (NonZeroUsize): The capacity of the cache. - `hash_builder` (S): The hash builder instance to use. ``` ```APIDOC ## unbounded_with_hasher ### Description Creates a new LruCache with no capacity limit and a custom hash builder. ### Signature ```rust pub fn unbounded_with_hasher(hash_builder: S) -> LruCache where K: Hash + Eq, S: BuildHasher ``` ### Type Parameters - `K`: Must implement `Hash` and `Eq`. - `V` - `S`: Must implement `BuildHasher`. ### Parameters - `hash_builder` (S): The hash builder instance to use. ``` -------------------------------- ### Peek at the most recently used entry in the LruCache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `peek_mru` to get references to the key and value of the most recently used entry without removing it or changing its position. This is useful for inspecting the most recently accessed item. ```rust pub fn peek_mru(&self) -> Option<(&K, &V)> ``` -------------------------------- ### Reorder Entries in LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/INDEX.md Shows how to reorder entries within the cache. `promote` moves an entry to the most recently used position (head), while `demote` moves it to the least recently used position (tail). ```rust cache.promote(&k) // Move to head (MRU) cache.demote(&k) // Move to tail (LRU) ``` -------------------------------- ### Create an Unbounded Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/README.md Create an LRU cache that can grow indefinitely. Entries will only be removed through manual eviction. ```rust let mut cache: LruCache = LruCache::unbounded(); ``` -------------------------------- ### LRU Cache Get-or-Insert Operations Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/INDEX.md Demonstrates methods for retrieving a value if it exists, or inserting a new value if it doesn't. Variants exist for different insertion strategies (by-key, by-ref, mutable) and whether the closure is fallible. ```rust cache.get_or_insert(k, || v) // Fallible: no cache.get_or_insert_with_key(k, |k| v) // By-key: yes cache.get_or_insert_ref(&k, || v) // By-ref: yes cache.get_or_insert_mut(k, || v) // Mutable: yes // ... and with_key and _ref variants ``` -------------------------------- ### Implement Clone for LruCache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Allows creating a deep copy of the LRU cache. Requires keys, values, and the build hasher to be cloneable. ```rust impl Clone for LruCache where K: Hash + PartialEq + Eq + Clone, V: Clone, S: BuildHasher + Clone, { fn clone(&self) -> Self } ``` -------------------------------- ### promote Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Marks a key as the most recently used, moving it to the head of the cache. Returns `true` if the key existed and was promoted, `false` otherwise. ```APIDOC ## promote ### Description Marks a key as the most recently used, moving it to the head. ### Method `promote(&mut self, k: &Q) -> bool` ### Parameters #### Path Parameters - **k** (`&Q`) - Required - Key to promote ### Return Type `bool` — `true` if key existed and was promoted, `false` otherwise ### Behavior - If key exists: moves it to the head (most recently used position) - If key does not exist: returns `false` without modifying the cache ### Example ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap()); cache.put(1, "a"); cache.put(2, "b"); cache.put(3, "c"); // Promote 1 to the head assert!(cache.promote(&1)); // Now 1 is most recently used assert_eq!(cache.pop_lru(), Some((2, "b"))); // 2 is now LRU // Non-existent key returns false assert!(!cache.promote(&99)); ``` ``` -------------------------------- ### Peek at the least recently used entry in the LruCache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `peek_lru` to get references to the key and value of the least recently used entry without removing it or changing its position. This is useful for understanding cache eviction candidates. ```rust pub fn peek_lru(&self) -> Option<(&K, &V)> ``` -------------------------------- ### Unbounded LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Shows how to create an LRU cache that does not evict entries, useful when memory is not a concern or when you want to keep all inserted items. ```rust let mut cache: LruCache = LruCache::unbounded(); for i in 0..1_000_000 { cache.put(i, format!("value_{}", i)); } // No entries are evicted ``` -------------------------------- ### Try Get or Insert with Fallible Closure Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Attempts to retrieve a reference to a value. If the key is not present, it attempts to insert a new value computed by a closure. The operation can fail, returning an error without modifying the cache if the closure returns an error. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); // Success case let result = cache.try_get_or_insert(1, || Ok::<_, &str>("value")); assert_eq!(result, Ok(&"value")); // Failure case let result = cache.try_get_or_insert(2, || Err::<&str, _>("failed")); assert_eq!(result, Err("failed")); assert!(!cache.contains(&2)); // Entry was not inserted ``` -------------------------------- ### Generic Type Parameter Constraints Summary Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Summary of generic type parameter constraints for various LruCache methods. ```APIDOC ## Generic Type Parameter Constraints - **Most methods:** `K: Hash + Eq` - **Lookup methods:** `K: Borrow` where `Q: Hash + Eq + ?Sized` - **Cloning:** All of `K`, `V`, `S` must be `Clone` - **Thread-safety:** All of `K`, `V`, `S` must be `Send`/`Sync` respectively ``` -------------------------------- ### Fallible Get or Insert Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/README.md Attempt to retrieve or insert a value, executing a fallible closure to load the data. If the closure returns an error, the error is propagated, and the failed attempt is not cached. This is useful for operations that might fail, like disk I/O. ```rust fn load_data(key: &str) -> Result { // Try to load from disk/network if key == "valid" { Ok("data".to_string()) } else { Err("not found".to_string()) } } // Returns Err if load_data fails; does not cache the failed attempt match cache.try_get_or_insert("valid", || load_data("valid")) { Ok(val) => println!("Cached: {}", val), Err(e) => println!("Failed: {}", e), } ``` -------------------------------- ### Peek at a value in the LruCache without updating LRU order Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `peek` to get an immutable reference to a value associated with a key without affecting the cache's LRU order. This is useful for inspecting values without triggering eviction logic. ```rust pub fn peek<'a, Q>(&'a self, k: &Q) -> Option<&'a V> where K: Borrow, Q: Hash + Eq + ?Sized ``` -------------------------------- ### Compute-Once-Cache Pattern with `get_or_insert` Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/Usage Guide.md Illustrates caching the result of an expensive computation. The computation is performed only on the first call for a given key; subsequent calls retrieve the cached value. ```rust use lru::LruCache; use std::num::NonZeroUsize; fn expensive_computation(n: i32) -> String { println!("Computing..."); format!("Result of computing {}", n) } fn main() { let mut cache = LruCache::new(NonZeroUsize::new(10).unwrap()); // First call: computes and caches let result1 = cache.get_or_insert(1, || expensive_computation(1)); println!("{}", result1); // Second call: uses cached value, closure not called let result2 = cache.get_or_insert(1, || expensive_computation(1)); println!("{}", result2); } ``` -------------------------------- ### Remove Entries from LRU Cache Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/INDEX.md Demonstrates methods for removing entries from the cache. Use `pop` for a specific key, `pop_entry` to get the key-value pair, `pop_lru` to remove the least recently used item, and `pop_mru` to remove the most recently used item. ```rust cache.pop(&k) // Returns Option cache.pop_entry(&k) // Returns Option<(K, V)> cache.pop_lru() // Returns Option<(K, V)> cache.pop_mru() // Returns Option<(K, V)> ``` -------------------------------- ### get_or_insert_with_key Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Similar to `get_or_insert`, but the provided closure receives the key itself as an argument, allowing for dynamic computation of the default value based on the key. ```APIDOC ## get_or_insert_with_key ### Description Returns a reference to the value for a key, using the key to compute the default if missing. The closure receives a reference to the key. ### Method Signature `pub fn get_or_insert_with_key(&mut self, k: K, f: F) -> &V where F: FnOnce(&K) -> V` ### Parameters #### Path Parameters - **k** (K) - Required - Key to retrieve or insert. - **f** (F) - Required - Closure that takes the key and returns a value. ### Return Type `&V` - Reference to the value. ### Behavior - If key exists: returns reference to existing value (moves to head). - If key does not exist: calls `f(&k)` with a reference to the key, uses result as value. ### Example ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); // Closure receives the key let val = cache.get_or_insert_with_key("apple", |k| k.len()); assert_eq!(val, &5); ``` ``` -------------------------------- ### Get Mutable Reference to Value and Key Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/LruCache.md Retrieves a mutable reference to a value and an immutable reference to its key. This operation moves the accessed entry to the head of the LRU list. Use this when you need to modify a value and potentially use its key, while also marking it as recently used. ```rust use lru::LruCache; use std::num::NonZeroUsize; let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap()); cache.put(1, "a"); if let Some((k, v)) = cache.get_key_value_mut(&1) { println!("key: {}, old value: {}", k, v); *v = "b"; } assert_eq!(cache.get(&1), Some(&"b")); ``` -------------------------------- ### Explicit and Implicit DefaultHasher Usage Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/types.md Demonstrates how to explicitly create a DefaultHasher instance for an LruCache or rely on the implicit default when the hasher type parameter is omitted. ```rust use lru::{LruCache, DefaultHasher}; use std::num::NonZeroUsize; // Explicit usage let hasher = DefaultHasher::default(); let mut cache: LruCache = LruCache::with_hasher(NonZeroUsize::new(100).unwrap(), hasher); // Or implicitly by not specifying the third generic parameter let mut cache: LruCache = LruCache::new(NonZeroUsize::new(100).unwrap()); ``` -------------------------------- ### Peek at a mutable value in the LruCache without updating LRU order Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/api-reference/MethodSignatures.md Use `peek_mut` to get a mutable reference to a value associated with a key without affecting the cache's LRU order. This allows modification of values without changing their position in the LRU list. ```rust pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V> where K: Borrow, Q: Hash + Eq + ?Sized ``` -------------------------------- ### Create LRU Cache with Custom Hash Builder Source: https://github.com/jeromefroe/lru-rs/blob/master/_autodocs/README.md Initialize an LruCache using a custom hasher, such as DefaultHasher, for specific hashing needs. This allows for more control over how keys are hashed. ```rust use lru::{LruCache, DefaultHasher}; use std::num::NonZeroUsize; let hasher = DefaultHasher::default(); let mut cache: LruCache = LruCache::with_hasher(NonZeroUsize::new(50).unwrap(), hasher); cache.put("key".to_string(), 10); assert_eq!(cache.get(&"key"), Some(&10)); ```