use crate::backend::native::NativeBackendError;
use crate::backend::native::NativeResult;
use crate::backend::native::v3::constants::checksum;
use crate::backend::native::v3::header::PersistentHeaderV3;
use bincode;
use serde::{Deserialize, Serialize};
mod checkpoint;
mod header_support;
mod record_support;
mod recovery;
#[cfg(test)]
mod tests;
mod writer;
pub use checkpoint::{read_kv_checkpoint, write_kv_checkpoint};
pub use recovery::{WALRecovery, WALRecoveryStats};
pub use writer::{V3WALPaths, WALWriter};
pub const V3_WAL_MAGIC: [u8; 8] = [b'V', b'3', b'W', b'A', b'L', 0, 0, 0];
pub const V3_WAL_VERSION: u32 = 1;
pub const V3_WAL_HEADER_SIZE: usize = 64;
pub const MAX_RECORD_SIZE: usize = 1024 * 1024;
pub const LSN_BEGIN: u64 = 1;
pub const LSN_INVALID: u64 = 0;
#[inline]
pub fn lsn_is_valid(lsn: u64) -> bool {
lsn >= LSN_BEGIN
}
#[inline]
pub fn lsn_next(lsn: u64) -> u64 {
lsn.wrapping_add(1)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub struct V3WALHeader {
pub magic: [u8; 8],
pub version: u32,
pub page_size: u32,
pub created_at: u64,
pub current_lsn: u64,
pub committed_lsn: u64,
pub checkpointed_lsn: u64,
pub reserved: [u64; 3],
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum V3WALRecordType {
PageAllocate = 1,
PageFree = 2,
PageWrite = 3,
BTreeSplit = 4,
Checkpoint = 5,
TransactionBegin = 6,
TransactionCommit = 7,
TransactionRollback = 8,
KvSet = 9,
KvDelete = 10,
KvTombstone = 11,
EdgeInsert = 12,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum V3WALRecord {
PageAllocate {
lsn: u64,
page_id: u64,
timestamp: u64,
},
PageFree {
lsn: u64,
page_id: u64,
checksum: u32,
timestamp: u64,
},
PageWrite {
lsn: u64,
page_id: u64,
offset: u32,
data: Vec<u8>,
checksum: u32,
timestamp: u64,
},
BTreeSplit {
lsn: u64,
original_page_id: u64,
new_page_id: u64,
split_key: u64,
page_type: u8, timestamp: u64,
},
Checkpoint {
lsn: u64,
root_page_id: u64,
total_pages: u64,
btree_height: u32,
free_page_list_head: u64,
header_snapshot: Vec<u8>, timestamp: u64,
},
TransactionBegin {
tx_id: u64,
lsn: u64,
timestamp: u64,
},
TransactionCommit {
tx_id: u64,
lsn: u64,
timestamp: u64,
},
TransactionRollback {
tx_id: u64,
lsn: u64,
timestamp: u64,
},
KvSet {
lsn: u64,
key: Vec<u8>,
value_bytes: Vec<u8>,
value_type: u8,
ttl_seconds: Option<u64>,
timestamp: u64,
},
KvDelete {
lsn: u64,
key: Vec<u8>,
timestamp: u64,
},
KvTombstone {
lsn: u64,
key: Vec<u8>,
old_value_bytes: Option<Vec<u8>>,
old_value_type: u8,
timestamp: u64,
},
EdgeInsert {
lsn: u64,
src: i64,
dst: i64,
direction: u8,
page_id: u64,
timestamp: u64,
},
}