Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ authors = ["Thomas Korrison <ferrite.db@gmail.com>"]
license = "MIT OR Apache-2.0"
description = "High-performance cache primitives with pluggable eviction policies (LRU, LFU, FIFO, 2Q, Clock-PRO, S3-FIFO) and optional metrics."
homepage = "https://oxidizelabs.github.io/cachekit/"
documentation = "https://docs.rs/cachekit"
repository = "https://github.com/OxidizeLabs/cachekit"
readme = "README.md"
keywords = ["cache", "lru", "lfu", "eviction", "s3-fifo"]
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_fifo.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cachekit::prelude::FifoCache;
use cachekit::policy::fifo::FifoCache;
use cachekit::traits::CoreCache;

fn main() {
Expand Down
7 changes: 6 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
//! │ │
//! │ traits Trait hierarchy (ReadOnlyCache → CoreCache → …) │
//! │ builder Unified CacheBuilder + Cache<K,V> wrapper │
//! │ policy 17 eviction policies behind feature flags │
//! │ policy 18 eviction policies behind feature flags │
//! │ ds Arena, ring buffer, intrusive list, ghost list, … │
//! │ store Storage backends (HashMap, slab, weighted) │
//! │ metrics Hit/miss counters and snapshots (feature-gated) │
Expand Down Expand Up @@ -162,6 +162,11 @@
//! return [`ConfigError`](error::ConfigError) for invalid parameters. Debug-only
//! invariant checks produce [`InvariantError`](error::InvariantError).
//!
//! # Release Notes
//!
//! See the [changelog](https://github.com/OxidizeLabs/cachekit/blob/main/CHANGELOG.md)
//! for a summary of changes in each published version.
//!
//! # Choosing a Policy
//!
//! ```text
Expand Down
20 changes: 10 additions & 10 deletions src/policy/fifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,9 @@ where
}

#[cfg(feature = "concurrency")]
impl<K, V> ConcurrentCache for ConcurrentFifoCache<K, V>
// SAFETY: ConcurrentFifoCache uses parking_lot RwLock internally for all
// shared-state access, so concurrent operations are correctly synchronised.
unsafe impl<K, V> ConcurrentCache for ConcurrentFifoCache<K, V>
where
K: Clone + Eq + Hash + Send + Sync,
V: Send + Sync,
Expand Down Expand Up @@ -859,16 +861,14 @@ where
None
}

