diff options
author | metamuffin <metamuffin@disroot.org> | 2024-01-24 18:11:23 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-01-24 18:47:29 +0100 |
commit | 7323709537c6ff14136cd79fb07606cd79391758 (patch) | |
tree | 3d817d449d4c0a821b9b5073c8acf826c6ccfda1 /base/src/cache.rs | |
parent | cbb2e163abfefd8ed61c41a096d5d6c27b4721b4 (diff) | |
download | jellything-7323709537c6ff14136cd79fb07606cd79391758.tar jellything-7323709537c6ff14136cd79fb07606cd79391758.tar.bz2 jellything-7323709537c6ff14136cd79fb07606cd79391758.tar.zst |
refactor asset system pt. 1
Diffstat (limited to 'base/src/cache.rs')
-rw-r--r-- | base/src/cache.rs | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/base/src/cache.rs b/base/src/cache.rs index d1c3e4d..3c4ae81 100644 --- a/base/src/cache.rs +++ b/base/src/cache.rs @@ -3,11 +3,10 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin <metamuffin.org> */ -use crate::{AssetLocationExt, CONF}; +use crate::CONF; use anyhow::{anyhow, Context}; use base64::Engine; use bincode::{Decode, Encode}; -use jellycommon::AssetLocation; use log::{info, warn}; use rand::random; use std::{ @@ -17,7 +16,6 @@ use std::{ future::Future, io::Seek, path::PathBuf, - str::FromStr, sync::{ atomic::{AtomicUsize, Ordering}, Arc, LazyLock, RwLock, @@ -29,7 +27,15 @@ use tokio::{ sync::Mutex, }; -pub fn cache_location(seed: &[&str]) -> (usize, AssetLocation) { +#[derive(Debug, Encode, Decode)] +pub struct CachePath(pub PathBuf); +impl CachePath { + pub fn abs(&self) -> PathBuf { + CONF.cache_path.join(&self.0) + } +} + +pub fn cache_location(seed: &[&str]) -> (usize, CachePath) { use sha2::Digest; let mut d = sha2::Sha512::new(); for s in seed { @@ -41,7 +47,7 @@ pub fn cache_location(seed: &[&str]) -> (usize, AssetLocation) { let fname = base64::engine::general_purpose::URL_SAFE.encode(d); let fname = &fname[..22]; let fname = format!("{}-{}", seed[0], fname); // about 128 bits - (n, AssetLocation::Cache(fname.into())) + (n, CachePath(fname.into())) } const CACHE_GENERATION_BUCKET_COUNT: usize = 1024; @@ -51,7 +57,7 @@ pub static CACHE_GENERATION_LOCKS: LazyLock<[Mutex<()>; CACHE_GENERATION_BUCKET_ pub async fn async_cache_file<Fun, Fut>( seed: &[&str], generate: Fun, -) -> Result<AssetLocation, anyhow::Error> +) -> Result<CachePath, anyhow::Error> where Fun: FnOnce(tokio::fs::File) -> Fut, Fut: Future<Output = Result<(), anyhow::Error>>, @@ -61,13 +67,11 @@ where let _guard = CACHE_GENERATION_LOCKS[bucket % CACHE_GENERATION_BUCKET_COUNT] .lock() .await; - let exists = tokio::fs::try_exists(location.path()) + let exists = tokio::fs::try_exists(&location.abs()) .await .context("unable to test for cache file existance")?; if !exists { - let temp_path = - AssetLocation::Cache(PathBuf::from_str(&format!("temp-{:x}", random::<u128>()))?) - .path(); + let temp_path = CONF.cache_path.join(format!("temp-{:x}", random::<u128>())); let f = tokio::fs::File::create(&temp_path) .await .context("creating new cache file")?; @@ -79,7 +83,7 @@ where return Err(e); } } - tokio::fs::rename(temp_path, location.path()) + tokio::fs::rename(temp_path, &location.abs()) .await .context("rename cache")?; } @@ -87,18 +91,15 @@ where Ok(location) } -pub fn cache_file<Fun>(seed: &[&str], mut generate: Fun) -> Result<AssetLocation, anyhow::Error> +pub fn cache_file<Fun>(seed: &[&str], mut generate: Fun) -> Result<CachePath, anyhow::Error> where Fun: FnMut(std::fs::File) -> Result<(), anyhow::Error>, { let (bucket, location) = cache_location(seed); // we need a lock even if it exists since somebody might be still in the process of writing. let _guard = CACHE_GENERATION_LOCKS[bucket % CACHE_GENERATION_BUCKET_COUNT].blocking_lock(); - let exists = location.path().exists(); - if !exists { - let temp_path = - AssetLocation::Cache(PathBuf::from_str(&format!("temp-{:x}", random::<u128>()))?) - .path(); + if !location.abs().exists() { + let temp_path = CONF.cache_path.join(format!("temp-{:x}", random::<u128>())); let f = std::fs::File::create(&temp_path).context("creating new cache file")?; match generate(f) { Ok(()) => (), @@ -108,7 +109,7 @@ where return Err(e); } } - rename(temp_path, location.path()).context("rename cache")?; + rename(temp_path, &location.abs()).context("rename cache")?; } drop(_guard); Ok(location) @@ -119,7 +120,7 @@ pub struct InMemoryCacheEntry { last_access: Instant, object: Arc<dyn Any + Send + Sync + 'static>, } -pub static CACHE_IN_MEMORY_OBJECTS: LazyLock<RwLock<HashMap<AssetLocation, InMemoryCacheEntry>>> = +pub static CACHE_IN_MEMORY_OBJECTS: LazyLock<RwLock<HashMap<PathBuf, InMemoryCacheEntry>>> = LazyLock::new(|| RwLock::new(HashMap::new())); pub static CACHE_IN_MEMORY_SIZE: AtomicUsize = AtomicUsize::new(0); @@ -131,7 +132,7 @@ where let (_, location) = cache_location(seed); { let mut g = CACHE_IN_MEMORY_OBJECTS.write().unwrap(); - if let Some(entry) = g.get_mut(&location) { + if let Some(entry) = g.get_mut(&location.abs()) { entry.last_access = Instant::now(); let object = entry .object @@ -148,7 +149,7 @@ where .context("encoding cache object")?; Ok(()) })?; - let mut file = std::fs::File::open(location.path())?; + let mut file = std::fs::File::open(&location.abs())?; let object = bincode::decode_from_std_read::<T, _, _>(&mut file, bincode::config::standard()) .context("decoding cache object")?; let object = Arc::new(object); @@ -157,7 +158,7 @@ where { let mut g = CACHE_IN_MEMORY_OBJECTS.write().unwrap(); g.insert( - location, + location.abs(), InMemoryCacheEntry { size, last_access: Instant::now(), @@ -184,7 +185,7 @@ where let (_, location) = cache_location(seed); { let mut g = CACHE_IN_MEMORY_OBJECTS.write().unwrap(); - if let Some(entry) = g.get_mut(&location) { + if let Some(entry) = g.get_mut(&location.abs()) { entry.last_access = Instant::now(); let object = entry .object @@ -205,7 +206,7 @@ where Ok(()) }) .await?; - let mut file = tokio::fs::File::open(location.path()).await?; + let mut file = tokio::fs::File::open(&location.abs()).await?; let mut data = Vec::new(); file.read_to_end(&mut data) .await @@ -218,7 +219,7 @@ where { let mut g = CACHE_IN_MEMORY_OBJECTS.write().unwrap(); g.insert( - location, + location.abs(), InMemoryCacheEntry { size, last_access: Instant::now(), |