Skip to main content

PageAllocator

Struct PageAllocator 

Source
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 durably

Implementations§

Source§

impl PageAllocator<PageFile>

Source

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
Source§

impl<S: PageStore> PageAllocator<S>

Source

pub fn new(store: S) -> PageResult<Self>

Build an allocator over store, reading or initializing its superblock.

§Errors
Source

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).

Source

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).

Source

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.

Source

pub fn free_count(&self) -> u64

The number of pages currently on the free-list, available for reuse without extending the file.

Source

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.

Auto Trait Implementations§

§

impl<S = PageFile> !Freeze for PageAllocator<S>

§

impl<S> RefUnwindSafe for PageAllocator<S>
where S: RefUnwindSafe,

§

impl<S> Send for PageAllocator<S>
where S: Send,

§

impl<S> Sync for PageAllocator<S>
where S: Sync,

§

impl<S> Unpin for PageAllocator<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for PageAllocator<S>
where S: UnsafeUnpin,

§

impl<S> UnwindSafe for PageAllocator<S>
where S: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.