walrus_rust/wal/
config.rs1use std::path::PathBuf;
2use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
3use std::time::SystemTime;
4
5pub(crate) static USE_FD_BACKEND: AtomicBool = AtomicBool::new(true);
7
8pub fn enable_fd_backend() {
10 USE_FD_BACKEND.store(true, Ordering::Relaxed);
11}
12
13pub fn disable_fd_backend() {
15 USE_FD_BACKEND.store(false, Ordering::Relaxed);
16}
17
18macro_rules! debug_print {
20 ($($arg:tt)*) => {
21 if std::env::var("WALRUS_QUIET").is_err() {
22 println!($($arg)*);
23 }
24 };
25}
26
27pub(crate) use debug_print;
28
29#[derive(Clone, Copy, Debug)]
30pub enum FsyncSchedule {
31 Milliseconds(u64),
32 SyncEach, NoFsync, }
35
36pub(crate) const DEFAULT_BLOCK_SIZE: u64 = 10 * 1024 * 1024; pub(crate) const BLOCKS_PER_FILE: u64 = 100;
38pub(crate) const MAX_ALLOC: u64 = 1 * 1024 * 1024 * 1024; pub(crate) const PREFIX_META_SIZE: usize = 64;
40pub(crate) const MAX_FILE_SIZE: u64 = DEFAULT_BLOCK_SIZE * BLOCKS_PER_FILE;
41pub(crate) const MAX_BATCH_ENTRIES: usize = 2000;
42pub(crate) const MAX_BATCH_BYTES: u64 = 10 * 1024 * 1024 * 1024; static LAST_MILLIS: AtomicU64 = AtomicU64::new(0);
45
46pub(crate) fn now_millis_str() -> String {
47 let system_ms = SystemTime::now()
48 .duration_since(SystemTime::UNIX_EPOCH)
49 .unwrap_or_else(|_| std::time::Duration::from_secs(0))
50 .as_millis();
51
52 let mut observed = LAST_MILLIS.load(Ordering::Relaxed);
53 loop {
54 let system_ms_u64 = system_ms.try_into().unwrap_or(u64::MAX);
55 let candidate = if system_ms_u64 <= observed {
56 observed.saturating_add(1)
57 } else {
58 system_ms_u64
59 };
60
61 match LAST_MILLIS.compare_exchange(observed, candidate, Ordering::AcqRel, Ordering::Acquire)
62 {
63 Ok(_) => return candidate.to_string(),
64 Err(actual) => observed = actual,
65 }
66 }
67}
68
69pub(crate) fn checksum64(data: &[u8]) -> u64 {
70 const FNV_OFFSET: u64 = 0xcbf29ce484222325;
72 const FNV_PRIME: u64 = 0x00000100000001B3;
73 let mut hash = FNV_OFFSET;
74 for &b in data {
75 hash ^= b as u64;
76 hash = hash.wrapping_mul(FNV_PRIME);
77 }
78 hash
79}
80
81pub(crate) fn wal_data_dir() -> PathBuf {
82 std::env::var_os("WALRUS_DATA_DIR")
83 .map(PathBuf::from)
84 .unwrap_or_else(|| PathBuf::from("wal_files"))
85}
86
87pub(crate) fn sanitize_namespace(key: &str) -> String {
88 let mut sanitized: String = key
89 .chars()
90 .map(|c| {
91 if c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.') {
92 c
93 } else {
94 '_'
95 }
96 })
97 .collect();
98
99 if sanitized.trim_matches('_').is_empty() {
100 sanitized = format!("ns_{:x}", checksum64(key.as_bytes()));
101 }
102 sanitized
103}