use std::sync::Arc;
use crate::Cache;
use anyhow::Result;
use moka::future::Cache as MokaCache;
pub struct InMemoryCache {
cache: MokaCache<String, Arc<Vec<f32>>>,
}
impl InMemoryCache {
pub fn unbounded() -> Self {
Self {
cache: MokaCache::builder().build(),
}
}
pub fn with_max_entries(max_entries: u64) -> Self {
Self {
cache: MokaCache::builder().max_capacity(max_entries).build(),
}
}
pub fn with_max_memory_mb(mb: u64) -> Self {
let max_bytes = mb * 1024 * 1024;
Self {
cache: MokaCache::builder()
.weigher(|_key: &String, value: &Arc<Vec<f32>>| (value.len() * 4) as u32)
.max_capacity(max_bytes)
.build(),
}
}
}
impl Default for InMemoryCache {
fn default() -> Self {
Self::with_max_entries(10_000)
}
}
#[async_trait::async_trait]
impl Cache for InMemoryCache {
async fn get(&self, input: &str) -> Result<Option<Vec<f32>>> {
Ok(self.cache.get(input).await.map(|arc| (*arc).clone()))
}
async fn put(&self, input: &str, embedding: Vec<f32>) -> Result<()> {
self.cache.insert(input.to_string(), Arc::new(embedding)).await;
Ok(())
}
async fn init(&self) -> Result<()> {
Ok(())
}
}