[−][src]Struct pagecache::PageCache
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; // Create a new `Materializer` with the previously recovered // state if any existed. fn new(config: pagecache::Config) -> 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 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(); { // We begin by initiating a new transaction, which // will prevent any witnessable memory from being // reclaimed before we drop this object. let tx = pc.begin().unwrap(); // The first item in a page should be set using allocate, // which signals that this is the beginning of a new // page history. let (id, mut key) = pc.allocate("a".to_owned(), &tx).unwrap(); // Subsequent atomic updates should be added with link. key = pc.link(id, key, "b".to_owned(), &tx).unwrap().unwrap(); key = pc.link(id, key, "c".to_owned(), &tx).unwrap().unwrap(); // When getting a page, the provided `Materializer` is // used to merge all pages together. let (consolidated, mut key) = pc.get(id, &tx).unwrap().unwrap(); assert_eq!(*consolidated, "abc".to_owned()); // You can completely rewrite a page by using `replace`: key = pc.replace(id, key, "d".into(), &tx).unwrap().unwrap(); let (consolidated, key) = pc.get(id, &tx).unwrap().unwrap(); assert_eq!(*consolidated, "d".to_owned()); } }
Methods
impl<PM, P> PageCache<PM, P> where
PM: Materializer<PageFrag = P>,
PM: 'static + Send + Sync,
P: 'static + Debug + Clone + Serialize + DeserializeOwned + Send + Sync,
[src]
PM: Materializer<PageFrag = P>,
PM: 'static + Send + Sync,
P: 'static + Debug + Clone + Serialize + DeserializeOwned + Send + Sync,
pub fn start(config: Config) -> Result<PageCache<PM, P>>
[src]
Instantiate a new PageCache
.
pub fn flush(&self) -> Result<usize>
[src]
Flushes any pending IO buffers to disk to ensure durability. Returns the number of bytes written during this call.
pub fn begin(&self) -> Result<Tx>
[src]
Begins a transaction.
pub fn allocate<'g>(
&self,
new: P,
tx: &'g Tx
) -> Result<(PageId, PagePtr<'g, P>)>
[src]
&self,
new: P,
tx: &'g Tx
) -> Result<(PageId, PagePtr<'g, P>)>
Create a new page, trying to reuse old freed pages if possible
to maximize underlying PageTable
pointer density. Returns
the page ID and its pointer for use in future atomic replace
and link
operations.
pub fn free<'g>(
&self,
pid: PageId,
old: PagePtr<'g, P>,
tx: &'g Tx
) -> Result<CasResult<'g, P, ()>>
[src]
&self,
pid: PageId,
old: PagePtr<'g, P>,
tx: &'g Tx
) -> Result<CasResult<'g, P, ()>>
Free a particular page.
pub fn link<'g>(
&'g self,
pid: PageId,
old: PagePtr<'g, P>,
new: P,
tx: &'g Tx
) -> Result<CasResult<'g, P, P>>
[src]
&'g self,
pid: PageId,
old: PagePtr<'g, P>,
new: P,
tx: &'g Tx
) -> Result<CasResult<'g, P, 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.
pub fn replace<'g>(
&self,
pid: PageId,
old: PagePtr<'g, P>,
new: P,
tx: &'g Tx
) -> Result<CasResult<'g, P, P>>
[src]
&self,
pid: PageId,
old: PagePtr<'g, P>,
new: P,
tx: &'g Tx
) -> Result<CasResult<'g, P, 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.
pub fn get<'g>(
&self,
pid: PageId,
tx: &'g Tx
) -> Result<PageGet<'g, PM::PageFrag>>
[src]
&self,
pid: PageId,
tx: &'g Tx
) -> Result<PageGet<'g, PM::PageFrag>>
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<usize>
[src]
Blocks until the provided Lsn is stable on disk, triggering necessary flushes in the process. Returns the number of bytes written during this call.
pub fn bump_page_rts(&self, pid: PageId, ts: u64, tx: &Tx)
[src]
Increase a page's associated transactional read timestamp (RTS) to as high as the specified timestamp.
pub fn get_page_rts(&self, pid: PageId, tx: &Tx) -> Option<u64>
[src]
Retrieves the current transactional read timestamp for a page.
pub fn was_recovered(&self) -> bool
[src]
Returns true
if the database was
recovered from a previous process.
Note that database state is only
guaranteed to be present up to the
last call to flush
! Otherwise state
is synced to disk periodically if the
sync_every_ms
configuration option
is set to Some(number_of_ms_between_syncs)
or if the IO buffer gets filled to
capacity before being rotated.
pub fn generate_id(&self) -> Result<u64>
[src]
Generate a monotonic ID. Not guaranteed to be
contiguous. Written to disk every idgen_persist_interval
operations, followed by a blocking flush. During recovery, we
take the last recovered generated ID and add 2x
the idgen_persist_interval
to it. While persisting, if the
previous persisted counter wasn't synced to disk yet, we will do
a blocking flush to fsync the latest counter, ensuring
that we will never give out the same counter twice.
pub fn meta<'a>(&self, tx: &'a Tx) -> Result<&'a Meta>
[src]
Returns the current Meta
map, which contains a convenient
mapping from identifiers to PageId's that the PageCache
owner may use for storing metadata about their higher-level
collections.
pub fn meta_pid_for_name(&self, name: &[u8], tx: &Tx) -> Result<usize>
[src]
Look up a PageId for a given identifier in the Meta
mapping. This is pretty cheap, but in some cases
you may prefer to maintain your own atomic references
to collection roots instead of relying on this. See
sled's Tree
root tracking for an example of
avoiding this in a lock-free way that handles
various race conditions.
pub fn cas_root_in_meta<'g>(
&self,
name: Vec<u8>,
old: Option<usize>,
new: Option<usize>,
tx: &'g Tx
) -> Result<Result<(), Option<usize>>>
[src]
&self,
name: Vec<u8>,
old: Option<usize>,
new: Option<usize>,
tx: &'g Tx
) -> Result<Result<(), Option<usize>>>
Compare-and-swap the Meta
mapping for a given
identifier.
Trait Implementations
impl<PM, P> Sync for PageCache<PM, P> where
PM: Send + Sync,
P: Clone + 'static + Send + Sync,
[src]
PM: Send + Sync,
P: Clone + 'static + Send + Sync,
impl<PM, P> Send for PageCache<PM, P> where
PM: Send + Sync,
P: Clone + 'static + Send + Sync,
[src]
PM: Send + Sync,
P: Clone + 'static + Send + Sync,
impl<PM, P> Debug for PageCache<PM, P> where
PM: Send + Sync,
P: Clone + Debug + Send + Sync,
[src]
PM: Send + Sync,
P: Clone + Debug + Send + Sync,
Blanket Implementations
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From for T
[src]
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,