Removes unused entries from memory.
This commit is contained in:
		@@ -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<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 {
 | 
			
		||||
@@ -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)]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user