commit
60dbdc92dc
@ -1,48 +1,51 @@ |
|||||||
extern crate rocksdb; |
extern crate rocksdb; |
||||||
|
mod util; |
||||||
|
|
||||||
use rocksdb::{DB, Options, SliceTransform}; |
use rocksdb::{DB, Options, SliceTransform}; |
||||||
|
use util::DBPath; |
||||||
|
|
||||||
#[test] |
#[test] |
||||||
pub fn test_slice_transform() { |
pub fn test_slice_transform() { |
||||||
|
let n = DBPath::new("_rust_rocksdb_slicetransform_test"); |
||||||
|
{ |
||||||
|
let a1: Box<[u8]> = key(b"aaa1"); |
||||||
|
let a2: Box<[u8]> = key(b"aaa2"); |
||||||
|
let b1: Box<[u8]> = key(b"bbb1"); |
||||||
|
let b2: Box<[u8]> = key(b"bbb2"); |
||||||
|
|
||||||
let path = "_rust_rocksdb_slicetransform_test"; |
fn first_three(k: &[u8]) -> Vec<u8> { |
||||||
let a1: Box<[u8]> = key(b"aaa1"); |
k.iter().take(3).cloned().collect() |
||||||
let a2: Box<[u8]> = key(b"aaa2"); |
} |
||||||
let b1: Box<[u8]> = key(b"bbb1"); |
|
||||||
let b2: Box<[u8]> = key(b"bbb2"); |
|
||||||
|
|
||||||
fn first_three(k: &[u8]) -> Vec<u8> { |
let prefix_extractor = SliceTransform::create("first_three", first_three, None); |
||||||
k.iter().take(3).cloned().collect() |
|
||||||
} |
|
||||||
|
|
||||||
let prefix_extractor = SliceTransform::create("first_three", first_three, None); |
let mut opts = Options::default(); |
||||||
|
opts.create_if_missing(true); |
||||||
|
opts.set_prefix_extractor(prefix_extractor); |
||||||
|
|
||||||
let mut opts = Options::default(); |
let db = DB::open(&opts, &n).unwrap(); |
||||||
opts.create_if_missing(true); |
|
||||||
opts.set_prefix_extractor(prefix_extractor); |
|
||||||
|
|
||||||
let db = DB::open(&opts, path).unwrap(); |
assert!(db.put(&*a1, &*a1).is_ok()); |
||||||
|
assert!(db.put(&*a2, &*a2).is_ok()); |
||||||
|
assert!(db.put(&*b1, &*b1).is_ok()); |
||||||
|
assert!(db.put(&*b2, &*b2).is_ok()); |
||||||
|
|
||||||
assert!(db.put(&*a1, &*a1).is_ok()); |
fn cba(input: &Box<[u8]>) -> Box<[u8]> { |
||||||
assert!(db.put(&*a2, &*a2).is_ok()); |
input.iter().cloned().collect::<Vec<_>>().into_boxed_slice() |
||||||
assert!(db.put(&*b1, &*b1).is_ok()); |
} |
||||||
assert!(db.put(&*b2, &*b2).is_ok()); |
|
||||||
|
|
||||||
fn cba(input: &Box<[u8]>) -> Box<[u8]> { |
fn key(k: &[u8]) -> Box<[u8]> { k.to_vec().into_boxed_slice() } |
||||||
input.iter().cloned().collect::<Vec<_>>().into_boxed_slice() |
|
||||||
} |
|
||||||
|
|
||||||
fn key(k: &[u8]) -> Box<[u8]> { k.to_vec().into_boxed_slice() } |
{ |
||||||
|
let expected = vec![(cba(&a1), cba(&a1)), (cba(&a2), cba(&a2))]; |
||||||
|
let a_iterator = db.prefix_iterator(b"aaa"); |
||||||
|
assert_eq!(a_iterator.collect::<Vec<_>>(), expected) |
||||||
|
} |
||||||
|
|
||||||
{ |
{ |
||||||
let expected = vec![(cba(&a1), cba(&a1)), (cba(&a2), cba(&a2))]; |
let expected = vec![(cba(&b1), cba(&b1)), (cba(&b2), cba(&b2))]; |
||||||
let a_iterator = db.prefix_iterator(b"aaa"); |
let b_iterator = db.prefix_iterator(b"bbb"); |
||||||
assert_eq!(a_iterator.collect::<Vec<_>>(), expected) |
assert_eq!(b_iterator.collect::<Vec<_>>(), expected) |
||||||
} |
} |
||||||
|
|
||||||
{ |
|
||||||
let expected = vec![(cba(&b1), cba(&b1)), (cba(&b2), cba(&b2))]; |
|
||||||
let b_iterator = db.prefix_iterator(b"bbb"); |
|
||||||
assert_eq!(b_iterator.collect::<Vec<_>>(), expected) |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,41 @@ |
|||||||
|
extern crate rocksdb; |
||||||
|
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH}; |
||||||
|
use std::path::{PathBuf, Path}; |
||||||
|
|
||||||
|
use rocksdb::{DB, Options}; |
||||||
|
|
||||||
|
/// Ensures that DB::Destroy is called for this database when DBPath is dropped.
|
||||||
|
pub struct DBPath { |
||||||
|
path: PathBuf |
||||||
|
} |
||||||
|
|
||||||
|
impl DBPath { |
||||||
|
/// Suffixes the given `prefix` with a timestamp to ensure that subsequent test runs don't reuse
|
||||||
|
/// an old database in case of panics prior to Drop being called.
|
||||||
|
pub fn new(prefix: &str) -> DBPath { |
||||||
|
let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); |
||||||
|
let path = format!( |
||||||
|
"{}.{}.{}", |
||||||
|
prefix, |
||||||
|
current_time.as_secs(), |
||||||
|
current_time.subsec_nanos() |
||||||
|
); |
||||||
|
|
||||||
|
DBPath { path: PathBuf::from(path) } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Drop for DBPath { |
||||||
|
fn drop(&mut self) { |
||||||
|
let opts = Options::default(); |
||||||
|
DB::destroy(&opts, &self.path).unwrap(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl AsRef<Path> for DBPath { |
||||||
|
fn as_ref(&self) -> &Path { |
||||||
|
&self.path |
||||||
|
} |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue