use std::time::SystemTime; use std::sync::{Arc, Mutex}; use std::time::Duration; use crate::videos::VideoItem; #[derive(Clone)] pub struct VideoCache { cache: Arc)>>>, // url -> time+Items max_size: usize, } impl VideoCache { pub fn new() -> Self { VideoCache { cache: Arc::new(Mutex::new(std::collections::HashMap::new())), max_size: 100, } } pub fn max_size(&mut self, size: usize) -> &mut Self { self.max_size = size; self } pub fn get(&self, key: &str) -> Option<(SystemTime, Vec)> { let cache = self.cache.lock().ok()?; cache.get(key).cloned() } pub fn insert(&self, key: String, value: Vec) { if let Ok(mut cache) = self.cache.lock() { if cache.len() >= self.max_size { // Simple eviction policy: remove a random entry if let Some(first_key) = cache.keys().next().cloned() { cache.remove(&first_key); } } cache.insert(key.clone(), (SystemTime::now(), value.clone())); } } pub fn remove(&self, key: &str) { if let Ok(mut cache) = self.cache.lock() { cache.remove(key); } } pub fn entries(&self) -> Option))>> { if let Ok(cache) = self.cache.lock() { // Return a cloned vector of the cache entries return Some(cache.iter().map(|(k, v)| (k.clone(), v.clone())).collect()); } None } pub async fn check(&self) -> Result<(), Box> { let iter = match self.entries() { Some(iter) => iter, None => { return Err(Box::new(std::io::Error::new( std::io::ErrorKind::Other, "Could not get entries", ))); } }; for (key, (time, _items)) in iter { if let Ok(elapsed) = time.elapsed() { if elapsed > Duration::from_secs(60 * 60) { self.remove(&key); } } } Ok(()) } }