diff options
author | metamuffin <metamuffin@disroot.org> | 2023-10-01 23:51:31 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-10-01 23:51:31 +0200 |
commit | 556b84b88a65c3df53ad35ca75b2c1a8fa360040 (patch) | |
tree | 73e9535d83717dea7a37134b7bdf63fba39cc3db /base/src/lib.rs | |
parent | 8b6a555d2dff18cad1135ebe62ae8fbc4a9f87c9 (diff) | |
download | jellything-556b84b88a65c3df53ad35ca75b2c1a8fa360040.tar jellything-556b84b88a65c3df53ad35ca75b2c1a8fa360040.tar.bz2 jellything-556b84b88a65c3df53ad35ca75b2c1a8fa360040.tar.zst |
move caching to its own file
Diffstat (limited to 'base/src/lib.rs')
-rw-r--r-- | base/src/lib.rs | 61 |
1 files changed, 3 insertions, 58 deletions
diff --git a/base/src/lib.rs b/base/src/lib.rs index 5a98be5..f130a8c 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -5,11 +5,10 @@ */ #![feature(lazy_cell)] pub mod permission; +pub mod cache; -use base64::Engine; -use jellycommon::{AssetLocation, config::GlobalConfig}; -use std::{fs::File, future::Future, path::PathBuf, sync::LazyLock}; -use tokio::sync::Mutex; +use jellycommon::{config::GlobalConfig, AssetLocation}; +use std::{fs::File, path::PathBuf, sync::LazyLock}; pub static CONF: LazyLock<GlobalConfig> = LazyLock::new(|| { serde_json::from_reader( @@ -23,60 +22,6 @@ pub static CONF: LazyLock<GlobalConfig> = LazyLock::new(|| { .unwrap() }); -pub fn cache_location(seed: &[&str]) -> (usize, AssetLocation) { - use sha2::Digest; - let mut d = sha2::Sha512::new(); - for s in seed { - d.update(s.as_bytes()); - d.update(b"\0"); - } - let d = d.finalize(); - let n = d[0] as usize | (d[1] as usize) << 8 | (d[2] as usize) << 16 | (d[3] as usize) << 24; - let fname = base64::engine::general_purpose::URL_SAFE.encode(d); - let fname = &fname[..22]; // about 128 bits - (n, AssetLocation::Cache(fname.into())) -} - -const CACHE_GENERATION_BUCKET_COUNT: usize = 1024; -pub static CACHE_GENERATION_LOCKS: LazyLock<[Mutex<()>; CACHE_GENERATION_BUCKET_COUNT]> = - LazyLock::new(|| [(); CACHE_GENERATION_BUCKET_COUNT].map(|_| Mutex::new(()))); - -pub async fn async_cache_file<Fun, Fut>( - seed: &[&str], - generate: Fun, -) -> Result<AssetLocation, anyhow::Error> -where - Fun: FnOnce(tokio::fs::File) -> Fut, - Fut: Future<Output = 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].lock(); - let exists = tokio::fs::try_exists(location.path()).await?; - if !exists { - let f = tokio::fs::File::create(location.path()).await?; - generate(f).await?; - } - drop(_guard); - Ok(location) -} - -pub fn cache_file<Fun>(seed: &[&str], mut generate: Fun) -> Result<AssetLocation, 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].lock(); - let exists = location.path().exists(); - if !exists { - let f = std::fs::File::create(location.path())?; - generate(f)?; - } - drop(_guard); - Ok(location) -} - pub trait AssetLocationExt { fn path(&self) -> PathBuf; } |