Crate rsdb [] [src]

rsdb is a flash-sympathetic persistent lock-free B+ tree, pagecache, and log.

Tree

let t = rsdb::Config::default().tree();
t.set(b"yo!".to_vec(), b"v1".to_vec());
assert_eq!(t.get(b"yo!"), Some(b"v1".to_vec()));
t.cas(b"yo!".to_vec(), Some(b"v1".to_vec()), Some(b"v2".to_vec())).unwrap();
let mut iter = t.scan(b"a non-present key before yo!");
assert_eq!(iter.next(), Some((b"yo!".to_vec(), b"v2".to_vec())));
assert_eq!(iter.next(), None);
t.del(b"yo!");

Working with the PageCache

extern crate rsdb;

use rsdb::Materializer;

pub struct TestMaterializer;

impl Materializer for TestMaterializer {
    type MaterializedPage = String;
    type PartialPage = String;
    type Recovery = ();

    fn materialize(&self, frags: &[String]) -> String {
        self.consolidate(frags).pop().unwrap()
    }

    fn consolidate(&self, frags: &[String]) -> Vec<String> {
        let mut consolidated = String::new();
        for frag in frags.into_iter() {
            consolidated.push_str(&*frag);
        }

        vec![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.replace(id, key, vec!["a".to_owned()]).unwrap();
    let key = pc.prepend(id, key, "b".to_owned()).unwrap();
    let _key = pc.prepend(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();
}

Working with Log

use rsdb::Log;

let log = rsdb::Config::default().log();
let first_offset = log.write(b"1".to_vec());
log.write(b"22".to_vec());
log.write(b"333".to_vec());

// stick an abort in the middle, which should not be returned
let res = log.reserve(b"never_gonna_hit_disk".to_vec());
res.abort();

log.write(b"4444".to_vec());
let last_offset = log.write(b"55555".to_vec());
log.make_stable(last_offset);
let mut iter = log.iter_from(first_offset);
assert_eq!(iter.next().unwrap().1, b"1".to_vec());
assert_eq!(iter.next().unwrap().1, b"22".to_vec());
assert_eq!(iter.next().unwrap().1, b"333".to_vec());
assert_eq!(iter.next().unwrap().1, b"4444".to_vec());
assert_eq!(iter.next().unwrap().1, b"55555".to_vec());
assert_eq!(iter.next(), None);

Structs

Config

Top-level configuration for the system.

LockFreeLog

LockFreeLog is responsible for putting data on disk, and retrieving it later on.

PageCache

A lock-free pagecache.

Radix

A simple lock-free radix tree.

Tree

A flash-sympathetic persistent lock-free B+ tree

Traits

Log

A trait for objects which facilitate log-structured storage.

Materializer

A tenant of a PageCache needs to provide a Materializer which handles the processing of pages.