aboutsummaryrefslogtreecommitdiff
path: root/base/src/cache.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-01-24 18:11:23 +0100
committermetamuffin <metamuffin@disroot.org>2024-01-24 18:47:29 +0100
commit7323709537c6ff14136cd79fb07606cd79391758 (patch)
tree3d817d449d4c0a821b9b5073c8acf826c6ccfda1 /base/src/cache.rs
parentcbb2e163abfefd8ed61c41a096d5d6c27b4721b4 (diff)
downloadjellything-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.rs51
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(),