use std::sync::Arc;
use quick_cache::Weighter;
use quick_cache::sync::Cache;
use crate::config::CacheConfig;
use crate::io::aligned_buf::AlignedBuf;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct BlockKey {
pub shard_id: u8,
pub file_id: u32,
pub block_offset: u64,
}
#[derive(Clone)]
struct BlockWeighter;
impl Weighter<BlockKey, Arc<AlignedBuf>> for BlockWeighter {
fn weight(&self, _key: &BlockKey, _value: &Arc<AlignedBuf>) -> u64 {
4096
}
}
pub struct BlockCache {
inner: Option<Cache<BlockKey, Arc<AlignedBuf>, BlockWeighter>>,
}
impl BlockCache {
pub fn new(config: &CacheConfig) -> Self {
if config.max_size == 0 {
return Self { inner: None };
}
let cache = Cache::with_weighter(config.estimated_items, config.max_size, BlockWeighter);
Self { inner: Some(cache) }
}
pub fn get(&self, key: &BlockKey) -> Option<Arc<AlignedBuf>> {
self.inner.as_ref()?.get(key)
}
pub fn insert(&self, key: BlockKey, block: Arc<AlignedBuf>) {
if let Some(cache) = &self.inner {
cache.insert(key, block);
}
}
pub fn invalidate_file(&self, shard_id: u8, file_id: u32, total_bytes: u64) {
if let Some(cache) = &self.inner {
let num_blocks = total_bytes.div_ceil(4096);
for i in 0..num_blocks {
cache.remove(&BlockKey {
shard_id,
file_id,
block_offset: i * 4096,
});
}
}
}
}