Add snapshots

master
David Greenberg 10 years ago
parent 86ab20ffd6
commit 91b8246735
  1. 29
      src/main.rs
  2. 38
      src/rocksdb.rs

@ -20,6 +20,33 @@ extern crate test;
use rocksdb::{Options, RocksDB, MergeOperands, new_bloom_filter, Writable, DBIterator, SubDBIterator };
use rocksdb::RocksDBCompactionStyle::RocksDBUniversalCompaction;
fn snapshot_test() {
let path = "_rust_rocksdb_iteratortest";
{
let mut db = RocksDB::open_default(path).unwrap();
let p = db.put(b"k1", b"v1111");
assert!(p.is_ok());
let p = db.put(b"k2", b"v2222");
assert!(p.is_ok());
let p = db.put(b"k3", b"v3333");
assert!(p.is_ok());
let mut snap = db.snapshot();
let mut view1 = snap.iterator();
println!("See the output of the first iter");
for (k,v) in view1.from_start() {
println!("Hello {}: {}", std::str::from_utf8(k).unwrap(), std::str::from_utf8(v).unwrap());
};
for (k,v) in view1.from_start() {
println!("Hello {}: {}", std::str::from_utf8(k).unwrap(), std::str::from_utf8(v).unwrap());
};
for (k,v) in view1.from_end() {
println!("Hello {}: {}", std::str::from_utf8(k).unwrap(), std::str::from_utf8(v).unwrap());
};
}
let opts = Options::new();
assert!(RocksDB::destroy(&opts, path).is_ok());
}
fn iterator_test() {
let path = "_rust_rocksdb_iteratortest";
{
@ -67,8 +94,10 @@ fn iterator_test() {
let opts = Options::new();
assert!(RocksDB::destroy(&opts, path).is_ok());
}
#[cfg(not(feature = "valgrind"))]
fn main() {
snapshot_test();
iterator_test();
let path = "/tmp/rust-rocksdb";
let mut db = RocksDB::open_default(path).unwrap();

@ -40,6 +40,11 @@ pub struct ReadOptions {
inner: rocksdb_ffi::RocksDBReadOptions,
}
pub struct Snapshot<'a> {
db: &'a RocksDB,
inner: rocksdb_ffi::RocksDBSnapshot,
}
pub struct DBIterator {
//TODO: should have a reference to DB to enforce scope, but it's trickier than I thought to add
inner: rocksdb_ffi::RocksDBIterator,
@ -87,7 +92,7 @@ impl <'a> Iterator for SubDBIterator<'a> {
impl DBIterator {
//TODO alias db & opts to different lifetimes, and DBIterator to the db's lifetime
pub fn new(db: &RocksDB, readopts: &ReadOptions) -> DBIterator {
fn new(db: &RocksDB, readopts: &ReadOptions) -> DBIterator {
unsafe {
let iterator = rocksdb_ffi::rocksdb_create_iterator(db.inner, readopts.inner);
rocksdb_ffi::rocksdb_iter_seek_to_first(iterator);
@ -122,13 +127,33 @@ impl DBIterator {
impl Drop for DBIterator {
fn drop(&mut self) {
println!("Dropped iter");
unsafe {
rocksdb_ffi::rocksdb_iter_destroy(self.inner);
}
}
}
impl <'a> Snapshot<'a> {
pub fn new(db: &RocksDB) -> Snapshot {
let snapshot = unsafe { rocksdb_ffi::rocksdb_create_snapshot(db.inner) };
Snapshot{db: db, inner: snapshot}
}
pub fn iterator(&self) -> DBIterator {
let mut readopts = ReadOptions::new();
readopts.set_snapshot(self);
DBIterator::new(self.db, &readopts)
}
}
impl <'a> Drop for Snapshot<'a> {
fn drop(&mut self) {
unsafe {
rocksdb_ffi::rocksdb_release_snapshot(self.db.inner, self.inner);
}
}
}
// This is for the RocksDB and write batches to share the same API
pub trait Writable {
fn put(&mut self, key: &[u8], value: &[u8]) -> Result<(), String>;
@ -269,6 +294,10 @@ impl RocksDB {
let opts = ReadOptions::new();
DBIterator::new(&self, &opts)
}
pub fn snapshot(&self) -> Snapshot {
Snapshot::new(self)
}
}
impl Writable for RocksDB {
@ -394,6 +423,11 @@ impl ReadOptions {
}
}
fn set_snapshot(&mut self, snapshot: &Snapshot) {
unsafe {
rocksdb_ffi::rocksdb_readoptions_set_snapshot(self.inner, snapshot.inner);
}
}
}
pub struct RocksDBVector {

Loading…
Cancel
Save