diff --git a/bindings/src/api.rs b/bindings/src/api.rs index 4224dc20d4eda675f265ee55f750acbd09a8afb8..f77053cb2b5d668637da03787d53a29cdf0d32f6 100644 --- a/bindings/src/api.rs +++ b/bindings/src/api.rs @@ -1,6 +1,6 @@ use std::hash::{Hash, Hasher}; -use proximipy::caching::bounded::bounded_linear_cache::BoundedLinearCache; +use proximipy::caching::bounded::lru::lru_cache::LRUCache; use proximipy::numerics::f32vector::F32Vector; use proximipy::{caching::approximate_cache::ApproximateCache, numerics::comp::ApproxComparable}; use pyo3::{ @@ -22,7 +22,7 @@ macro_rules! create_pythonized_interface { // happen on the Rust side and will not be visible to the Python ML pipeline. #[pyclass(unsendable)] pub struct $name { - inner: BoundedLinearCache<$keytype, $valuetype, $best_match>, + inner: LRUCache<$keytype, $valuetype, $best_match>, } #[pymethods] @@ -30,7 +30,7 @@ macro_rules! create_pythonized_interface { #[new] pub fn new(max_capacity: usize, tolerance: f32) -> Self { Self { - inner: BoundedLinearCache::new(max_capacity, tolerance), + inner: LRUCache::new(max_capacity, tolerance), } } diff --git a/core/src/caching/bounded/linked_list.rs b/core/src/caching/bounded/lru/linked_list.rs similarity index 97% rename from core/src/caching/bounded/linked_list.rs rename to core/src/caching/bounded/lru/linked_list.rs index 3b560aec1cf06ef47d95e2d1471845383ee253b6..7fec90cba7f58ac71e542c3e555f79ba2f66ebfc 100644 --- a/core/src/caching/bounded/linked_list.rs +++ b/core/src/caching/bounded/lru/linked_list.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use crate::caching::bounded::list_node::SharedNode; +use crate::caching::bounded::lru::list_node::SharedNode; pub struct DoublyLinkedList<K, V> { head: Option<SharedNode<K, V>>, @@ -60,7 +60,7 @@ impl<K, V> DoublyLinkedList<K, V> { #[cfg(test)] mod tests { use super::*; - use crate::caching::bounded::list_node::Node; + use crate::caching::bounded::lru::list_node::Node; #[test] fn test_add_to_head() { diff --git a/core/src/caching/bounded/list_node.rs b/core/src/caching/bounded/lru/list_node.rs similarity index 100% rename from core/src/caching/bounded/list_node.rs rename to core/src/caching/bounded/lru/list_node.rs diff --git a/core/src/caching/bounded/bounded_linear_cache.rs b/core/src/caching/bounded/lru/lru_cache.rs similarity index 84% rename from core/src/caching/bounded/bounded_linear_cache.rs rename to core/src/caching/bounded/lru/lru_cache.rs index 7bf92be9b460fdeddcb9531929a2824240c9e175..b41173008a0534688960b8c8f90e03700eb43c0a 100644 --- a/core/src/caching/bounded/bounded_linear_cache.rs +++ b/core/src/caching/bounded/lru/lru_cache.rs @@ -8,9 +8,7 @@ use crate::caching::approximate_cache::ApproximateCache; use super::linked_list::DoublyLinkedList; use super::list_node::{Node, SharedNode}; -/// `BoundedLinearCache` is a bounded cache with approximate key matching support. -/// -/// The cache enforces a maximum capacity, and when the capacity is exceeded, the least recently used (LRU) element is evicted. +/// `LRUCache` is a bounded cache with approximate key matching support and LRU eviction. /// /// # Approximate Key Matching /// Keys must implement the `ApproxComparable` trait, which allows approximate equality comparisons based on the provided `tolerance`. @@ -18,10 +16,10 @@ use super::list_node::{Node, SharedNode}; /// /// # Example Usage /// ``` -/// use proximipy::caching::bounded::bounded_linear_cache::BoundedLinearCache; +/// use proximipy::caching::bounded::lru::lru_cache::LRUCache; /// use proximipy::caching::approximate_cache::ApproximateCache; /// -/// let mut cache = BoundedLinearCache::<_,_,true>::new(3, 2.0); +/// let mut cache = LRUCache::<_,_,true>::new(3, 2.0); /// /// cache.insert(10 as i16, "Value 1"); /// cache.insert(20, "Value 2"); @@ -43,14 +41,14 @@ use super::list_node::{Node, SharedNode}; /// - `find(&mut self, key: &K) -> Option<V>`: Attempts to find a value matching the given key approximately. Promotes the found key to the head of the list. /// - `insert(&mut self, key: K, value: V)`: Inserts a key-value pair into the cache. Evicts the least recently used item if the cache is full. /// - `len(&self) -> usize`: Returns the current size of the cache. -pub struct BoundedLinearCache<K, V, const BEST_MATCH: bool> { +pub struct LRUCache<K, V, const BEST_MATCH: bool> { max_capacity: usize, map: HashMap<K, SharedNode<K, V>>, list: DoublyLinkedList<K, V>, tolerance: f32, } -impl<K, V, const BEST_MATCH: bool> ApproximateCache<K, V> for BoundedLinearCache<K, V, BEST_MATCH> +impl<K, V, const BEST_MATCH: bool> ApproximateCache<K, V> for LRUCache<K, V, BEST_MATCH> where K: ApproxComparable + Eq + Hash + Clone, V: Clone, @@ -94,7 +92,7 @@ where } } -impl<K, V, const BESTMATCH: bool> BoundedLinearCache<K, V, BESTMATCH> { +impl<K, V, const BESTMATCH: bool> LRUCache<K, V, BESTMATCH> { pub fn new(max_capacity: usize, tolerance: f32) -> Self { assert!(max_capacity > 0); assert!(tolerance > 0.0); @@ -115,8 +113,8 @@ mod tests { #[test] fn test_lru_cache_basic_operations() { fn test_lru_cache_basic_operations_best_match<const BEST_MATCH: bool>() { - let mut cache: BoundedLinearCache<i16, i16, BEST_MATCH> = - BoundedLinearCache::new(2, TEST_TOLERANCE); + let mut cache: LRUCache<i16, i16, BEST_MATCH> = + LRUCache::new(2, TEST_TOLERANCE); cache.insert(1, 1); // Cache is {1=1} cache.insert(2, 2); // Cache is {1=1, 2=2} assert_eq!(cache.find(&1), Some(1)); // Returns 1, Cache is {2=2, 1=1} @@ -134,8 +132,8 @@ mod tests { #[test] fn test_lru_cache_eviction_order() { fn test_lru_cache_eviction_order_best_match<const BEST_MATCH: bool>() { - let mut cache: BoundedLinearCache<i16, i16, BEST_MATCH> = - BoundedLinearCache::new(3, TEST_TOLERANCE); + let mut cache: LRUCache<i16, i16, BEST_MATCH> = + LRUCache::new(3, TEST_TOLERANCE); cache.insert(1, 1); // Cache is {1=1} cache.insert(2, 2); // Cache is {1=1, 2=2} cache.insert(3, 3); // Cache is {1=1, 2=2, 3=3} @@ -154,8 +152,8 @@ mod tests { #[test] fn test_lru_cache_overwrite() { fn test_lru_cache_overwrite_best_match<const BEST_MATCH: bool>() { - let mut cache: BoundedLinearCache<i16, i16, BEST_MATCH> = - BoundedLinearCache::new(2, TEST_TOLERANCE); + let mut cache: LRUCache<i16, i16, BEST_MATCH> = + LRUCache::new(2, TEST_TOLERANCE); cache.insert(1, 1); // Cache is {1=1} cache.insert(2, 2); // Cache is {1=1, 2=2} cache.insert(1, 10); // Overwrites key 1, Cache is {2=2, 1=10} @@ -171,8 +169,8 @@ mod tests { #[test] fn test_lru_cache_capacity_one() { fn test_lru_cache_capacity_one_best_match<const BEST_MATCH: bool>() { - let mut cache: BoundedLinearCache<i16, i16, BEST_MATCH> = - BoundedLinearCache::new(1, TEST_TOLERANCE); + let mut cache: LRUCache<i16, i16, BEST_MATCH> = + LRUCache::new(1, TEST_TOLERANCE); cache.insert(1, 1); // Cache is {1=1} assert_eq!(cache.find(&1), Some(1)); // Returns 1 cache.insert(2, 2); // Evicts key 1, Cache is {2=2} @@ -186,6 +184,6 @@ mod tests { #[test] #[should_panic] fn test_lru_cache_empty() { - let _cache: BoundedLinearCache<i16, i16, true> = BoundedLinearCache::new(0, TEST_TOLERANCE); + let _cache: LRUCache<i16, i16, true> = LRUCache::new(0, TEST_TOLERANCE); } } diff --git a/core/src/caching/bounded/lru/mod.rs b/core/src/caching/bounded/lru/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..83175224b643b4ac9fb629d6bd3958f134fe558c --- /dev/null +++ b/core/src/caching/bounded/lru/mod.rs @@ -0,0 +1,3 @@ +pub mod lru_cache; +mod linked_list; +mod list_node; diff --git a/core/src/caching/bounded/mod.rs b/core/src/caching/bounded/mod.rs index b2b1881a91a5fe79a9634011518242ed279dc1e8..2cafec9fe8d5b666a764b5001669b1d99219383a 100644 --- a/core/src/caching/bounded/mod.rs +++ b/core/src/caching/bounded/mod.rs @@ -1,3 +1 @@ -pub mod bounded_linear_cache; -mod linked_list; -mod list_node; +pub mod lru; \ No newline at end of file diff --git a/core/src/main.rs b/core/src/main.rs index 28b62b45434cc523994c5b07d381e3ff7815ed8c..af7851e15c91ff8cc4d524d79c16f3faefc7b635 100644 --- a/core/src/main.rs +++ b/core/src/main.rs @@ -4,7 +4,7 @@ use std::path::Path; use caching::approximate_cache::ApproximateCache; -use caching::bounded::bounded_linear_cache::BoundedLinearCache; +use caching::bounded::lru::lru_cache::LRUCache; use fs::file_manager; use numerics::f32vector::F32Vector; use std::fs::File; @@ -27,7 +27,7 @@ fn main() { let vecs_f: Vec<f32> = vecs.into_iter().map(f32::from).collect(); println!("{:?}", vecs_f.chunks_exact(128).next().unwrap()); - let mut ulc = BoundedLinearCache::<F32Vector, usize, true>::new(10000, 15_000.0); + let mut ulc = LRUCache::<F32Vector, usize, true>::new(10000, 15_000.0); let mut count: u32 = 0; let mut scanned: usize = 0;