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 fn refresh(&mut self, cx: &Cx) -> Result<()>
pub 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 fn create(
cx: &Cx,
file: F,
page_size: u32,
checkpoint_seq: u32,
salts: WalSalts,
) -> Result<Self>
pub 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 fn open(cx: &Cx, file: F) -> Result<Self>
pub 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 fn append_frame(
&mut self,
cx: &Cx,
page_number: u32,
page_data: &[u8],
db_size_if_commit: u32,
) -> Result<()>
pub 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 fn prepared_append_window_still_current(
&self,
cx: &Cx,
generation: WalGenerationIdentity,
start_frame_index: usize,
) -> Result<bool>
pub 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 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 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 fn append_prepared_frame_bytes(
&mut self,
cx: &Cx,
prepared_frame_bytes: &mut [u8],
frame_transforms: &[WalChecksumTransform],
) -> Result<()>
pub 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 fn append_frames(
&mut self,
cx: &Cx,
frames: &[WalAppendFrameRef<'_>],
) -> Result<()>
pub 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 fn read_frame(
&self,
cx: &Cx,
frame_index: usize,
) -> Result<(WalFrameHeader, Vec<u8>)>
pub 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 fn read_frame_into(
&self,
cx: &Cx,
frame_index: usize,
buf: &mut [u8],
) -> Result<WalFrameHeader>
pub 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 fn read_frame_header(
&self,
cx: &Cx,
frame_index: usize,
) -> Result<WalFrameHeader>
pub 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.
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.
Callers that will publish a CommitIndex MUST call this (not raw sync)
so the invariant tracker can verify ordering.
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 durable_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 at which the last successful durable sync completed.
Sourcepub fn reset(
&mut self,
cx: &Cx,
new_checkpoint_seq: u32,
new_salts: WalSalts,
truncate_file: bool,
) -> Result<()>
pub 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.
Auto Trait Implementations§
impl<F> Freeze for WalFile<F>where
F: Freeze,
impl<F> RefUnwindSafe for WalFile<F>where
F: RefUnwindSafe,
impl<F> Send for WalFile<F>
impl<F> Sync for WalFile<F>
impl<F> Unpin for WalFile<F>where
F: Unpin,
impl<F> UnsafeUnpin for WalFile<F>where
F: UnsafeUnpin,
impl<F> UnwindSafe for WalFile<F>where
F: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, _span: NoopSpan) -> Self
fn instrument(self, _span: NoopSpan) -> Self
Source§fn in_current_span(self) -> Self
fn in_current_span(self) -> Self
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more