pub struct PageCache<PM, P, R>where
PM: Materializer<PageFrag = P, Recovery = R> + Send + Sync,
P: 'static + Debug + PartialEq + Clone + Serialize + DeserializeOwned + Send + Sync,
R: Debug + PartialEq + Clone + Serialize + DeserializeOwned + Send,{ /* private fields */ }Expand description
lock-free pagecache A lock-free pagecache which supports fragmented pages for dramatically improving write throughput.
§Working with the PageCache
extern crate rsdb;
use rsdb::Materializer;
pub struct TestMaterializer;
impl Materializer for TestMaterializer {
type PageFrag = String;
type Recovery = ();
fn merge(&self, frags: &[&String]) -> String {
let mut consolidated = String::new();
for frag in frags.into_iter() {
consolidated.push_str(&*frag);
}
consolidated
}
fn recover(&self, _: &String) -> Option<()> {
None
}
}
fn main() {
let path = "test_pagecache_doc.log";
let conf = rsdb::Config::default().path(Some(path.to_owned()));
let pc = rsdb::PageCache::new(TestMaterializer, conf.clone());
let (id, key) = pc.allocate();
// 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.
let key = pc.set(id, key, "a".to_owned()).unwrap();
let key = pc.merge(id, key, "b".to_owned()).unwrap();
let _key = pc.merge(id, key, "c".to_owned()).unwrap();
let (consolidated, _key) = pc.get(id).unwrap();
assert_eq!(consolidated, "abc".to_owned());
drop(pc);
std::fs::remove_file(path).unwrap();
}Implementations§
Source§impl<PM, P, R> PageCache<PM, P, R>
impl<PM, P, R> PageCache<PM, P, R>
Sourcepub fn allocate(&self) -> (usize, CasKey<P>)
pub fn allocate(&self) -> (usize, CasKey<P>)
Create a new page, trying to reuse old freed pages if possible
to maximize underlying Radix pointer density.
Sourcepub fn get(&self, pid: usize) -> Option<(PM::PageFrag, CasKey<P>)>
pub fn get(&self, pid: usize) -> Option<(PM::PageFrag, CasKey<P>)>
Try to retrieve a page by its logical ID.
Sourcepub fn set(
&self,
pid: usize,
old: CasKey<P>,
new: P,
) -> Result<CasKey<P>, Option<CasKey<P>>>
pub fn set( &self, pid: usize, old: CasKey<P>, new: P, ) -> Result<CasKey<P>, Option<CasKey<P>>>
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 page has changed since the provided CasKey was created.
Sourcepub fn merge(
&self,
pid: usize,
old: CasKey<P>,
new: P,
) -> Result<CasKey<P>, Option<CasKey<P>>>
pub fn merge( &self, pid: usize, old: CasKey<P>, new: P, ) -> Result<CasKey<P>, Option<CasKey<P>>>
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 page has changed since the provided CasKey was created.
Trait Implementations§
impl<PM, P, R> Send for PageCache<PM, P, R>
impl<PM, P, R> Sync for PageCache<PM, P, R>
Auto Trait Implementations§
impl<PM, P, R> !Freeze for PageCache<PM, P, R>
impl<PM, P, R> !RefUnwindSafe for PageCache<PM, P, R>
impl<PM, P, R> Unpin for PageCache<PM, P, R>where
PM: Unpin,
impl<PM, P, R> !UnwindSafe for PageCache<PM, P, R>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more