use std::collections::HashSet;
use serde::{Deserialize, Serialize};
use tempest_core::journal::Replayable;
#[derive(Serialize, Deserialize)]
pub(super) enum WalDataEditV1 {
AddFile(u64),
RemoveFile(u64),
Snapshot(Vec<WalDataEdit>),
}
#[repr(u8)]
#[derive(Serialize, Deserialize)]
pub(super) enum WalDataEdit {
V1(WalDataEditV1) = 1,
}
impl WalDataEdit {
pub(super) fn add_file(filenum: u64) -> Self {
Self::V1(WalDataEditV1::AddFile(filenum))
}
pub(super) fn remove_file(filenum: u64) -> Self {
Self::V1(WalDataEditV1::RemoveFile(filenum))
}
pub(super) fn snapshot(edits: Vec<Self>) -> Self {
Self::V1(WalDataEditV1::Snapshot(edits))
}
}
#[derive(Debug, Default)]
pub(super) struct WalData {
pub(super) next_filenum: u64,
pub(super) live_files: HashSet<u64>,
}
impl Replayable for WalData {
type Edit = WalDataEdit;
fn apply(&mut self, edit: Self::Edit) {
match edit {
WalDataEdit::V1(WalDataEditV1::AddFile(filenum)) => {
self.live_files.insert(filenum);
self.next_filenum = self.next_filenum.max(filenum);
}
WalDataEdit::V1(WalDataEditV1::RemoveFile(filenum)) => {
self.live_files.remove(&filenum);
}
WalDataEdit::V1(WalDataEditV1::Snapshot(snapshot)) => {
for edit in snapshot {
self.apply(edit);
}
}
}
}
fn snapshot(&self) -> Self::Edit {
let mut edits = Vec::new();
edits.extend(
self.live_files
.iter()
.map(|n| WalDataEdit::V1(WalDataEditV1::AddFile(*n))),
);
WalDataEdit::snapshot(edits)
}
fn filename_prefix() -> &'static str {
"wal-journal"
}
fn initial() -> Self {
Self::default()
}
}