persistent_kv/snapshot_set/
mod.rs

1pub mod admin;
2pub mod file_snapshot_set;
3
4use std::{io, path::PathBuf};
5
6/// Classifications of different snapshot files (used in conjunction with SnapshotSet)
7#[derive(PartialEq, Clone, Debug, Copy)]
8pub enum SnapshotType {
9    /// A differential snapshot containing set and unset operations in sequence.
10    /// Used for write-ahead-log snapshot files.
11    Diff,
12    /// A full snapshot containing all key-value pairs at a given point in time,
13    /// assessed as complete and up-to-date i.e. the latest snapshot of this type.
14    FullCompleted,
15    /// A snapshot that did not complete successfully, e.g. due to a power failure
16    /// or process panic. This snapshot is incomplete and should not be used.
17    Pending,
18}
19
20/// Ordinal number type used for sequencing snapshots. Snapshots with higher ordinal numbers must
21/// be applied after snapshots with lower ordinal numbers. Shards of the same snapshot can be
22/// applied in parallel.
23#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Copy)]
24pub struct SnapshotOrdinal(pub u64);
25
26impl std::fmt::Display for SnapshotOrdinal {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        write!(f, "{}", self.0)
29    }
30}
31
32/// Information about a snapshot. Always matches the state on disk, i.e. if a snapshot has
33/// a SnapshotInfo instance the corresponding files also exist, though they may be empty.
34#[derive(Clone, PartialEq, Debug)]
35pub struct SnapshotInfo {
36    pub snapshot_type: SnapshotType,
37    pub ordinal: SnapshotOrdinal,
38    // Paths to the different shards that make up the snapshot. Shards are guaranteed
39    // to contain distinct keys and can thus be read in parallel.
40    //
41    // Shards are usually placed in numbered files containing the index and shard count.
42    // However, once a snapshot is parsed, this information should no longer be used
43    // and shard_paths is the canonical source of the ordering and number of shards.
44    // This ensures we support recovery from broken state.
45    pub shard_paths: Vec<PathBuf>,
46}
47
48impl SnapshotInfo {
49    #[cfg(test)]
50    pub fn single_shard_path(&self) -> PathBuf {
51        assert!(
52            self.shard_paths.len() == 1,
53            "This snapshotInfo should have exactly one path"
54        );
55        self.shard_paths[0].clone()
56    }
57}
58
59/// A set of snapshot files, used to manage and query snapshots in a given folder.
60/// Provides operations to query snapshots that exist with their types and to add
61/// new snapshot file (names) to the set.
62///
63/// This type only manages file names and creates/removes files as a whole, it does
64/// not actually read/write snapshots _contents_.
65pub trait SnapshotSet: Send {
66    /// Registers a new snapshot path usable for the given snapshot type.
67    /// This will return a new snapshot path that can be used to write the snapshot to.
68    ///
69    /// If `may_append_existing` is set to true, an existing snapshot file may be returned
70    /// if there is no (completed) full snapshot with a higher ordinal.
71    ///
72    /// A new snapshot file will have a ordinal higher than all previous snapshots.
73    /// A new shapshot file will be created with empty contents.
74    fn create_or_get_snapshot(
75        &mut self,
76        snapshot_type: SnapshotType,
77        shard_count: u64,
78        may_append_existing: bool,
79    ) -> Result<SnapshotInfo, io::Error>;
80
81    /// Publishes a pending snapshot as a full snapshot. This will rename the snapshot file
82    /// to indicate that it is a full snapshot and considered complete.
83    /// `purge_obsolete_diff_snapshots` specifies if differential snapshots that
84    /// are now obsolete should be auto-deleted.
85    /// `purge_obsolete_pending_snapshots` specifies if pending snapshots that
86    /// precede the now completed snapshot should be auto-deleted.
87    fn publish_completed_snapshot(
88        &mut self,
89        pending_snapshot_ordinal: SnapshotOrdinal,
90        purge_obsolete_diff_snapshots: bool,
91        purge_obsolete_pending_snapshots: bool,
92    ) -> Result<(), io::Error>;
93
94    /// Returns all snapshots that need to be restored in order to get the latest state.
95    /// This includes the latest full snapshot and all differential snapshots since then.
96    fn get_snapshots_to_restore(&self) -> Vec<&SnapshotInfo>;
97}
98
99/// Primary file based implementation of the SnapshotSet trait.
100pub use file_snapshot_set::FileSnapshotSet;