-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7081186
commit 941ed46
Showing
12 changed files
with
381 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use std::{ | ||
collections::{HashMap, HashSet, VecDeque}, | ||
sync::Arc, | ||
}; | ||
|
||
use tracing::debug; | ||
|
||
use crate::components::previewers::Preview; | ||
|
||
/// A ring buffer that also keeps track of the keys it contains to avoid duplicates. | ||
struct SetRingBuffer<T> { | ||
ring_buffer: VecDeque<T>, | ||
known_keys: HashSet<T>, | ||
capacity: usize, | ||
} | ||
|
||
impl<T> SetRingBuffer<T> | ||
where | ||
T: Eq + std::hash::Hash + Clone + std::fmt::Debug, | ||
{ | ||
pub fn with_capacity(capacity: usize) -> Self { | ||
SetRingBuffer { | ||
ring_buffer: VecDeque::with_capacity(capacity), | ||
known_keys: HashSet::with_capacity(capacity), | ||
capacity, | ||
} | ||
} | ||
|
||
// TODO: finish this | ||
pub fn push(&mut self, key: T) -> Option<T> { | ||
// If the key is already in the buffer, do nothing | ||
if self.contains(&key) { | ||
debug!("Key already in ring buffer: {:?}", key); | ||
return None; | ||
} | ||
// If the buffer is full, remove the oldest key | ||
if self.ring_buffer.len() >= self.capacity { | ||
self.pop(); | ||
} | ||
// finally, push the new key | ||
self.ring_buffer.push_back(key.clone()); | ||
self.known_keys.insert(key); | ||
None | ||
} | ||
|
||
pub fn pop(&mut self) -> Option<T> { | ||
if let Some(key) = self.ring_buffer.pop_front() { | ||
debug!("Removing key from ring buffer: {:?}", key); | ||
self.known_keys.remove(&key); | ||
Some(key) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
pub fn contains(&self, key: &T) -> bool { | ||
self.known_keys.contains(key) | ||
} | ||
} | ||
|
||
const DEFAULT_PREVIEW_CACHE_SIZE: usize = 100; | ||
|
||
/// A cache for previews. | ||
pub struct PreviewCache { | ||
entries: HashMap<String, Arc<Preview>>, | ||
set_ring_buffer: SetRingBuffer<String>, | ||
} | ||
|
||
impl PreviewCache { | ||
pub fn new(max_size: usize) -> Self { | ||
PreviewCache { | ||
entries: HashMap::new(), | ||
set_ring_buffer: SetRingBuffer::with_capacity(max_size), | ||
} | ||
} | ||
|
||
pub fn get(&self, key: &str) -> Option<Arc<Preview>> { | ||
self.entries.get(key).cloned() | ||
} | ||
|
||
pub fn insert(&mut self, key: String, preview: Arc<Preview>) { | ||
debug!("Inserting preview into cache: {}", key); | ||
self.entries.insert(key.clone(), preview.clone()); | ||
self.set_ring_buffer.push(key); | ||
if self.entry_buffer.len() >= self.max_size { | ||
if let Some(oldest_key) = self.entry_buffer.pop_front() { | ||
debug!("Cache full, removing oldest entry: {}", oldest_key); | ||
self.entries.remove(&oldest_key); | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl Default for PreviewCache { | ||
fn default() -> Self { | ||
PreviewCache::new(DEFAULT_PREVIEW_CACHE_SIZE) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.