use std::path::Path;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
pub type Decision = bool;
pub fn h1_ttl(journal_committed_at_unix: u64) -> Decision {
let ttl_secs: u64 = crate::constants::WAL_KEEP_SECS_DEFAULT;
if ttl_secs == 0 {
return false;
}
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
let age = now.saturating_sub(journal_committed_at_unix);
age < ttl_secs
}
pub fn h2_lru_within_cap(workspace_committed_count: u64, age_rank: u64) -> Decision {
let max_count: u64 = crate::constants::WAL_MAX_COUNT_DEFAULT;
age_rank < max_count || workspace_committed_count <= max_count
}
pub fn h3_rate_limit() -> Decision {
let max_per_min: u64 = crate::constants::WAL_RATE_LIMIT_DEFAULT;
if max_per_min == 0 {
return false;
}
static WINDOW_START: AtomicU64 = AtomicU64::new(0);
static WINDOW_COUNT: AtomicU64 = AtomicU64::new(0);
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
let start = WINDOW_START.load(Ordering::Relaxed);
if now.saturating_sub(start) >= 60 {
match WINDOW_START.compare_exchange(start, now, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => {
WINDOW_COUNT.store(1, Ordering::Relaxed);
return false;
}
Err(_) => {
}
}
}
let count = WINDOW_COUNT.fetch_add(1, Ordering::Relaxed) + 1;
count > max_per_min
}
pub fn h4_sentinel(target: &Path) -> Decision {
let dir = target.parent().unwrap_or_else(|| Path::new("."));
dir.join(".atomwrite_no_wal").exists()
}
pub fn h5_archive(journal_committed_at_unix: u64) -> Decision {
let archive_days: u64 = crate::constants::WAL_ARCHIVE_DAYS_DEFAULT;
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
let age_days = now.saturating_sub(journal_committed_at_unix) / 86_400;
age_days >= archive_days
}
pub fn heuristics_should_preserve(
target: &Path,
journal_committed_at_unix: u64,
workspace_committed_count: u64,
age_rank: u64,
) -> bool {
h1_ttl(journal_committed_at_unix)
|| h2_lru_within_cap(workspace_committed_count, age_rank)
|| h3_rate_limit()
|| h4_sentinel(target)
|| h5_archive(journal_committed_at_unix)
}