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
//! A highly performant, thread-safe cache implementation.
//!
//! This crate provides a cache that implements the S3-FIFO eviction algorithm as specified in
//! [FIFO Queues are All You Need for Cache Eviction](https://dl.acm.org/doi/pdf/10.1145/3600006.3613147).
//!
//! # Features
//!
//! - Thread-safe by default - no need for explicit synchronization
//! - S3-FIFO eviction algorithm for optimal cache performance
//! - Sharded design to reduce contention during concurrent access
//! - No unsafe code
//!
//! # Safety
//!
//! This crate is designed to be safe and easy to use:
//!
//! - No unsafe code is used
//! - Thread-safe by default when wrapped in `Arc`
//! - All operations are atomic
//!
//! # Examples
//!
//! Basic usage with string keys and values:
//!
//! ```rust
//! use plain_cache::Cache;
//!
//! // Create a new cache with a capacity of 1000 items
//! let cache = Cache::with_capacity(1000);
//!
//! // Insert and retrieve a value
//! cache.insert("key1", "value1");
//! assert_eq!(cache.get("key1"), Some("value1"));
//! ```
//!
//! Updating existing values:
//!
//! ```rust
//! use plain_cache::Cache;
//!
//! let cache = Cache::with_capacity(100);
//!
//! // Insert initial value
//! cache.insert("key1", "value1");
//!
//! // Update the value and get the old one
//! let old_value = cache.insert("key1", "new_value");
//! assert_eq!(old_value, Some("value1"));
//! assert_eq!(cache.get("key1"), Some("new_value"));
//! ```
//!
//! Thread-safe usage across multiple threads:
//!
//! ```rust
//! use plain_cache::Cache;
//! use std::sync::Arc;
//! use std::thread;
//!
//! let cache = Arc::new(Cache::with_capacity(100));
//! cache.insert("key1", "value1");
//!
//! // Spawn a thread that inserts a value
//! let cache_in_arc = Arc::clone(&cache);
//! let handle = thread::spawn(move || {
//! cache_in_arc.insert("key2", "value2");
//! });
//!
//! handle.join().unwrap();
//!
//! assert_eq!(cache.get("key1"), Some("value1"));
//! assert_eq!(cache.get("key2"), Some("value2"));
//! ```
//!
//! Monitoring cache performance with statistics:
//!
//! ```rust
//! use plain_cache::Cache;
//!
//! let cache = Cache::with_capacity(100);
//!
//! // Perform some cache operations
//! cache.insert("key1", "value1");
//! cache.get("key1"); // hit
//! cache.get("key2"); // miss
//!
//! // Get statistics (counters are reset after each call)
//! let stats = cache.stats();
//! println!("Hits: {}, Misses: {}, Evictions: {}, Time elapsed: {}ms",
//! stats.hit_count, stats.miss_count, stats.eviction_count, stats.millis_elapsed);
//!
//! // Calculate hit rate
//! let total_requests = stats.hit_count + stats.miss_count;
//! if total_requests > 0 {
//! let hit_rate = stats.hit_count as f64 / total_requests as f64;
//! println!("Hit rate: {:.2}%", hit_rate * 100.0);
//! }
//! ```
pub use Cache;
pub use Stats;