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