3d1cc7a
//! Cache helpers for `lib/git/*/usecase.rs` trait methods.
//!
//! Trait methods are sync but the underlying `Cache` is async. These helpers
//! wrap the sync cache bridge (`ObjectCache::get_sync` / `set_sync` /
//! `object_pool_*_sync`) and add the key conventions used across the crate:
//!
//! - Content-addressed: `object.pool.{kind}.{id}` — TTL = 0 (immutable).
//! - Reference-derived: `{module}.{func}.{key_part}:{tip_oid}` — TTL = 60s.
//!
//! Helpers in this file must not panic on transient cache failures. They are
//! best-effort: a missing or malformed cache entry simply means a cache miss.
use gix::hash::ObjectId;
use serde::Serialize;
use serde::de::DeserializeOwned;
use crate::GitRepository;
use crate::error::Error;
/// TTL for content-addressed keys (immutable — set to 0 = no expiry).
pub const IMMUTABLE_TTL: u64 = 0;
/// TTL for reference-derived keys (depend on tip / branch state).
pub const DERIVED_TTL: u64 = 60;
impl GitRepository {
/// Resolve HEAD to a detached `ObjectId`. Used as the invalidation anchor
/// for all reference-derived cache entries.
pub(crate) fn tip_id(&self) -> Result<ObjectId, Error> {
let repo = self.repo()?;
repo.head_id()
.map(|id| id.detach())
.map_err(|e| Error::Ref(e.to_string()))
}
/// Look up a content-addressed entry (`object.pool.{kind}.{id}`).
pub(crate) fn cache_get_oid<T>(&self, kind: &str, id: &ObjectId) -> Option<T>
where
T: DeserializeOwned + Send + Sync,
{
let k = format!("{kind}.{id}");
self.cache.object_pool_get_sync(&k)
}
/// Store a content-addressed entry with TTL=0 (immutable).
pub(crate) fn cache_put_oid<T: Serialize>(&self, kind: &str, id: &ObjectId, v: &T) {
let k = format!("{kind}.{id}");
self.cache.set_sync_with_ttl(&k, v, IMMUTABLE_TTL);
}
/// Look up a reference-derived entry (`{module}.{func}.{key_part}:{tip_oid}`).
pub(crate) fn cache_get_rev<T>(
&self,
module: &str,
func: &str,
key_part: &str,
tip: ObjectId,
) -> Option<T>
where
T: DeserializeOwned + Send + Sync,
{
let k = format!("{module}.{func}.{key_part}:{tip}");
self.cache.get_sync(&k)
}
/// Store a reference-derived entry with TTL=60s.
pub(crate) fn cache_put_rev<T: Serialize>(
&self,
module: &str,
func: &str,
key_part: &str,
tip: ObjectId,
v: &T,
) {
let k = format!("{module}.{func}.{key_part}:{tip}");
self.cache.set_sync_with_ttl(&k, v, DERIVED_TTL);
}
}