television_previewers/previewers/
cache.rs

1use rustc_hash::FxHashMap;
2use std::sync::Arc;
3
4use crate::previewers::Preview;
5use television_utils::cache::RingSet;
6use tracing::debug;
7
8/// Default size of the preview cache: 100 entries.
9///
10/// This does seem kind of arbitrary for now, will need to play around with it.
11/// At the moment, files over 4 MB are not previewed, so the cache size
12/// should never exceed 400 MB.
13const DEFAULT_PREVIEW_CACHE_SIZE: usize = 100;
14
15/// A cache for previews.
16/// The cache is implemented as an LRU cache with a fixed size.
17#[derive(Debug)]
18pub struct PreviewCache {
19    entries: FxHashMap<String, Arc<Preview>>,
20    ring_set: RingSet<String>,
21}
22
23impl PreviewCache {
24    /// Create a new preview cache with the given capacity.
25    pub fn new(capacity: usize) -> Self {
26        PreviewCache {
27            entries: FxHashMap::default(),
28            ring_set: RingSet::with_capacity(capacity),
29        }
30    }
31
32    pub fn get(&self, key: &str) -> Option<Arc<Preview>> {
33        self.entries.get(key).cloned()
34    }
35
36    /// Insert a new preview into the cache.
37    /// If the cache is full, the oldest entry will be removed.
38    /// If the key is already in the cache, the preview will be updated.
39    pub fn insert(&mut self, key: String, preview: &Arc<Preview>) {
40        debug!("Inserting preview into cache: {}", key);
41        self.entries.insert(key.clone(), Arc::clone(preview));
42        if let Some(oldest_key) = self.ring_set.push(key) {
43            debug!("Cache full, removing oldest entry: {}", oldest_key);
44            self.entries.remove(&oldest_key);
45        }
46    }
47
48    /// Get the preview for the given key, or insert a new preview if it doesn't exist.
49    #[allow(dead_code)]
50    pub fn get_or_insert<F>(&mut self, key: String, f: F) -> Arc<Preview>
51    where
52        F: FnOnce() -> Preview,
53    {
54        if let Some(preview) = self.get(&key) {
55            preview
56        } else {
57            let preview = Arc::new(f());
58            self.insert(key, &preview);
59            preview
60        }
61    }
62}
63
64impl Default for PreviewCache {
65    fn default() -> Self {
66        PreviewCache::new(DEFAULT_PREVIEW_CACHE_SIZE)
67    }
68}