Add docs
This commit is contained in:
parent
28296a0f6e
commit
1e806ef4f0
@ -1,9 +1,13 @@
|
|||||||
|
//! Simple cache structure that stores values for a specified time. The cache itself is backed by
|
||||||
|
//! a HashMap.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Time based cache, that stores values for a defined time.
|
||||||
pub struct Cache<K, V> {
|
pub struct Cache<K, V> {
|
||||||
cache: HashMap<K, CacheEntry<V>>,
|
cache: HashMap<K, CacheEntry<V>>,
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
@ -13,6 +17,16 @@ impl<K, V> Cache<K, V>
|
|||||||
where
|
where
|
||||||
K: Eq + Hash,
|
K: Eq + Hash,
|
||||||
{
|
{
|
||||||
|
/// Creates a new cache.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// use time_cache::{Cache, CacheResult};
|
||||||
|
///
|
||||||
|
/// let cache: Cache<u8, u8> = Cache::new(Duration::from_secs(0));
|
||||||
|
/// assert_eq!(CacheResult::Empty, cache.get(&0));
|
||||||
|
/// ```
|
||||||
pub fn new(duration: Duration) -> Self {
|
pub fn new(duration: Duration) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cache: HashMap::new(),
|
cache: HashMap::new(),
|
||||||
@ -20,6 +34,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an item from the cache. The item can be either valid, invalid or non existent.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// use time_cache::{Cache, CacheResult};
|
||||||
|
///
|
||||||
|
/// let key = 0;
|
||||||
|
/// let value = 1;
|
||||||
|
/// let mut cache: Cache<u8, u8> = Cache::new(Duration::from_secs(0));
|
||||||
|
/// assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
/// cache.store(key, value);
|
||||||
|
/// assert_eq!(CacheResult::Invalid, cache.get(&key));
|
||||||
|
/// ```
|
||||||
pub fn get(&self, key: &K) -> CacheResult<&V> {
|
pub fn get(&self, key: &K) -> CacheResult<&V> {
|
||||||
if let Some(entry) = self.cache.get(key) {
|
if let Some(entry) = self.cache.get(key) {
|
||||||
if Self::is_valid(Instant::now(), entry) {
|
if Self::is_valid(Instant::now(), entry) {
|
||||||
@ -32,16 +60,66 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes an item from the cache. Returns `true` if the key was present.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// use time_cache::{Cache, CacheResult};
|
||||||
|
///
|
||||||
|
/// let key = 0;
|
||||||
|
/// let value = 1;
|
||||||
|
/// let mut cache: Cache<u8, u8> = Cache::new(Duration::from_secs(0));
|
||||||
|
/// assert!(!cache.invalidate(&key));
|
||||||
|
/// cache.store(key, value);
|
||||||
|
/// assert!(cache.invalidate(&key));
|
||||||
|
/// ```
|
||||||
pub fn invalidate(&mut self, key: &K) -> bool {
|
pub fn invalidate(&mut self, key: &K) -> bool {
|
||||||
self.cache.remove(key).is_some()
|
self.cache.remove(key).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stores an item in the cache.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// use time_cache::{Cache, CacheResult};
|
||||||
|
///
|
||||||
|
/// let key = 0;
|
||||||
|
/// let value = 1;
|
||||||
|
/// let dur = Duration::from_millis(500);
|
||||||
|
/// let mut cache: Cache<u8, u8> = Cache::new(dur);
|
||||||
|
///
|
||||||
|
/// assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
/// cache.store(key, value);
|
||||||
|
/// assert_eq!(CacheResult::Cached(&value), cache.get(&key));
|
||||||
|
/// std::thread::sleep(dur);
|
||||||
|
/// assert_eq!(CacheResult::Invalid, cache.get(&key));
|
||||||
|
/// ```
|
||||||
pub fn store(&mut self, key: K, value: V) -> Option<V> {
|
pub fn store(&mut self, key: K, value: V) -> Option<V> {
|
||||||
self.cache
|
self.cache
|
||||||
.insert(key, CacheEntry::new(value, self.duration))
|
.insert(key, CacheEntry::new(value, self.duration))
|
||||||
.map(|old| old.1)
|
.map(|old| old.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes all invalid items from the cache.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// use time_cache::{Cache, CacheResult};
|
||||||
|
///
|
||||||
|
/// let key = 0;
|
||||||
|
/// let value = 1;
|
||||||
|
/// let dur = Duration::from_secs(0);
|
||||||
|
/// let mut cache: Cache<u8, u8> = Cache::new(dur);
|
||||||
|
///
|
||||||
|
/// assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
/// cache.store(key, value);
|
||||||
|
/// assert_eq!(CacheResult::Invalid, cache.get(&key));
|
||||||
|
/// cache.clear();
|
||||||
|
/// assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
/// ```
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
self.cache.retain(|_, v| Self::is_valid(now, v))
|
self.cache.retain(|_, v| Self::is_valid(now, v))
|
||||||
@ -52,9 +130,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Result when requesting a cached item.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum CacheResult<T> {
|
pub enum CacheResult<T> {
|
||||||
|
/// Item is cached and still valid
|
||||||
Cached(T),
|
Cached(T),
|
||||||
|
/// Item is cached but invalid
|
||||||
Invalid,
|
Invalid,
|
||||||
|
/// Item is not in the cache
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user