2024-11-23 18:29:03 +01:00
|
|
|
use std::fmt::{self, Debug};
|
|
|
|
|
|
|
|
use dashmap::DashMap;
|
2024-11-26 20:55:49 +01:00
|
|
|
use tracing::{info_span, instrument};
|
2024-11-23 18:29:03 +01:00
|
|
|
|
2024-11-29 20:03:32 +01:00
|
|
|
use super::{query, Content, ContentVersion, Dir, Query, VPath, VPathBuf};
|
2024-11-23 18:29:03 +01:00
|
|
|
|
|
|
|
pub struct Blake3ContentVersionCache<T> {
|
2025-01-10 14:10:23 +01:00
|
|
|
salt: Vec<u8>,
|
2024-11-23 18:29:03 +01:00
|
|
|
inner: T,
|
2024-11-29 20:03:32 +01:00
|
|
|
cache: DashMap<VPathBuf, ContentVersion>,
|
2024-11-23 18:29:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Blake3ContentVersionCache<T> {
|
2025-01-10 14:10:23 +01:00
|
|
|
pub fn new(salt: Vec<u8>, inner: T) -> Self {
|
2024-11-23 18:29:03 +01:00
|
|
|
Self {
|
2025-01-10 14:10:23 +01:00
|
|
|
salt,
|
2024-11-23 18:29:03 +01:00
|
|
|
inner,
|
|
|
|
cache: DashMap::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-29 20:03:32 +01:00
|
|
|
impl<T> Blake3ContentVersionCache<T>
|
2024-11-23 18:29:03 +01:00
|
|
|
where
|
|
|
|
T: Dir,
|
|
|
|
{
|
2024-11-26 20:55:49 +01:00
|
|
|
#[instrument(name = "Blake3ContentVersionCache::content_version", skip(self))]
|
2024-11-29 20:03:32 +01:00
|
|
|
fn content_version(&self, path: &VPath) -> Option<ContentVersion> {
|
2024-11-23 22:18:10 +01:00
|
|
|
self.cache.get(path).map(|x| x.clone()).or_else(|| {
|
2024-11-26 20:55:49 +01:00
|
|
|
let _span = info_span!("cache_miss").entered();
|
|
|
|
|
2024-11-29 20:03:32 +01:00
|
|
|
let version = query::<Content>(&self.inner, path).map(|content| {
|
2025-01-10 14:10:23 +01:00
|
|
|
let mut hasher = blake3::Hasher::new();
|
|
|
|
hasher.update(&self.salt);
|
|
|
|
hasher.update(&content.bytes());
|
|
|
|
let hash = hasher.finalize().to_hex();
|
2024-11-29 20:03:32 +01:00
|
|
|
ContentVersion {
|
|
|
|
string: format!("b3-{}", &hash[0..8]),
|
|
|
|
}
|
2024-11-23 22:18:10 +01:00
|
|
|
});
|
|
|
|
if let Some(version) = &version {
|
|
|
|
self.cache.insert(path.to_owned(), version.clone());
|
|
|
|
}
|
|
|
|
version
|
|
|
|
})
|
2024-11-23 18:29:03 +01:00
|
|
|
}
|
2024-11-29 20:03:32 +01:00
|
|
|
}
|
2024-11-23 18:29:03 +01:00
|
|
|
|
2024-11-29 20:03:32 +01:00
|
|
|
impl<T> Dir for Blake3ContentVersionCache<T>
|
|
|
|
where
|
|
|
|
T: Dir,
|
|
|
|
{
|
|
|
|
fn query(&self, path: &VPath, query: &mut Query) {
|
|
|
|
query.try_provide(|| self.content_version(path));
|
2024-11-23 18:29:03 +01:00
|
|
|
|
2024-11-29 20:03:32 +01:00
|
|
|
self.inner.query(path, query);
|
2024-11-23 18:29:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> fmt::Debug for Blake3ContentVersionCache<T>
|
|
|
|
where
|
|
|
|
T: Debug,
|
|
|
|
{
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "Blake3ContentVersionCache({:?})", self.inner)
|
|
|
|
}
|
|
|
|
}
|