### Install Mini Moka dependency Source: https://context7.com/moka-rs/mini-moka/llms.txt Add the library to your Cargo.toml file. ```toml [dependencies] mini_moka = "0.10" ``` -------------------------------- ### Use unsync::Cache for single-threaded performance Source: https://context7.com/moka-rs/mini-moka/llms.txt Implement a non-thread-safe cache for single-threaded applications. Note that get() returns a reference rather than a clone. ```rust use mini_moka::unsync::Cache; fn main() { // Create cache with max 1000 entries let mut cache: Cache = Cache::new(1000); // Insert entries cache.insert(1, "one".to_string()); cache.insert(2, "two".to_string()); cache.insert(3, "three".to_string()); // get() returns Option<&V> (reference, not clone) assert_eq!(cache.get(&1), Some(&"one".to_string())); // Check existence assert!(cache.contains_key(&2)); // Remove and return value let removed = cache.remove(&3); assert_eq!(removed, Some("three".to_string())); // Invalidate without returning value cache.invalidate(&2); // Iterate over entries for (key, value) in cache.iter() { println!("{}: {}", key, value); } // Conditional invalidation cache.insert(10, "ten".to_string()); cache.insert(20, "twenty".to_string()); cache.invalidate_entries_if(|k, _v| *k > 5); // Clear all cache.invalidate_all(); } ``` -------------------------------- ### Run All Tests in Mini Moka Source: https://github.com/moka-rs/mini-moka/blob/v0.11.x/README.md Execute all tests, including doc tests, by running this command in the project directory. It uses RUSTFLAGS to enable specific configurations for testing. ```bash $ RUSTFLAGS='--cfg trybuild' cargo test --all-features ``` -------------------------------- ### Generate Documentation for Mini Moka Source: https://github.com/moka-rs/mini-moka/blob/v0.11.x/README.md Generate documentation for the Mini Moka project, including doc tests, using Cargo with nightly and specific unstable features enabled. ```bash $ cargo +nightly -Z unstable-options --config 'build.rustdocflags="--cfg docsrs"' \ doc --no-deps ``` -------------------------------- ### Configure Cache with CacheBuilder Source: https://context7.com/moka-rs/mini-moka/llms.txt Use the builder pattern to set capacity and expiration policies like TTL and TTI. ```rust use mini_moka::sync::Cache; use std::time::Duration; fn main() { let cache: Cache = Cache::builder() // Maximum number of entries .max_capacity(10_000) // Initial capacity hint for the internal hash map .initial_capacity(100) // Time to live: expire 30 minutes after insert .time_to_live(Duration::from_secs(30 * 60)) // Time to idle: expire 5 minutes after last access .time_to_idle(Duration::from_secs(5 * 60)) .build(); // Entry expires after 5 minutes of no access (TTI) cache.insert("session:abc".to_string(), "user_data".to_string()); // get() resets the idle timer let _ = cache.get(&"session:abc".to_string()); // Entry will still expire 30 minutes after insert (TTL) // regardless of get() calls } ``` -------------------------------- ### Multi-Threaded Cache Access in Rust Source: https://context7.com/moka-rs/mini-moka/llms.txt Demonstrates concurrent insertion, reading, and invalidation of cache entries from multiple threads using `mini_moka::sync::Cache`. Ensure `mini_moka` is added as a dependency. ```rust use mini_moka::sync::Cache; use std::thread; fn main() { const NUM_THREADS: usize = 16; const NUM_KEYS_PER_THREAD: usize = 64; let cache: Cache = Cache::new(10_000); let threads: Vec<_> = (0..NUM_THREADS) .map(|i| { let my_cache = cache.clone(); let start = i * NUM_KEYS_PER_THREAD; let end = (i + 1) * NUM_KEYS_PER_THREAD; thread::spawn(move || { // Insert entries for key in start..end { my_cache.insert(key, format!("value {{}}", key)); } // Read and verify for key in start..end { assert_eq!( my_cache.get(&key), Some(format!("value {{}}", key)) ); } // Invalidate some entries for key in (start..end).step_by(4) { my_cache.invalidate(&key); } }) }) .collect(); // Wait for all threads for t in threads { t.join().expect("Thread panicked"); } // Verify results for key in 0..(NUM_THREADS * NUM_KEYS_PER_THREAD) { if key % 4 == 0 { assert_eq!(cache.get(&key), None); } else { assert_eq!(cache.get(&key), Some(format!("value {{}}", key))); } } println!("All threads completed successfully"); } ``` -------------------------------- ### Implement Custom Hasher Source: https://context7.com/moka-rs/mini-moka/llms.txt Provide a custom hasher to the cache builder to optimize performance for specific key types. ```rust use mini_moka::sync::Cache; use std::collections::hash_map::RandomState; fn main() { // Using custom hasher (e.g., ahash for better performance) // let hasher = ahash::RandomState::new(); // Example with default RandomState let hasher = RandomState::new(); let cache: Cache = Cache::builder() .max_capacity(1000) .build_with_hasher(hasher); cache.insert(42, "answer".to_string()); assert_eq!(cache.get(&42), Some("answer".to_string())); } ``` -------------------------------- ### Configure size-aware eviction with a weigher Source: https://github.com/moka-rs/mini-moka/blob/v0.11.x/README.md Uses a weigher closure to define entry weights, allowing the cache to evict based on total weighted size rather than entry count. ```rust use std::convert::TryInto; use mini_moka::sync::Cache; fn main() { let cache = Cache::builder() // A weigher closure takes &K and &V and returns a u32 representing the // relative size of the entry. Here, we use the byte length of the value // String as the size. .weigher(|_key, value: &String| -> u32 { value.len().try_into().unwrap_or(u32::MAX) }) // This cache will hold up to 32MiB of values. .max_capacity(32 * 1024 * 1024) .build(); cache.insert(0, "zero".to_string()); } ``` -------------------------------- ### Configure Size-Aware Eviction with Weigher Source: https://context7.com/moka-rs/mini-moka/llms.txt Use a weigher to bound cache capacity by total weighted size rather than entry count. The weigher function must return a u32 representing the relative size of the entry. ```rust use mini_moka::sync::Cache; use std::convert::TryInto; fn main() { // Cache bounded by total byte size of values let cache: Cache> = Cache::builder() // Weigher returns relative size as u32 .weigher(|_key, value: &Vec| -> u32 { value.len().try_into().unwrap_or(u32::MAX) }) // Maximum 32 MiB of data .max_capacity(32 * 1024 * 1024) .build(); // Small entry (100 bytes) cache.insert("small".to_string(), vec![0u8; 100]); // Large entry (1 MiB) cache.insert("large".to_string(), vec![0u8; 1024 * 1024]); // Cache evicts entries when total weighted size exceeds max_capacity println!("Weighted size: {} bytes", cache.weighted_size()); } ``` -------------------------------- ### Inspect Cache Policy Configuration Source: https://context7.com/moka-rs/mini-moka/llms.txt Retrieve read-only access to the cache's current configuration settings like TTL, TTI, and capacity. ```rust use mini_moka::sync::Cache; use std::time::Duration; fn main() { let cache: Cache = Cache::builder() .max_capacity(5000) .time_to_live(Duration::from_secs(3600)) .time_to_idle(Duration::from_secs(600)) .build(); let policy = cache.policy(); println!("Max capacity: {:?}", policy.max_capacity()); // Some(5000) println!("TTL: {:?}", policy.time_to_live()); // Some(3600s) println!("TTI: {:?}", policy.time_to_idle()); // Some(600s) } ``` -------------------------------- ### Use sync::Cache for thread-safe operations Source: https://context7.com/moka-rs/mini-moka/llms.txt Utilize the thread-safe cache implementation for multi-threaded environments. Clone is cheap as it creates reference-counted pointers. ```rust use mini_moka::sync::Cache; use std::thread; fn main() { // Create a cache that can store up to 10,000 entries let cache: Cache = Cache::new(10_000); // Clone is cheap - creates reference-counted pointers let cache_clone = cache.clone(); // Use from multiple threads let handle = thread::spawn(move || { cache_clone.insert("user:1001".to_string(), "Alice".to_string()); cache_clone.insert("user:1002".to_string(), "Bob".to_string()); }); handle.join().unwrap(); // get() returns Option, a clone of the stored value assert_eq!(cache.get(&"user:1001".to_string()), Some("Alice".to_string())); // Check if key exists without cloning value assert!(cache.contains_key(&"user:1001".to_string())); // Invalidate specific entry cache.invalidate(&"user:1002".to_string()); assert_eq!(cache.get(&"user:1002".to_string()), None); // Clear all entries cache.invalidate_all(); println!("Entry count: {}", cache.entry_count()); println!("Weighted size: {}", cache.weighted_size()); } ``` -------------------------------- ### Perform multi-threaded cache operations Source: https://github.com/moka-rs/mini-moka/blob/v0.11.x/README.md Demonstrates cloning a cache for use across multiple threads to perform concurrent insertions and invalidations. ```rust // Use the synchronous cache. use mini_moka::sync::Cache; use std::thread; fn value(n: usize) -> String { format!("value {}", n) } fn main() { const NUM_THREADS: usize = 16; const NUM_KEYS_PER_THREAD: usize = 64; // Create a cache that can store up to 10,000 entries. let cache = Cache::new(10_000); // Spawn threads and read and update the cache simultaneously. let threads: Vec<_> = (0..NUM_THREADS) .map(|i| { // To share the same cache across the threads, clone it. // This is a cheap operation. let my_cache = cache.clone(); let start = i * NUM_KEYS_PER_THREAD; let end = (i + 1) * NUM_KEYS_PER_THREAD; thread::spawn(move || { // Insert 64 entries. (NUM_KEYS_PER_THREAD = 64) for key in start..end { my_cache.insert(key, value(key)); // get() returns Option, a clone of the stored value. assert_eq!(my_cache.get(&key), Some(value(key))); } // Invalidate every 4 element of the inserted entries. for key in (start..end).step_by(4) { my_cache.invalidate(&key); } }) }) .collect(); // Wait for all threads to complete. threads.into_iter().for_each(|t| t.join().expect("Failed")); // Verify the result. for key in 0..(NUM_THREADS * NUM_KEYS_PER_THREAD) { if key % 4 == 0 { assert_eq!(cache.get(&key), None); } else { assert_eq!(cache.get(&key), Some(value(key))); } } } ``` -------------------------------- ### Optimize large value storage with Arc Source: https://github.com/moka-rs/mini-moka/blob/v0.11.x/README.md Wraps large values in std::sync::Arc to avoid expensive cloning during cache retrieval. ```rust use std::sync::Arc; let key = ... let large_value = vec![0u8; 2 * 1024 * 1024]; // 2 MiB // When insert, wrap the large_value by Arc. cache.insert(key.clone(), Arc::new(large_value)); // get() will call Arc::clone() on the stored value, which is cheap. cache.get(&key); ``` -------------------------------- ### Iterate Over Cache Entries Source: https://context7.com/moka-rs/mini-moka/llms.txt Traverse all key-value pairs in the cache without impacting internal access statistics. ```rust use mini_moka::sync::Cache; fn main() { let cache: Cache<&str, i32> = Cache::new(100); cache.insert("Julia", 14); cache.insert("Bob", 25); cache.insert("Alice", 30); // Iterate using iter() for entry_ref in cache.iter() { let (key, value) = entry_ref.pair(); println!("{}: {}", key, value); } // Or use into_iter on reference for entry_ref in &cache { println!("Key: {}, Value: {}", entry_ref.key(), entry_ref.value()); } } ``` -------------------------------- ### Configure Cache Expiration Policies in Rust Source: https://github.com/moka-rs/mini-moka/blob/v0.11.x/README.md Use CacheBuilder to set time-to-live (TTL) and time-to-idle (TTI) expiration durations for cache entries. Panics if durations exceed 1000 years. ```rust use mini_moka::sync::Cache; use std::time::Duration; fn main() { let cache = Cache::builder() // Time to live (TTL): 30 minutes .time_to_live(Duration::from_secs(30 * 60)) // Time to idle (TTI): 5 minutes .time_to_idle(Duration::from_secs( 5 * 60)) // Create the cache. .build(); // This entry will expire after 5 minutes (TTI) if there is no get(). cache.insert(0, "zero"); // This get() will extend the entry life for another 5 minutes. cache.get(&0); // Even though we keep calling get(), the entry will expire // after 30 minutes (TTL) from the insert(). } ``` -------------------------------- ### Synchronize Cache State Source: https://context7.com/moka-rs/mini-moka/llms.txt Ensure pending internal operations are processed to retrieve accurate statistics by calling the sync() method. ```rust use mini_moka::sync::{Cache, ConcurrentCacheExt}; fn main() { let cache: Cache = Cache::new(10); cache.insert('n', "Netherland Dwarf"); cache.insert('l', "Lop Eared"); cache.insert('d', "Dutch"); // Entry exists assert!(cache.contains_key(&'n')); // Statistics might be stale due to async internal updates println!("Count (may be stale): {}", cache.entry_count()); // Bring ConcurrentCacheExt trait into scope and call sync() cache.sync(); // Now statistics are accurate println!("Count (accurate): {}", cache.entry_count()); // 3 println!("Weighted size: {}", cache.weighted_size()); // 3 } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.