Struct pagecache::PageCache
[−]
[src]
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
extern crate pagecache; extern crate crossbeam_epoch as epoch; use pagecache::Materializer; use epoch::{Shared, pin}; 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(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(&self, frags: &[&Self::PageFrag]) -> Self::PageFrag { let mut consolidated = String::new(); for frag in frags.into_iter() { consolidated.push_str(&*frag); } consolidated } // 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 } } fn main() { let conf = pagecache::ConfigBuilder::new().temporary(true); let pc: pagecache::PageCache<TestMaterializer, _, _> = pagecache::PageCache::start(conf.build()); { let guard = pin(); let id = pc.allocate(&guard); // 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.replace(id, Shared::null(), "a".to_owned(), &guard).unwrap(); // Subsequent atomic updates should be added with link. let key = pc.link(id, key, "b".to_owned(), &guard).unwrap(); let _key = pc.link(id, key, "c".to_owned(), &guard).unwrap(); // When getting a page, the provide `Materializer` is // used to merge all pages together. let (consolidated, _key) = pc.get(id, &guard).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: Debug + Clone + Serialize + DeserializeOwned + Send,
[src]
PM: Materializer<PageFrag = P, Recovery = R>,
PM: 'static + Send + Sync,
P: 'static + Debug + Clone + Serialize + DeserializeOwned + Send + Sync,
R: Debug + Clone + Serialize + DeserializeOwned + Send,
fn start(config: Config) -> PageCache<PM, P, R>
[src]
Instantiate a new PageCache
.
fn flush(&self)
[src]
Flushes any pending IO buffers to disk to ensure durability.
fn recovered_state(&self) -> Option<R>
[src]
Return the recovered state from the snapshot
fn allocate<'g>(&self, guard: &'g Guard) -> PageID
[src]
Create a new page, trying to reuse old freed pages if possible
to maximize underlying Radix
pointer density.
fn free(&self, pid: PageID)
[src]
Free a particular page.
fn link<'g>(
&self,
pid: PageID,
old: Shared<'g, Node<CacheEntry<P>>>,
new: P,
guard: &'g Guard
) -> Result<Shared<'g, Node<CacheEntry<P>>>, Option<Shared<'g, Node<CacheEntry<P>>>>>
[src]
&self,
pid: PageID,
old: Shared<'g, Node<CacheEntry<P>>>,
new: P,
guard: &'g Guard
) -> Result<Shared<'g, Node<CacheEntry<P>>>, Option<Shared<'g, Node<CacheEntry<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 atomic append fails.
fn replace<'g>(
&self,
pid: PageID,
old: Shared<'g, Node<CacheEntry<P>>>,
new: P,
guard: &'g Guard
) -> Result<Shared<'g, Node<CacheEntry<P>>>, Option<Shared<'g, Node<CacheEntry<P>>>>>
[src]
&self,
pid: PageID,
old: Shared<'g, Node<CacheEntry<P>>>,
new: P,
guard: &'g Guard
) -> Result<Shared<'g, Node<CacheEntry<P>>>, Option<Shared<'g, Node<CacheEntry<P>>>>>
Replace an existing page with a different set of PageFrag
s.
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.
fn get<'g>(&self, pid: PageID, guard: &'g Guard) -> PageGet<'g, PM::PageFrag>
[src]
Try to retrieve a page by its logical ID.
Trait Implementations
impl<PM, P, R> Send for PageCache<PM, P, R> where
PM: Send + Sync,
P: 'static + Send + Sync,
R: Send,
[src]
PM: Send + Sync,
P: 'static + Send + Sync,
R: Send,
impl<PM, P, R> Debug for PageCache<PM, P, R> where
PM: Send + Sync,
P: Debug + Send + Sync,
R: Debug + Send,
[src]
PM: Send + Sync,
P: Debug + Send + Sync,
R: Debug + Send,