use std::sync::atomic::{AtomicU64, Ordering};
use concinnity_core::blob::CacheEntryKind;
const FILE_BUDGET_BYTES: u64 = 32 * 1024 * 1024;
const KIND: CacheEntryKind = CacheEntryKind::Pipeline;
static CREATED: AtomicU64 = AtomicU64::new(0);
static CREATE_MICROS: AtomicU64 = AtomicU64::new(0);
pub(crate) fn note_creation(micros: u64) {
CREATED.fetch_add(1, Ordering::Relaxed);
CREATE_MICROS.fetch_add(micros, Ordering::Relaxed);
}
pub(crate) fn report_init(disk: &str) {
let (created, micros) = (
CREATED.load(Ordering::Relaxed),
CREATE_MICROS.load(Ordering::Relaxed),
);
if created == 0 {
return;
}
tracing::info!(
"pipeline cache: {created} pipelines created ({:.0} ms) at renderer init, disk blob {disk}",
micros as f64 / 1000.0
);
}
pub(crate) fn load(key: &str) -> Option<Vec<u8>> {
let bytes = crate::runtime_cache::load(KIND, key)?;
if within_budget(&bytes) {
Some(bytes)
} else {
delete(key);
None
}
}
pub(crate) fn store(key: &str, bytes: &[u8]) -> bool {
crate::runtime_cache::store(KIND, key, bytes)
}
pub(crate) fn delete(key: &str) {
crate::runtime_cache::delete(KIND, key);
}
fn within_budget(bytes: &[u8]) -> bool {
!bytes.is_empty() && bytes.len() as u64 <= FILE_BUDGET_BYTES
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_empty_or_over_budget_blob_is_not_kept() {
assert!(within_budget(&[1]));
assert!(within_budget(&vec![0u8; FILE_BUDGET_BYTES as usize]));
assert!(!within_budget(&[]), "a truncated entry");
assert!(!within_budget(&vec![0u8; FILE_BUDGET_BYTES as usize + 1]));
}
#[test]
fn the_cache_is_off_under_test() {
assert!(!crate::runtime_cache::enabled());
assert_eq!(load("vk-probe"), None);
assert!(!store("vk-probe", &[1, 2, 3]));
}
}