Merge pull request #313 from pavel-mukhanov/sync_snapshot

Implement Send and Sync for Snapshot
master
Oleksandr Anyshchenko 6 years ago committed by GitHub
commit 184aea79b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      CHANGELOG.md
  2. 5
      src/db.rs
  3. 43
      tests/test_db.rs

@ -1,5 +1,11 @@
# Changelog # Changelog
## Unreleased
### Changes
* Added `Sync` and `Send` implementations to `Snapshot` (pavel-mukhanov)
## 0.12.2 (2019-05-03) ## 0.12.2 (2019-05-03)
### Changes ### Changes

@ -104,6 +104,11 @@ pub struct Snapshot<'a> {
inner: *const ffi::rocksdb_snapshot_t, inner: *const ffi::rocksdb_snapshot_t,
} }
/// `Send` and `Sync` implementations for `Snapshot` are safe, because `Snapshot` is
/// immutable and can be safely shared between threads.
unsafe impl<'a> Send for Snapshot<'a> {}
unsafe impl<'a> Sync for Snapshot<'a> {}
/// An iterator over a database or column family, with specifiable /// An iterator over a database or column family, with specifiable
/// ranges and direction. /// ranges and direction.
/// ///

@ -19,7 +19,9 @@ mod util;
use libc::size_t; use libc::size_t;
use rocksdb::{DBVector, Error, IteratorMode, Options, WriteBatch, DB}; use rocksdb::{DBVector, Error, IteratorMode, Options, Snapshot, WriteBatch, DB};
use std::sync::Arc;
use std::{mem, thread};
use util::DBPath; use util::DBPath;
#[test] #[test]
@ -163,6 +165,45 @@ fn snapshot_test() {
} }
} }
#[derive(Clone)]
struct SnapshotWrapper {
snapshot: Arc<Snapshot<'static>>,
}
impl SnapshotWrapper {
fn new(db: &DB) -> Self {
Self {
snapshot: Arc::new(unsafe { mem::transmute(db.snapshot()) }),
}
}
fn check<K>(&self, key: K, value: &str) -> bool
where
K: AsRef<[u8]>,
{
self.snapshot.get(key).unwrap().unwrap().to_utf8().unwrap() == value
}
}
#[test]
fn sync_snapshot_test() {
let path = DBPath::new("_rust_rocksdb_sync_snapshottest");
let db = DB::open_default(&path).unwrap();
assert!(db.put(b"k1", b"v1").is_ok());
assert!(db.put(b"k2", b"v2").is_ok());
let wrapper = SnapshotWrapper::new(&db);
let wrapper_1 = wrapper.clone();
let handler_1 = thread::spawn(move || wrapper_1.check("k1", "v1"));
let wrapper_2 = wrapper.clone();
let handler_2 = thread::spawn(move || wrapper_2.check("k2", "v2"));
assert!(handler_1.join().unwrap());
assert!(handler_2.join().unwrap());
}
#[test] #[test]
fn set_option_test() { fn set_option_test() {
let path = DBPath::new("_rust_rocksdb_set_optionstest"); let path = DBPath::new("_rust_rocksdb_set_optionstest");

Loading…
Cancel
Save