parent
1fb08b35a0
commit
674dab36d1
@ -0,0 +1,85 @@
|
||||
//! Service cacheing
|
||||
use super::*;
|
||||
use std::{
|
||||
hash::Hash,
|
||||
marker::{Send, Sync},
|
||||
fmt,
|
||||
};
|
||||
use std::sync::{
|
||||
RwLock,
|
||||
atomic::AtomicUsize,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::collections::HashMap;
|
||||
use chrono::DateTime;
|
||||
use ::bytes::Bytes;
|
||||
|
||||
|
||||
pub type Timezone = chrono::Utc;
|
||||
|
||||
/// A type that can be used for the cache key
|
||||
pub trait Key: Sized +
|
||||
Send +
|
||||
Sync +
|
||||
Hash +
|
||||
PartialEq +
|
||||
Eq +
|
||||
fmt::Display +
|
||||
Serialize +
|
||||
for<'a> Deserialize<'a> +
|
||||
'static
|
||||
{}
|
||||
|
||||
basic_enum!(pub PurgeOrder; "How should a cache determine what to purge": Oldest => "Purge the oldest entries first", LeastUsed => "Purge the least accessed entries first", OldestUsed => "Purge the oldest accessed entries first");
|
||||
default!(PurgeOrder: Self::LeastUsed);
|
||||
|
||||
/// Config for a cache
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Config
|
||||
{
|
||||
// General
|
||||
|
||||
// Disk cache
|
||||
/// The directory to save to data to.
|
||||
/// If `None`, se memory cache only.
|
||||
pub disk_location: Option<PathBuf>,
|
||||
|
||||
// Memory cache
|
||||
/// Max size of an entry to cache in memory
|
||||
pub mem_max_ent_size: Option<NonZeroUsize>,
|
||||
/// Max entries in memory cache
|
||||
pub mem_max_ent: Option<NonZeroUsize>,
|
||||
/// Max total bytes to keep in memcache before purging older entries.
|
||||
pub mem_max_total_size: Option<NonZeroUsize>,
|
||||
/// When purging entries from memcache, how to select ones to purge
|
||||
pub mem_purge_order: PurgeOrder,
|
||||
}
|
||||
|
||||
/// The memory hold of a cahce.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
struct Memory(Bytes);
|
||||
|
||||
/// An entry in a `ByteCache`.
|
||||
#[derive(Debug)]
|
||||
pub struct CacheEntry //<K: Key> // `K` is the key in `entries`.
|
||||
{
|
||||
tm_accessed: RwLock<DateTime<Timezone>>, // Can be mutated when read, so must be mutable by the reader, hence the `RwLock`.
|
||||
tm_created: DateTime<Timezone>,
|
||||
accesses: AtomicUsize, // Can be mutated when read, hence the atomic.
|
||||
|
||||
memory: Option<Memory>,
|
||||
|
||||
// Pathname is computed from `key`.
|
||||
}
|
||||
|
||||
/// A byte-stream cache. Caches both to memory and also writes entries to disk.
|
||||
#[derive(Debug)]
|
||||
pub struct ByteCache<K: Key>
|
||||
{
|
||||
// Config is big, box it.
|
||||
cfg: Box<Config>,
|
||||
|
||||
/// Frozen entries.
|
||||
entries: HashMap<K, CacheEntry>,
|
||||
}
|
Loading…
Reference in new issue