diff --git a/Cargo.lock b/Cargo.lock index e2a5ca0..5fd8173 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,17 @@ dependencies = [ "build_const", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + [[package]] name = "crypto-mac" version = "0.9.1" @@ -527,6 +538,7 @@ dependencies = [ "bytes 1.0.1", "chacha20stream", "chrono", + "crossbeam-utils", "cryptohelpers", "futures", "generational-arena", diff --git a/Cargo.toml b/Cargo.toml index 4818207..1224ddc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ bitflags = "1.2.1" bytes = "1.0.1" chacha20stream = {version = "1.0", features = ["async", "serde"]} chrono = {version = "0.4.19", features= ["serde"]} +crossbeam-utils = "0.8.4" cryptohelpers = {version = "1.7", features = ["full", "async", "serde"]} futures = "0.3.8" generational-arena = "0.2.8" diff --git a/src/service/cache/mod.rs b/src/service/cache/mod.rs index 4ce002d..7e166ae 100644 --- a/src/service/cache/mod.rs +++ b/src/service/cache/mod.rs @@ -6,15 +6,19 @@ use std::{ fmt, }; use std::sync::{ + Weak, + RwLock, atomic::AtomicUsize, }; +use std::cell::UnsafeCell; use std::path::PathBuf; use std::num::NonZeroUsize; use std::collections::HashMap; use chrono::DateTime; use ::bytes::Bytes; - +use uuid::Uuid; +use crossbeam_utils::atomic::AtomicCell; pub type Timezone = chrono::Utc; @@ -30,6 +34,18 @@ pub trait Key: Sized + for<'a> Deserialize<'a> + 'static {} +impl Key for T +where T: +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); @@ -64,22 +80,59 @@ struct Memory(Bytes); #[derive(Debug)] pub struct CacheEntry // // `K` is the key in `entries`. { + id: Uuid, + tm_accessed: RwLock>, // Can be mutated when read, so must be mutable by the reader, hence the `RwLock`. tm_created: DateTime, accesses: AtomicUsize, // Can be mutated when read, hence the atomic. memory: Option, - // Pathname is computed from `key`. + // Pathname is computed from `id`. } -/// A byte-stream cache. Caches both to memory and also writes entries to disk. +/// A byte-stream cache of data. Caches both to memory and also writes entries to disk. #[derive(Debug)] pub struct ByteCache { + /// How the cache should operate // Config is big, box it. cfg: Box, /// Frozen entries. - entries: HashMap, + entries: RwLock>, + + ///// Non-complete entries are completed with async semantics. + ///// Moving them to `entries` is completed with sync semantics. + // TODO: Is this right at all? eh... + // FUCK This shit, don't store it here, do it somewhere fucking else FUCK. + // working: tokio::sync::RwLock>>>>, +} +/* +XXX: Move this to submodule, fuck the Cell BULLSHIT FUCK +#[derive(Debug)] +struct PartialCacheEntryInner +{ + key: K, + + disk: tokio::fs::File, + memory: ::bytes::BytesMut, +} + + +//#[derive(Debug)] +pub struct PartialCacheEntry(Arc>>); + +impl PartialCacheEntry +{ + fn as_inner_mut(&mut self) -> &mut PartialCacheEntryInner + { + //XXX: Is this safe???? Do we need an extra unsafecell? eh... fuck this + unsafe { &mut *(self.0.as_ptr() as *mut _)} + } + fn as_inner(&self) -> &PartialCacheEntryInner + { + unsafe { &*self.0.as_ptr() } + } } +*/