Removes unused entries from memory.

This commit is contained in:
Jeff Baskin 2022-12-26 17:48:50 -05:00
parent d3f53422df
commit 5e0faf4da8

View File

@ -4,6 +4,7 @@ use async_std::{
fs::{create_dir, read, write}, fs::{create_dir, read, write},
path::Path, path::Path,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
task::{sleep, spawn},
}; };
use error::DBError; use error::DBError;
use rand::{distributions::Alphanumeric, thread_rng, Rng}; 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())), cache: Arc::new(Mutex::new(HashMap::new())),
dir: data_dir.to_str().unwrap().to_string(), 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<String> = 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 { 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)] #[cfg(test)]