//! 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 { 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(&self, kind: &str, id: &ObjectId) -> Option 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(&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( &self, module: &str, func: &str, key_part: &str, tip: ObjectId, ) -> Option 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( &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); } }