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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
// Copyright (C) 2024 Christian Mauduit <ufoot@ufoot.org>
//! [HashLRU](https://gitlab.com/liberecofr/hashlru) is a LRU cache.
//!
//! It tries to follow the API exposed by a [standard Rust HashMap](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html)
//! while enforcing a limited memory footprint by limiting the number of keys using the LRU strategy, which is
//! a quite [common cache replacement policy]( https://en.wikipedia.org/wiki/Cache_replacement_policies).
//!
//! ![HashLRU icon](https://gitlab.com/liberecofr/hashlru/raw/main/hashlru.png)
//!
//! # Examples
//!
//! Feels like a hash map:
//!
//! ```
//! use hashlru::Cache;
//!
//! let mut cache = Cache::new(1000);
//!
//! cache.insert("my-key", 123);
//! assert_eq!(Some(&123), cache.get(&"my-key"));
//! ```
//!
//! Drops unused entries:
//!
//! ```
//! use hashlru::Cache;
//!
//! let mut cache = Cache::new(4);
//! cache.insert("key1", 10);
//! cache.insert("key2", 20);
//! cache.insert("key3", 30);
//! cache.insert("key4", 40);
//! cache.insert("key5", 50);
//! // key1 has been dropped, size is limited to 4
//! assert_eq!(Some(&"key2"), cache.lru());
//! assert_eq!(Some(&20), cache.get(&"key2"));
//! // getting key2 has made key3 the least recently used item
//! assert_eq!(Some(&"key3"), cache.lru());
//! assert_eq!(Some(&40), cache.get(&"key4"));
//! // getting key4 makes it the most recently used item
//! assert_eq!("[key3: 30, key5: 50, key2: 20, key4: 40]", format!("{}", cache));
//! ```
//!
//! More complex example:
//!
//! ```
//! use hashlru::Cache;
//!
//! #[derive(Debug, Eq, PartialEq)]
//! struct Obj {
//! name: String,
//! scalar: usize,
//! }
//!
//! impl Obj {
//! fn new(name: &str, scalar: usize) -> Self {
//! Obj{name: name.to_string(), scalar}
//! }
//! }
//!
//! #[derive(Debug, Eq, PartialEq, Hash, Clone)]
//! struct Key {
//! x: i64,
//! y: i64,
//! }
//!
//! impl Key {
//! fn new(x: i64, y: i64) -> Self {
//! Key{x, y}
//! }
//! }
//!
//! let mut cache: Cache<Key, Obj> = Cache::new(2);
//! cache.insert(Key::new(1, 2), Obj::new("pim", 123));
//! cache.insert(Key::new(3, 9), Obj::new("pam", 456));
//! cache.insert(Key::new(-4, 0), Obj::new("pom", 789));
//! assert_eq!(2, cache.len());
//! cache.resize(10);
//! cache.insert(Key::new(22, 10), Obj::new("pem", 0));
//! assert_eq!(Some(&Key::new(22, 10)), cache.mru());
//! assert_eq!(Some(&Key::new(3, 9)), cache.lru());
//! assert_eq!(Some(&Obj::new("pom", 789)), cache.get(&Key::new(-4, 0)));
//! assert_eq!(Some(&Key::new(-4, 0)), cache.mru());
//! assert_eq!(Some(&Key::new(3, 9)), cache.lru());
//! assert_eq!(Some(&Obj::new("pam", 456)), cache.get(&Key::new(3, 9)));
//! assert_eq!(Some(&Key::new(3, 9)), cache.mru());
//! assert_eq!(Some(&Key::new(22, 10)), cache.lru());
//! ```
//!
//! Thread-safe cache:
//!
//! ```
//! use hashlru::SyncCache;
//! use std::thread;
//!
//! let cache: SyncCache<usize, usize> = SyncCache::new(50);
//!
//! let cache1 = cache.clone();
//! let handle1 = thread::spawn(move || cache1.insert(1,2));
//! let cache2 = cache.clone();
//! let handle2 = thread::spawn(move || cache2.insert(3,4));
//!
//! handle1.join().unwrap();
//! handle2.join().unwrap();
//!
//! assert_eq!(Some(2), cache.get(&1));
//! assert_eq!(Some(4), cache.get(&3));
//! ```
mod cache;
#[cfg(feature = "serde")]
mod custom_serde;
mod dump;
mod iter;
mod sync_cache;
pub use cache::*;
#[cfg(feature = "serde")]
pub use custom_serde::*;
pub use dump::*;
pub use iter::*;
pub use sync_cache::*;