pub struct WalFile<F: VfsFile> { /* private fields */ }Expand description
A WAL file backed by a VFS file handle.
Manages the write-ahead log: creation, sequential frame append with checksum chain integrity, frame reads, and reset after checkpoint.
Implementations§
Source§impl<F: VfsFile> WalFile<F>
impl<F: VfsFile> WalFile<F>
Sourcepub async fn refresh(&mut self, cx: &Cx) -> Result<()>
pub async fn refresh(&mut self, cx: &Cx) -> Result<()>
Re-synchronize this handle with the on-disk WAL if another writer has appended frames or reset/truncated the file.
This keeps frame_count and running_checksum coherent across
multiple concurrently-open WalFile handles.
Sourcepub fn frame_size(&self) -> usize
pub fn frame_size(&self) -> usize
Size in bytes of a single frame (header + page data).
Sourcepub fn frame_count(&self) -> usize
pub fn frame_count(&self) -> usize
Number of valid frames in the WAL.
Sourcepub fn generation_identity(&self) -> WalGenerationIdentity
pub fn generation_identity(&self) -> WalGenerationIdentity
The current WAL generation identity (checkpoint_seq + salts).
Sourcepub fn big_endian_checksum(&self) -> bool
pub fn big_endian_checksum(&self) -> bool
Whether the WAL uses big-endian checksum words.
Sourcepub fn running_checksum(&self) -> SqliteWalChecksum
pub fn running_checksum(&self) -> SqliteWalChecksum
The current rolling checksum (after the last valid frame, or header seed).
Sourcepub async fn create(
cx: &Cx,
file: F,
page_size: u32,
checkpoint_seq: u32,
salts: WalSalts,
) -> Result<Self>
pub async fn create( cx: &Cx, file: F, page_size: u32, checkpoint_seq: u32, salts: WalSalts, ) -> Result<Self>
Create a new WAL file, writing the 32-byte header.
The file should already be opened via the VFS. This overwrites any existing content by writing the header at offset 0 and truncating.
Sourcepub async fn open(cx: &Cx, file: F) -> Result<Self>
pub async fn open(cx: &Cx, file: F) -> Result<Self>
Open an existing WAL file by reading and validating its header, then scanning frames to determine the valid frame count and running checksum.
Sourcepub fn advance_state_after_write(
&mut self,
frames_written: usize,
new_running_checksum: SqliteWalChecksum,
) -> Result<()>
pub fn advance_state_after_write( &mut self, frames_written: usize, new_running_checksum: SqliteWalChecksum, ) -> Result<()>
Advance the internal WAL state after a direct, consolidated file write.
This avoids re-reading the written frames just to update bookkeeping. The caller must guarantee the frames were successfully synced to disk and that the provided checksum exactly matches the end of the chain.
Sourcepub async fn append_frame(
&mut self,
cx: &Cx,
page_number: u32,
page_data: &[u8],
db_size_if_commit: u32,
) -> Result<()>
pub async fn append_frame( &mut self, cx: &Cx, page_number: u32, page_data: &[u8], db_size_if_commit: u32, ) -> Result<()>
Append a frame to the WAL.
page_number is the database page this frame writes.
page_data must be exactly page_size bytes.
db_size_if_commit should be the database size in pages for commit
frames, or 0 for non-commit frames.
Sourcepub fn prepare_frame_bytes(
&self,
frames: &[WalAppendFrameRef<'_>],
) -> Result<Vec<u8>>
pub fn prepare_frame_bytes( &self, frames: &[WalAppendFrameRef<'_>], ) -> Result<Vec<u8>>
Serialize a frame batch into contiguous WAL bytes without writing the rolling checksum chain.
This lets higher layers move header/payload copy work out of a serialized append window while preserving the requirement that checksum chaining still uses the live on-disk seed at append time.
Sourcepub fn prepare_frame_bytes_with_transforms_into<'a, I>(
&self,
frame_count: usize,
frames: I,
frame_buf: &mut Vec<u8>,
checksum_transforms: &mut Vec<WalChecksumTransform>,
) -> Result<Option<usize>>where
I: IntoIterator<Item = WalAppendFrameRef<'a>>,
pub fn prepare_frame_bytes_with_transforms_into<'a, I>(
&self,
frame_count: usize,
frames: I,
frame_buf: &mut Vec<u8>,
checksum_transforms: &mut Vec<WalChecksumTransform>,
) -> Result<Option<usize>>where
I: IntoIterator<Item = WalAppendFrameRef<'a>>,
Serialize a batch of frames into caller-owned storage and precompute the per-frame checksum transforms in the same pass.
This lets higher layers reserve the buffer up front and avoid both an
intermediate Vec<WalAppendFrameRef> and a later whole-batch checksum
transform walk over the serialized bytes.
Sourcepub async fn prepared_append_window_still_current(
&self,
cx: &Cx,
generation: WalGenerationIdentity,
start_frame_index: usize,
) -> Result<bool>
pub async fn prepared_append_window_still_current( &self, cx: &Cx, generation: WalGenerationIdentity, start_frame_index: usize, ) -> Result<bool>
Check whether the on-disk WAL still matches a previously observed append window.
This is a cheap ABA-resistant probe used after a pre-lock finalize pass. If the generation identity and frame count still match, no other writer could have changed the append seed or target offset.
Sourcepub fn finalize_prepared_frame_bytes(
&self,
prepared_frame_bytes: &mut [u8],
frame_transforms: &[WalChecksumTransform],
) -> Result<SqliteWalChecksum>
pub fn finalize_prepared_frame_bytes( &self, prepared_frame_bytes: &mut [u8], frame_transforms: &[WalChecksumTransform], ) -> Result<SqliteWalChecksum>
Finalize a previously prepared frame buffer against the current live rolling checksum seed.
This mutates the frame checksum fields in-place and returns the final running checksum that should become authoritative after the eventual durable append succeeds.
Sourcepub async fn append_finalized_prepared_frame_bytes(
&mut self,
cx: &Cx,
prepared_frame_bytes: &[u8],
frame_count: usize,
final_running_checksum: SqliteWalChecksum,
last_commit_offset: Option<usize>,
) -> Result<()>
pub async fn append_finalized_prepared_frame_bytes( &mut self, cx: &Cx, prepared_frame_bytes: &[u8], frame_count: usize, final_running_checksum: SqliteWalChecksum, last_commit_offset: Option<usize>, ) -> Result<()>
Append a batch whose frame bytes were already finalized against the current append window.
Sourcepub async fn append_finalized_prepared_frame_bytes_tracked(
&mut self,
cx: &Cx,
prepared_frame_bytes: &[u8],
frame_count: usize,
final_running_checksum: SqliteWalChecksum,
last_commit_offset: Option<usize>,
completion: VfsWriteCompletion,
) -> Result<()>
pub async fn append_finalized_prepared_frame_bytes_tracked( &mut self, cx: &Cx, prepared_frame_bytes: &[u8], frame_count: usize, final_running_checksum: SqliteWalChecksum, last_commit_offset: Option<usize>, completion: VfsWriteCompletion, ) -> Result<()>
Append a finalized frame batch while retaining source-level write proof.
The caller may keep a clone of completion across cancellation. A
Pending state is in-doubt, never proof that no WAL bytes were written.
Sourcepub async fn append_prepared_frame_bytes(
&mut self,
cx: &Cx,
prepared_frame_bytes: &mut [u8],
frame_transforms: &[WalChecksumTransform],
) -> Result<()>
pub async fn append_prepared_frame_bytes( &mut self, cx: &Cx, prepared_frame_bytes: &mut [u8], frame_transforms: &[WalChecksumTransform], ) -> Result<()>
Finalize checksums for a previously prepared frame buffer and append it.
prepared_frame_bytes must contain frame_transforms.len() frame
records in WAL frame layout with page number, db_size, salts, and
payload already serialized. The checksum bytes are overwritten in-place
using the live rolling checksum seed from this WAL handle.
Sourcepub async fn append_prepared_frame_bytes_tracked(
&mut self,
cx: &Cx,
prepared_frame_bytes: &mut [u8],
frame_transforms: &[WalChecksumTransform],
completion: VfsWriteCompletion,
) -> Result<()>
pub async fn append_prepared_frame_bytes_tracked( &mut self, cx: &Cx, prepared_frame_bytes: &mut [u8], frame_transforms: &[WalChecksumTransform], completion: VfsWriteCompletion, ) -> Result<()>
Finalize and append prepared frame bytes with source-level write proof.
Sourcepub async fn append_frames(
&mut self,
cx: &Cx,
frames: &[WalAppendFrameRef<'_>],
) -> Result<()>
pub async fn append_frames( &mut self, cx: &Cx, frames: &[WalAppendFrameRef<'_>], ) -> Result<()>
Append a batch of frames to the WAL using a single contiguous write.
This preserves the checksum chain while avoiding per-frame write
syscalls on hot commit paths. Durability is still controlled by
Self::sync or a higher-level caller.
Sourcepub async fn append_frames_tracked(
&mut self,
cx: &Cx,
frames: &[WalAppendFrameRef<'_>],
completion: VfsWriteCompletion,
) -> Result<()>
pub async fn append_frames_tracked( &mut self, cx: &Cx, frames: &[WalAppendFrameRef<'_>], completion: VfsWriteCompletion, ) -> Result<()>
Append a frame batch with a caller-retained source completion token.
Sourcepub async fn read_frame(
&self,
cx: &Cx,
frame_index: usize,
) -> Result<(WalFrameHeader, Vec<u8>)>
pub async fn read_frame( &self, cx: &Cx, frame_index: usize, ) -> Result<(WalFrameHeader, Vec<u8>)>
Read a frame by 0-based index, returning header and page data.
Sourcepub async fn read_frame_into(
&self,
cx: &Cx,
frame_index: usize,
buf: &mut [u8],
) -> Result<WalFrameHeader>
pub async fn read_frame_into( &self, cx: &Cx, frame_index: usize, buf: &mut [u8], ) -> Result<WalFrameHeader>
Read a frame into a provided buffer, returning the header.
buf must be at least frame_size bytes. The frame header is parsed
from the beginning of the buffer, and the page data follows immediately
after at offset WAL_FRAME_HEADER_SIZE.
Sourcepub async fn read_frame_header(
&self,
cx: &Cx,
frame_index: usize,
) -> Result<WalFrameHeader>
pub async fn read_frame_header( &self, cx: &Cx, frame_index: usize, ) -> Result<WalFrameHeader>
Read just the frame header at a given 0-based index.
Sourcepub fn last_commit_frame(&mut self, cx: &Cx) -> Result<Option<usize>>
pub fn last_commit_frame(&mut self, cx: &Cx) -> Result<Option<usize>>
Find the last commit frame index, or None if there are no commits.
Sourcepub fn sync(&mut self, cx: &Cx, flags: SyncFlags) -> Result<()>
pub fn sync(&mut self, cx: &Cx, flags: SyncFlags) -> Result<()>
Sync the WAL file to stable storage and record every appended frame covered by the successful sync for the two-phase publish invariant.
Sourcepub fn repair_uncommitted_tail(&mut self, cx: &Cx) -> Result<()>
pub fn repair_uncommitted_tail(&mut self, cx: &Cx) -> Result<()>
Remove every physical byte after the checksum-valid committed prefix represented by this handle.
Callers must first refresh the handle while holding the external writer gate. This is the recovery-side counterpart to append completion tracking: a terminal write error can still leave a partial frame or a complete but uncommitted interval, neither of which may be reused as an append base.
Sourcepub fn durable_sync(&mut self, cx: &Cx, kind: SyncKind) -> Result<()>
pub fn durable_sync(&mut self, cx: &Cx, kind: SyncKind) -> Result<()>
Durability-intent sync: makes all appended frames durable and records the fsynced frame count for the two-phase commit invariant.
This is the intent-preserving form of Self::sync. Both successful
sync paths advance the invariant tracker before a caller can publish.
Sourcepub fn assert_publish_safe(&self, publish_frame_count: usize) -> Result<()>
pub fn assert_publish_safe(&self, publish_frame_count: usize) -> Result<()>
Assert that it is safe to publish frames up to publish_frame_count
— i.e. that a successful sync has already completed covering those frames.
Under debug-assertions this panics. In release mode, it returns an error
only when FRANKENSQLITE_PARANOID_DURABILITY=1 is set.
Sourcepub fn last_fsynced_frame_count(&self) -> usize
pub fn last_fsynced_frame_count(&self) -> usize
The frame count covered by the last successful WAL sync.
Sourcepub async fn reset(
&mut self,
cx: &Cx,
new_checkpoint_seq: u32,
new_salts: WalSalts,
truncate_file: bool,
) -> Result<()>
pub async fn reset( &mut self, cx: &Cx, new_checkpoint_seq: u32, new_salts: WalSalts, truncate_file: bool, ) -> Result<()>
Reset the WAL for a new checkpoint generation.
Writes a new header with updated checkpoint sequence and salts,
and resets the running checksum and frame count to zero.
If truncate_file is true, also truncates the file to header-only.