[][src]Struct pagecache::PageCache

pub struct PageCache<PM, P, R> where
    P: 'static + Send + Sync
{ /* fields omitted */ }

A lock-free pagecache which supports fragmented pages for dramatically improving write throughput.

Working with the PageCache

use pagecache::{pin, Materializer};

pub struct TestMaterializer;

impl Materializer for TestMaterializer {
    // The possibly fragmented page, written to log storage sequentially, and
    // read in parallel from multiple locations on disk when serving
    // a request to read the page. These will be merged to a single version
    // at read time, and possibly cached.
    type PageFrag = String;

    // The state returned by a call to `PageCache::recover`, as
    // described by `Materializer::recover`
    type Recovery = ();

    // Create a new `Materializer` with the previously recovered
    // state if any existed.
    fn new(config: pagecache::Config, last_recovery: &Option<Self::Recovery>) -> Self {
        TestMaterializer
    }

    // Used to merge chains of partial pages into a form
    // that is useful for the `PageCache` owner.
    fn merge<'a, I>(&'a self, frags: I) -> Self::PageFrag
    where
        I: IntoIterator<Item = &'a Self::PageFrag>,
    {
        frags.into_iter().fold(String::new(), |mut acc, ref s| {
            acc.push_str(&*s);
            acc
        })
    }

    // Used to feed custom recovery information back to a higher-level abstraction
    // during startup. For example, a B-Link tree must know what the current
    // root node is before it can start serving requests.
    fn recover(&self, _: &Self::PageFrag) -> Option<Self::Recovery> {
        None
    }

    // Used to determine the resident size for this item in cache.
    fn size_in_bytes(&self, frag: &String) -> usize {
        std::mem::size_of::<String>() + frag.as_bytes().len()
    }

}

fn main() {
    let config = pagecache::ConfigBuilder::new().temporary(true).build();
    let pc: pagecache::PageCache<TestMaterializer, _, _> =
        pagecache::PageCache::start(config).unwrap();
    {
        let guard = pin();
        let id = pc.allocate(&guard).unwrap();
        let mut key = pagecache::PagePtr::allocated();

        // The first item in a page should be set using replace,
        // which signals that this is the beginning of a new
        // page history, and that any previous items associated
        // with this page should be forgotten.
        key = pc.replace(id, key, "a".to_owned(), &guard).unwrap();

        // Subsequent atomic updates should be added with link.
        key = pc.link(id, key, "b".to_owned(), &guard).unwrap();
        key = pc.link(id, key, "c".to_owned(), &guard).unwrap();

        // When getting a page, the provided `Materializer` is
        // used to merge all pages together.
        let (consolidated, key) = pc.get(id, &guard).unwrap().unwrap();

        assert_eq!(*consolidated, "abc".to_owned());
    }
}

Methods

impl<PM, P, R> PageCache<PM, P, R> where
    PM: Materializer<PageFrag = P, Recovery = R>,
    PM: 'static + Send + Sync,
    P: 'static + Debug + Clone + Serialize + DeserializeOwned + Send + Sync,
    R: 'static + Debug + Clone + Serialize + DeserializeOwned + Send + Sync
[src]

pub fn start(config: Config) -> Result<PageCache<PM, P, R>, ()>
[src]

Instantiate a new PageCache.

pub fn flush(&self) -> Result<(), ()>
[src]

Flushes any pending IO buffers to disk to ensure durability.

pub fn recovered_state(&self) -> Option<R>
[src]

Return the recovered state from the snapshot

pub fn allocate<'g>(&self, guard: &'g Guard) -> Result<PageId, ()>
[src]

Create a new page, trying to reuse old freed pages if possible to maximize underlying Radix pointer density.

pub fn free<'g>(
    &self,
    pid: PageId,
    old: PagePtr<'g, P>,
    guard: &'g Guard
) -> Result<(), Option<PagePtr<'g, P>>>
[src]

Free a particular page.

Try to atomically add a PageFrag to the page. Returns Ok(new_key) if the operation was successful. Returns Err(None) if the page no longer exists. Returns Err(Some(actual_key)) if the atomic append fails.

pub fn replace<'g>(
    &self,
    pid: PageId,
    old: PagePtr<'g, P>,
    new: P,
    guard: &'g Guard
) -> Result<PagePtr<'g, P>, Option<PagePtr<'g, P>>>
[src]

Replace an existing page with a different set of PageFrags. Returns Ok(new_key) if the operation was successful. Returns Err(None) if the page no longer exists. Returns Err(Some(actual_key)) if the atomic swap fails.

pub fn get<'g>(
    &self,
    pid: PageId,
    guard: &'g Guard
) -> Result<PageGet<'g, PM::PageFrag>, Option<PagePtr<'g, P>>>
[src]

Try to retrieve a page by its logical ID.

pub fn stable_lsn(&self) -> Lsn
[src]

The highest known stable Lsn on disk.

pub fn make_stable(&self, lsn: Lsn) -> Result<(), ()>
[src]

Blocks until the provided Lsn is stable on disk, triggering necessary flushes in the process.

Trait Implementations

impl<PM, P, R> Send for PageCache<PM, P, R> where
    PM: Send + Sync,
    P: 'static + Send + Sync,
    R: Send + Sync
[src]

impl<PM, P, R> Sync for PageCache<PM, P, R> where
    PM: Send + Sync,
    P: 'static + Send + Sync,
    R: Send + Sync
[src]

impl<PM, P, R> Debug for PageCache<PM, P, R> where
    PM: Send + Sync,
    P: Debug + Send + Sync,
    R: Debug + Send + Sync
[src]

Blanket Implementations

impl<T> From for T
[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    T: From<U>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

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

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Any for T where
    T: 'static + ?Sized
[src]