fn pop_oldest_batch(&mut self, count: usize) -> Vec<(K, V)> {
let mut result = Vec::with_capacity(count.min(self.len()));
fn pop_oldest_batch_into(&mut self, count: usize, out: &mut Vec<(K, V)>) {
out.reserve(count.min(self.len()));
for _ in 0..count {
if let Some(entry) = self.pop_oldest() {
result.push(entry);
} else {
break;
match self.pop_oldest() {
Some(entry) => out.push(entry),
None => break,
}
}
result
}

fn age_rank(&self, key: &K) -> Option<usize> {
Expand Down Expand Up @@ -1513,8 +1513,8 @@ mod tests {
partial_cache.insert("d", 4);

// Remove 2 items
partial_cache.pop_oldest(); // Remove "a"
partial_cache.pop_oldest(); // Remove "b"
let _ = partial_cache.pop_oldest(); // Remove "a"
let _ = partial_cache.pop_oldest(); // Remove "b"
assert_eq!(partial_cache.len(), 2);

// Add 2 new items
Expand Down
12 changes: 6 additions & 6 deletions src/policy/lfu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2579,10 +2579,10 @@ mod tests {
assert_eq!(cache.len(), 2);

// Test pop_lfu operations
cache.pop_lfu();
let _ = cache.pop_lfu();
assert_eq!(cache.len(), 1);

cache.pop_lfu();
let _ = cache.pop_lfu();
assert_eq!(cache.len(), 0);

// Test pop_lfu on empty cache doesn't change length
Expand Down Expand Up @@ -2642,7 +2642,7 @@ mod tests {
cache.remove(&format!("key{}", capacity - 1));
assert_eq!(cache.capacity(), capacity);

cache.pop_lfu();
let _ = cache.pop_lfu();
assert_eq!(cache.capacity(), capacity);

cache.clear();
Expand Down Expand Up @@ -2673,7 +2673,7 @@ mod tests {
cache.remove(&format!("key{}", i % 10));
},
3 => {
cache.pop_lfu();
let _ = cache.pop_lfu();
},
_ => unreachable!(),
}
Expand Down Expand Up @@ -3113,7 +3113,7 @@ mod tests {
cache.remove(&format!("temp{}", i - 1));
},
3 => {
cache.pop_lfu();
let _ = cache.pop_lfu();
},
4 => {
cache.increment_frequency(&"key2".to_string());
Expand All @@ -3140,7 +3140,7 @@ mod tests {

// Test invariants after pop_lfu operations
while cache.len() > 0 {
cache.pop_lfu();
let _ = cache.pop_lfu();
verify_invariants(&mut cache);
}

Expand Down
14 changes: 7 additions & 7 deletions src/policy/lru.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2155,8 +2155,8 @@ mod tests {
assert_eq!(cache.len(), 5);

// Simulate capacity reduction to 3 by removing 2 LRU items
cache.pop_lru(); // Remove 1
cache.pop_lru(); // Remove 2
let _ = cache.pop_lru(); // Remove 1
let _ = cache.pop_lru(); // Remove 2
assert_eq!(cache.len(), 3);

// Remaining items should be 3, 4, 5
Expand Down Expand Up @@ -3175,12 +3175,12 @@ mod tests {
assert_eq!(*new_tail_key, 2);

// Pop again
cache.pop_lru();
let _ = cache.pop_lru();
let (final_tail_key, _) = cache.peek_lru().unwrap();
assert_eq!(*final_tail_key, 3);

// Pop last item
cache.pop_lru();
let _ = cache.pop_lru();
assert!(cache.peek_lru().is_none());
assert_eq!(cache.len(), 0);
}
Expand Down Expand Up @@ -4258,7 +4258,7 @@ mod tests {
cache.insert(6, Arc::new(600));
verify_ranks(&cache);

cache.pop_lru();
let _ = cache.pop_lru();
verify_ranks(&cache);
}

Expand Down Expand Up @@ -6165,7 +6165,7 @@ mod tests {
cache.insert(3, Arc::new(3));

// Pop LRU
cache.pop_lru(); // Removes 1
let _ = cache.pop_lru(); // Removes 1

// Check recency rank of remaining items to force traversal
assert!(cache.recency_rank(&2).is_some());
Expand Down Expand Up @@ -6231,7 +6231,7 @@ mod tests {
cache.get(&2);

// Remove head (LRU)
cache.pop_lru(); // Should remove 0 (LRU)
let _ = cache.pop_lru(); // Should remove 0 (LRU)

// Remove tail (MRU)
cache.remove(&2); // 2 was MRU
Expand Down
4 changes: 3 additions & 1 deletion src/policy/s3_fifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1547,7 +1547,9 @@ where
}

#[cfg(feature = "concurrency")]
impl<K, V> ConcurrentCache for ConcurrentS3FifoCache<K, V>
// SAFETY: ConcurrentS3FifoCache uses parking_lot RwLock internally for all
// shared-state access, so concurrent operations are correctly synchronised.
unsafe impl<K, V> ConcurrentCache for ConcurrentS3FifoCache<K, V>
where
K: Clone + Eq + Hash + Send + Sync,
V: Send + Sync,
Expand Down
33 changes: 18 additions & 15 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
pub use crate::ds::{
ClockRing, FixedHistory, FrequencyBucketEntryMeta, FrequencyBuckets, FrequencyBucketsHandle,
GhostList, IntrusiveList, KeyInterner, LazyMinHeap, ShardSelector, SlotArena, SlotId,
};
//! Convenience re-exports for the most common cachekit types.
//!
//! Import everything with:
//!
//! ```
//! use cachekit::prelude::*;
//! ```
//!
//! This gives you the core traits ([`CoreCache`], [`ReadOnlyCache`],
//! [`MutableCache`]), the policy-specific traits, and the [`CacheBuilder`]
//! entry point. Internal data structures and concrete policy types are
//! available from their respective modules ([`ds`](crate::ds),
//! [`policy`](crate::policy)).

#[cfg(feature = "concurrency")]
pub use crate::ds::{
ConcurrentClockRing, ConcurrentIntrusiveList, ConcurrentSlotArena,
ShardedFrequencyBucketEntryMeta, ShardedFrequencyBuckets, ShardedSlotArena, ShardedSlotId,
pub use crate::builder::{Cache, CacheBuilder, CachePolicy};
pub use crate::traits::{
ConcurrentCache, CoreCache, FifoCacheTrait, LfuCacheTrait, LruCacheTrait, LrukCacheTrait,
MutableCache, ReadOnlyCache,
};

#[cfg(feature = "metrics")]
pub use crate::metrics::snapshot::CacheMetricsSnapshot;
#[cfg(feature = "policy-fifo")]
pub use crate::policy::fifo::FifoCache;
pub use crate::traits::{
AsyncCacheFuture, CacheConfig, CacheFactory, CacheTier, CacheTierManager, ConcurrentCache,
CoreCache, FifoCacheTrait, LfuCacheTrait, LruCacheTrait, LrukCacheTrait, MutableCache,
ReadOnlyCache,
};
Loading
Loading