pub struct Pager {
pub db_file: Arc<dyn DatabaseStorage>,
pub io: Arc<dyn IO>,
pub db_header: Arc<SpinLock<DatabaseHeader>>,
pub savepoints: RefCell<Vec<SavepointFrame>>,
/* private fields */
}Expand description
The pager interface implements the persistence layer by providing access to pages of the database file, including caching, concurrency control, and transaction management.
Fields§
§db_file: Arc<dyn DatabaseStorage>Source of the database pages.
io: Arc<dyn IO>I/O interface for input/output operations.
db_header: Arc<SpinLock<DatabaseHeader>>§savepoints: RefCell<Vec<SavepointFrame>>Stack of active savepoints for SAVEPOINT / ROLLBACK TO / RELEASE.
Implementations§
Source§impl Pager
impl Pager
Sourcepub fn begin_open(
db_file: Arc<dyn DatabaseStorage>,
) -> Result<Arc<SpinLock<DatabaseHeader>>>
pub fn begin_open( db_file: Arc<dyn DatabaseStorage>, ) -> Result<Arc<SpinLock<DatabaseHeader>>>
Begins opening a database by reading the database header.
Sourcepub fn finish_open(
db_header_ref: Arc<SpinLock<DatabaseHeader>>,
db_file: Arc<dyn DatabaseStorage>,
wal: Rc<RefCell<dyn Wal>>,
io: Arc<dyn IO>,
page_cache: Arc<RwLock<DumbLruPageCache>>,
buffer_pool: Rc<BufferPool>,
) -> Result<Self>
pub fn finish_open( db_header_ref: Arc<SpinLock<DatabaseHeader>>, db_file: Arc<dyn DatabaseStorage>, wal: Rc<RefCell<dyn Wal>>, io: Arc<dyn IO>, page_cache: Arc<RwLock<DumbLruPageCache>>, buffer_pool: Rc<BufferPool>, ) -> Result<Self>
Completes opening a database by initializing the Pager with the database header.
pub fn get_auto_vacuum_mode(&self) -> AutoVacuumMode
pub fn set_auto_vacuum_mode(&self, mode: AutoVacuumMode)
pub fn get_synchronous_mode(&self) -> SynchronousMode
pub fn set_synchronous_mode(&self, mode: SynchronousMode)
Sourcepub fn ptrmap_get(
&self,
target_page_num: u32,
) -> Result<CursorResult<Option<PtrmapEntry>>>
pub fn ptrmap_get( &self, target_page_num: u32, ) -> Result<CursorResult<Option<PtrmapEntry>>>
Retrieves the pointer map entry for a given database page.
target_page_num (1-indexed) is the page whose entry is sought.
Returns Ok(None) if the page is not supposed to have a ptrmap entry (e.g. header, or a ptrmap page itself).
Sourcepub fn ptrmap_put(
&self,
db_page_no_to_update: u32,
entry_type: PtrmapType,
parent_page_no: u32,
) -> Result<CursorResult<()>>
pub fn ptrmap_put( &self, db_page_no_to_update: u32, entry_type: PtrmapType, parent_page_no: u32, ) -> Result<CursorResult<()>>
Writes or updates the pointer map entry for a given database page.
db_page_no_to_update (1-indexed) is the page whose entry is to be set.
entry_type and parent_page_no define the new entry.
Sourcepub fn btree_create(
&self,
flags: &CreateBTreeFlags,
) -> Result<CursorResult<u32>>
pub fn btree_create( &self, flags: &CreateBTreeFlags, ) -> Result<CursorResult<u32>>
This method is used to allocate a new root page for a btree, both for tables and indexes FIXME: handle no room in page cache
Sourcepub fn allocate_overflow_page(&self) -> PageRef
pub fn allocate_overflow_page(&self) -> PageRef
Allocate a new overflow page. This is done when a cell overflows and new space is needed.
Sourcepub fn do_allocate_page(
&self,
page_type: PageType,
offset: usize,
_alloc_mode: BtreePageAllocMode,
) -> Arc<BTreePageInner> ⓘ
pub fn do_allocate_page( &self, page_type: PageType, offset: usize, _alloc_mode: BtreePageAllocMode, ) -> Arc<BTreePageInner> ⓘ
Allocate a new page to the btree via the pager. This marks the page as dirty and writes the page header.
Sourcepub fn usable_space(&self) -> usize
pub fn usable_space(&self) -> usize
The “usable size” of a database page is the page size specified by the 2-byte integer at offset 16 in the header, minus the “reserved” space size recorded in the 1-byte integer at offset 20 in the header. The usable size of a page might be an odd number. However, the usable size is not allowed to be less than 480. In other words, if the page size is 512, then the reserved space size cannot exceed 32.
pub fn begin_read_tx(&self) -> Result<LimboResult>
pub fn begin_write_tx(&self) -> Result<LimboResult>
pub fn end_tx(&self) -> Result<PagerCacheflushStatus>
pub fn end_read_tx(&self) -> Result<()>
Sourcepub fn read_page(&self, page_idx: usize) -> Result<PageRef, LimboError>
pub fn read_page(&self, page_idx: usize) -> Result<PageRef, LimboError>
Reads a page from the database.
Sourcepub fn write_database_header(&self, header: &DatabaseHeader) -> Result<()>
pub fn write_database_header(&self, header: &DatabaseHeader) -> Result<()>
Writes the database header.
Sourcepub fn refresh_header_from_wal(&self) -> Result<()>
pub fn refresh_header_from_wal(&self) -> Result<()>
Refresh the shared in-memory database header from the write-ahead log.
The header occupies the first 100 bytes of page 1. At open time the
header is read straight from the main database file (see
Pager::begin_open / sqlite3_ondisk::begin_read_database_header),
which deliberately bypasses the WAL. Every other page is read through
Pager::read_page, which consults the WAL via
crate::storage::wal::Wal::find_frame. That asymmetry means a page-1
change that has been committed to the WAL but not yet checkpointed back
into the main file (the normal state after a non-checkpointing close)
is invisible to the header — so cookies written via PRAGMA application_id / PRAGMA user_version reset to their pre-write value on
reopen even though they are durably recorded in the WAL.
This routine closes that gap the way SQLite itself resolves the header: if the WAL holds a frame for page 1, page 1 is read through the WAL-aware pager path and the shared header is re-decoded from that frame. When the WAL has no page-1 frame the header read from the main file at open time is already authoritative and the call is a no-op.
It is intended to be invoked once, immediately after the shared WAL has been opened/recovered, before any connection observes the header.
Sourcepub fn change_page_cache_size(
&self,
capacity: usize,
) -> Result<CacheResizeResult>
pub fn change_page_cache_size( &self, capacity: usize, ) -> Result<CacheResizeResult>
Changes the size of the page cache.
pub fn add_dirty(&self, page_id: usize)
pub fn wal_frame_count(&self) -> Result<u64>
Sourcepub fn cacheflush(&self) -> Result<PagerCacheflushStatus>
pub fn cacheflush(&self) -> Result<PagerCacheflushStatus>
Flush dirty pages to disk. In the base case, it will write the dirty pages to the WAL and then fsync the WAL. If the WAL size is over the checkpoint threshold, it will checkpoint the WAL to the database file and then fsync the database file.
pub fn wal_get_frame( &self, frame_no: u32, p_frame: *mut u8, frame_len: u32, ) -> Result<Arc<Completion>>
pub fn checkpoint(&self) -> Result<CheckpointStatus>
Sourcepub fn clear_page_cache(&self)
pub fn clear_page_cache(&self)
Invalidates entire page cache by removing all dirty and clean pages. Usually used in case of a rollback or in case we want to invalidate page cache after starting a read transaction right after new writes happened which would invalidate current page cache.
Sourcepub fn rollback(&self)
pub fn rollback(&self)
Roll back the current write transaction.
Clears all dirty pages from the page cache, resets in-flight flush and checkpoint state machines to their idle state, and delegates to the WAL to undo any frames appended during this transaction.
Sourcepub fn open_savepoint(&self, name: String, is_txn_owner: bool) -> Result<()>
pub fn open_savepoint(&self, name: String, is_txn_owner: bool) -> Result<()>
Open a new named savepoint by capturing the current WAL frame state.
All currently dirty pages are first flushed to WAL so that the
pre-savepoint state is recorded as actual WAL frames. ROLLBACK TO
can then restore to this point by pruning frames written after the
savepoint and clearing the page cache.
is_txn_owner should be true when this savepoint implicitly started
the surrounding write transaction (i.e., opened in autocommit mode).
Sourcepub fn rollback_to_savepoint(&self, name: &str) -> Result<()>
pub fn rollback_to_savepoint(&self, name: &str) -> Result<()>
Roll back to a previously opened savepoint (ROLLBACK TO SAVEPOINT).
Truncates the WAL to the savepoint’s frame watermark, clears the page cache, and resets the flush state machine — exactly as a full rollback does, but scoped to the savepoint boundary. The savepoint itself remains valid so subsequent writes can continue within the transaction.
Nested savepoints opened after the target are discarded.
Sourcepub fn release_savepoint(&self, name: &str) -> Result<bool>
pub fn release_savepoint(&self, name: &str) -> Result<bool>
Release a savepoint (RELEASE SAVEPOINT).
Removes the named savepoint and all savepoints opened after it from the
stack. Returns true when the released savepoint was the implicit
transaction owner — the caller must then commit the transaction.
pub fn checkpoint_shutdown(&self) -> Result<()>
pub fn wal_checkpoint(&self) -> CheckpointResult
Sourcepub fn wal_checkpoint_mode(
&self,
mode: CheckpointMode,
) -> Result<CheckpointResult>
pub fn wal_checkpoint_mode( &self, mode: CheckpointMode, ) -> Result<CheckpointResult>
Run a blocking checkpoint in the given mode (used by close()/Drop and by
PRAGMA wal_checkpoint(<MODE>) at the pager level). Unlike
Self::wal_checkpoint, this never panics and returns a Result.