use std::sync::{Arc, Mutex};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SnapshotManifest {
pub sstable_ids: Vec<u64>,
}
impl SnapshotManifest {
pub fn new(sstable_ids: Vec<u64>) -> Self {
Self { sstable_ids }
}
pub fn len(&self) -> usize {
self.sstable_ids.len()
}
pub fn is_empty(&self) -> bool {
self.sstable_ids.is_empty()
}
}
#[derive(Debug, Clone)]
pub struct Snapshot {
manifest: Arc<SnapshotManifest>,
id: u64,
}
impl Snapshot {
pub fn manifest(&self) -> &SnapshotManifest {
&self.manifest
}
pub fn id(&self) -> u64 {
self.id
}
pub fn sstable_ids(&self) -> &[u64] {
&self.manifest.sstable_ids
}
}
pub struct SnapshotManager {
current: Mutex<Arc<SnapshotManifest>>,
next_snapshot_id: Mutex<u64>,
}
impl SnapshotManager {
pub fn new() -> Self {
Self::with_initial(SnapshotManifest::new(Vec::new()))
}
pub fn with_initial(initial: SnapshotManifest) -> Self {
Self {
current: Mutex::new(Arc::new(initial)),
next_snapshot_id: Mutex::new(0),
}
}
pub fn publish(&self, manifest: SnapshotManifest) {
*self.current.lock().unwrap() = Arc::new(manifest);
}
pub fn publish_with<F>(&self, f: F)
where
F: FnOnce(&SnapshotManifest) -> SnapshotManifest,
{
let mut guard = self.current.lock().unwrap();
let next = f(&guard);
*guard = Arc::new(next);
}
pub fn snapshot(&self) -> Snapshot {
let manifest = Arc::clone(&self.current.lock().unwrap());
let mut id = self.next_snapshot_id.lock().unwrap();
let snap_id = *id;
*id += 1;
Snapshot {
manifest,
id: snap_id,
}
}
pub fn current_ids(&self) -> Vec<u64> {
self.current.lock().unwrap().sstable_ids.clone()
}
}
impl Default for SnapshotManager {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
#[path = "snapshot_tests.rs"]
mod tests;