From 5e0faf4da84362f64f697ca671e17b1185fa3b0c Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Mon, 26 Dec 2022 17:48:50 -0500 Subject: [PATCH] Removes unused entries from memory. --- src/morethantext/mod.rs | 62 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 40c83da..b3fc31b 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -4,6 +4,7 @@ use async_std::{ fs::{create_dir, read, write}, path::Path, sync::{Arc, Mutex}, + task::{sleep, spawn}, }; use error::DBError; use rand::{distributions::Alphanumeric, thread_rng, Rng}; @@ -111,10 +112,28 @@ impl MoreThanText { } } } - Ok(Self { + let output = Self { cache: Arc::new(Mutex::new(HashMap::new())), dir: data_dir.to_str().unwrap().to_string(), - }) + }; + let looper = output.cache.clone(); + spawn(async move { + loop { + sleep(Duration::from_secs(1)).await; + let hold_time = Duration::from_secs(300); + let mut ids: Vec = Vec::new(); + let mut cache = looper.lock().await; + for (id, entry) in cache.iter() { + if entry.elapsed() > hold_time { + ids.push(id.to_string()); + } + } + for id in ids.iter() { + cache.remove(id); + } + } + }); + Ok(output) } fn filename(&self, id: &str) -> String { @@ -409,6 +428,45 @@ mod cache { } } } + + #[async_std::test] + async fn remove_older() { + let mtt = MTT::new().await; + let id = mtt + .db + .add_entry(CacheType::Raw("removed".to_string())) + .await + .unwrap(); + let mut cache = mtt.db.cache.lock().await; + let entry = cache.get_mut(&id).unwrap(); + entry.last_used = Instant::now() - Duration::from_secs(1000); + drop(cache); + sleep(Duration::from_secs(2)).await; + let cache = mtt.db.cache.lock().await; + let output = cache.get(&id); + assert!(output.is_none(), "The entry shoould not be in memory."); + drop(cache); + let filename = mtt.db.filename(&id); + let fpath = Path::new(&filename); + assert!( + fpath.is_file().await, + "The stored version should still exist." + ); + } + + #[async_std::test] + async fn keep_newer() { + let mtt = MTT::new().await; + let id = mtt + .db + .add_entry(CacheType::Raw("keep".to_string())) + .await + .unwrap(); + sleep(Duration::from_secs(2)).await; + let cache = mtt.db.cache.lock().await; + let output = cache.get(&id); + assert!(output.is_some(), "The entry shoould be in memory."); + } } #[cfg(test)]