pub struct PageAllocator<S = PageFile> { /* private fields */ }Expand description
A page-id allocator over a PageStore.
PageAllocator<S> is generic over its backing store; the default is
PageFile, so PageAllocator with no type parameter manages ids in a file
of pages. It is Send + Sync and every method takes &self.
The allocator owns page 0 (the superblock); the ids it returns are >= 1.
Pair it with a BufferPool over the same store — the
allocator picks ids, the pool caches the pages at those ids — but do not use
page 0 for data, and free a page only once it is no longer in use.
§Examples
use page_db::{PageAllocator, DEFAULT_PAGE_SIZE};
let alloc = PageAllocator::open(&path, DEFAULT_PAGE_SIZE)?;
let a = alloc.allocate()?; // 1
let b = alloc.allocate()?; // 2
alloc.free(a)?; // a goes on the free-list
let c = alloc.allocate()?; // reuses a
assert_eq!(c, a);
assert_ne!(b, c);
alloc.sync()?; // persist the superblock durablyImplementations§
Source§impl PageAllocator<PageFile>
impl PageAllocator<PageFile>
Sourcepub fn open<P: AsRef<Path>>(path: P, page_size: PageSize) -> PageResult<Self>
pub fn open<P: AsRef<Path>>(path: P, page_size: PageSize) -> PageResult<Self>
Open a page file and an allocator over it.
Reads the superblock if the file already has one, or initializes a fresh
one. A convenience over PageFile::open and PageAllocator::new.
§Errors
PageError::Ioif the file cannot be opened.PageError::InvalidSuperblockif page 0 exists but is not a superblock this allocator wrote.
Source§impl<S: PageStore> PageAllocator<S>
impl<S: PageStore> PageAllocator<S>
Sourcepub fn new(store: S) -> PageResult<Self>
pub fn new(store: S) -> PageResult<Self>
Build an allocator over store, reading or initializing its superblock.
§Errors
PageError::InvalidSuperblockif page 0 exists but is not a valid allocator superblock.- Whatever the store’s read or write returns.
Sourcepub fn allocate(&self) -> PageResult<PageId>
pub fn allocate(&self) -> PageResult<PageId>
Allocate an unused page id.
Reuses a freed id if the free-list is non-empty, otherwise extends the high-water mark with a never-used id. This is an in-memory operation; the returned id’s page has no defined contents until written.
§Errors
PageError::InvalidPageId only if the id space is exhausted (reachable
at 2^64 pages).
Sourcepub fn free(&self, id: PageId) -> PageResult<()>
pub fn free(&self, id: PageId) -> PageResult<()>
Return a page id to the free-list for reuse.
An in-memory push; the free-list is written to the store at the next
sync. Freeing an id that is already free is a
caller error and corrupts the free-list, exactly as with a system
allocator.
§Errors
PageError::InvalidPageId if id is the reserved superblock (0) or was
never allocated (at or beyond the high-water mark).
Sourcepub fn high_water(&self) -> u64
pub fn high_water(&self) -> u64
The next id that would be newly allocated — one past the highest id ever
handed out. Pages 1..high_water() have been allocated at some point.
Sourcepub fn free_count(&self) -> u64
pub fn free_count(&self) -> u64
The number of pages currently on the free-list, available for reuse without extending the file.
Sourcepub fn sync(&self) -> PageResult<()>
pub fn sync(&self) -> PageResult<()>
Persist the superblock and free-list chain, then make the store durable.
Writes the free-list onto its pages as an intrusive chain, records the head and high-water mark in page 0, then syncs the store. Call it as part of the checkpoint that makes the allocated pages durable (see the module docs on ordering). Cost is proportional to the free-list length.
§Errors
Whatever the store’s writes or sync return.