use std::collections::VecDeque;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, MutexGuard};
#[derive(Debug)]
pub(crate) struct Trail {
capacity: usize,
paths: Mutex<VecDeque<Arc<str>>>,
dropped: AtomicUsize,
}
impl Trail {
pub(crate) fn new(capacity: usize) -> Arc<Self> {
Arc::new(Self {
capacity: capacity.max(1),
paths: Mutex::new(VecDeque::new()),
dropped: AtomicUsize::new(0),
})
}
fn lock(&self) -> MutexGuard<'_, VecDeque<Arc<str>>> {
crate::journal::owner::lock(&self.paths)
}
pub(crate) fn record(&self, path: &Arc<str>) {
let mut paths = self.lock();
if paths.len() >= self.capacity {
paths.pop_front();
self.dropped.fetch_add(1, Ordering::Relaxed);
}
paths.push_back(Arc::clone(path));
}
pub(crate) fn snapshot(&self) -> (Vec<Arc<str>>, usize) {
let paths = self.lock();
(
paths.iter().cloned().collect(),
self.dropped.load(Ordering::Relaxed),
)
}
}