use std::path::Path;
use serde::{Deserialize, Serialize};
use super::{JournalOp, L1_LARGE_FILE_BYTES};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, clap::ValueEnum)]
#[serde(rename_all = "snake_case")]
#[clap(rename_all = "snake_case")]
pub enum WalPolicy {
#[default]
Auto,
Always,
Never,
}
impl WalPolicy {
pub const fn as_str(&self) -> &'static str {
match self {
Self::Auto => "auto",
Self::Always => "always",
Self::Never => "never",
}
}
}
pub fn should_create_sidecar(target: &Path, op: JournalOp, policy: WalPolicy) -> bool {
match policy {
WalPolicy::Never => false,
WalPolicy::Always => true,
WalPolicy::Auto => {
let size = std::fs::metadata(target).map(|m| m.len()).unwrap_or(0);
if size > L1_LARGE_FILE_BYTES {
return true;
}
if matches!(op, JournalOp::Edit | JournalOp::Replace) {
return true;
}
if !directory_is_git_tracked(target) {
return true;
}
if size <= crate::constants::WAL_SMALL_RECORD_BYTES {
return false;
}
false
}
}
}
fn directory_is_git_tracked(target: &Path) -> bool {
let start = target.parent().unwrap_or_else(|| Path::new("."));
let mut current = Some(start);
let mut depth = 0u8;
while let Some(dir) = current {
if dir.join(".git").exists() {
return true;
}
depth += 1;
if depth > 16 {
return false;
}
current = dir.parent();
}
false
}