Skip to main content

BufferPool

Struct BufferPool 

Source
pub struct BufferPool<S = PageFile> { /* private fields */ }
Expand description

A bounded cache of pages over a PageStore.

BufferPool<S> is generic over its backing store; the default is PageFile, so BufferPool without a type parameter is a pool over a file of pages. The handle is Send + Sync and every method takes &self, so it is shared across threads behind an Arc with no outer lock.

§Examples

use page_db::{BufferPool, PageId, Lsn, DEFAULT_PAGE_SIZE};

// A pool of 128 frames over a 4 KiB-page file.
let pool = BufferPool::open(&path, DEFAULT_PAGE_SIZE, 128)?;

// Create page 0, write to it (which marks it dirty), then release the pin.
{
    let guard = pool.new_page(PageId::new(0))?;
    let mut page = guard.write();
    page.set_lsn(Lsn::new(1));
    page.payload_mut()[..5].copy_from_slice(b"hello");
}

// Flush dirty pages to the file and make them durable.
pool.flush_all()?;
pool.sync()?;

// Fetch it back — served from cache if resident, else read from the file.
let guard = pool.fetch(PageId::new(0))?;
assert_eq!(&guard.read().payload()[..5], b"hello");

Implementations§

Source§

impl BufferPool<PageFile>

Source

pub fn open<P: AsRef<Path>>( path: P, page_size: PageSize, capacity: usize, ) -> PageResult<Self>

Open a page file and wrap it in a pool of capacity frames.

A convenience over PageFile::open followed by BufferPool::new.

§Errors

Returns PageError::Io if the file cannot be opened.

Source§

impl<S: PageStore> BufferPool<S>

Source

pub fn new(store: S, capacity: usize) -> Self

Build a pool of capacity frames over store.

capacity is the number of pages held resident; it is clamped up to at least one. The frame buffers are allocated once, here — the pool does no per-request allocation on the hot path.

Source

pub fn capacity(&self) -> usize

The number of frames in the pool.

Source

pub fn resident_len(&self) -> usize

The number of pages currently resident.

Source

pub fn is_resident(&self, id: PageId) -> bool

Whether page id is currently held in the pool.

Source

pub fn fetch(&self, id: PageId) -> PageResult<PageGuard>

Fetch the page at id, pinning it and returning a guard.

Served from cache if resident; otherwise a frame is found (a free one, or an evicted victim, flushing it first if dirty) and the page is read from the store into it. The returned PageGuard holds a pin for its lifetime.

§Errors
Source

pub fn new_page(&self, id: PageId) -> PageResult<PageGuard>

Introduce a fresh, zeroed page at id, pinning it and returning a guard.

The page is created in memory and marked dirty, so it is written to the store on the next flush; no read is performed. If id is already resident it is reset to a blank page. The caller chooses the id — the free-list allocator that picks ids is a later release.

§Errors
Source

pub fn flush(&self, id: PageId) -> PageResult<()>

Flush page id to the store if it is resident and dirty.

This places the bytes in the store; call sync to make them durable. Do not call this while holding a write guard to the same page on the same thread — flushing takes the frame’s lock.

§Errors

Whatever the store’s write returns.

Source

pub fn flush_all(&self) -> PageResult<()>

Flush every dirty resident page to the store.

§Errors

Whatever the store’s write returns. On error, some pages may already have been flushed; the operation is safe to retry.

Source

pub fn checkpoint(&self) -> PageResult<()>

Flush all dirty pages, then make the store durable.

Equivalent to flush_all followed by sync — the common checkpoint sequence.

§Errors

Whatever flushing or the store’s sync returns.

Source

pub fn sync(&self) -> PageResult<()>

Make the store durable (the pages already written to it).

This does not flush dirty cached pages first; use flush_all or checkpoint for that.

§Errors

Whatever the store’s sync returns.

Auto Trait Implementations§

§

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

§

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

§

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

§

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

§

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

§

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

§

impl<S> UnwindSafe for BufferPool<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.