Commit 62741f9e authored by Li Shihai's avatar Li Shihai Committed by GitHub

export readopt of prefix_same_as_start (#65)

parent 76b3a4b7
......@@ -10,4 +10,5 @@ tags
.idea/
out/
*.iml
\ No newline at end of file
*.iml
.vscode
......@@ -2424,6 +2424,11 @@ void crocksdb_readoptions_set_total_order_seek(crocksdb_readoptions_t* opt,
opt->rep.total_order_seek = v;
}
void crocksdb_readoptions_set_prefix_same_as_start(crocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.prefix_same_as_start = v;
}
crocksdb_writeoptions_t* crocksdb_writeoptions_create() {
return new crocksdb_writeoptions_t;
}
......
......@@ -955,6 +955,8 @@ extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_readahead_size(
crocksdb_readoptions_t*, size_t);
extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_total_order_seek(
crocksdb_readoptions_t*, unsigned char);
extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_prefix_same_as_start(
crocksdb_readoptions_t*, unsigned char);
/* Write options */
......
......@@ -374,6 +374,7 @@ extern "C" {
pub fn crocksdb_readoptions_set_read_tier(readopts: *mut DBReadOptions, tier: c_int);
pub fn crocksdb_readoptions_set_tailing(readopts: *mut DBReadOptions, v: bool);
pub fn crocksdb_readoptions_set_total_order_seek(readopts: *mut DBReadOptions, v: bool);
pub fn crocksdb_readoptions_set_prefix_same_as_start(readopts: *mut DBReadOptions, v: bool);
pub fn crocksdb_get(db: *const DBInstance,
readopts: *const DBReadOptions,
......
......@@ -214,6 +214,12 @@ impl ReadOptions {
}
}
pub fn set_prefix_same_as_start(&mut self, v: bool) {
unsafe {
crocksdb_ffi::crocksdb_readoptions_set_prefix_same_as_start(self.inner, v);
}
}
pub unsafe fn get_inner(&self) -> *const DBReadOptions {
self.inner
}
......
......@@ -14,13 +14,27 @@
use rocksdb::*;
use tempdir::TempDir;
struct FixedPrefixTransform {
pub prefix_len: usize,
}
impl SliceTransform for FixedPrefixTransform {
fn transform<'a>(&mut self, key: &'a [u8]) -> &'a [u8] {
&key[..self.prefix_len]
}
fn in_domain(&mut self, key: &[u8]) -> bool {
key.len() >= self.prefix_len
}
}
struct FixedSuffixTransform {
pub suffix_len: usize,
}
impl SliceTransform for FixedSuffixTransform {
fn transform<'a>(&mut self, key: &'a [u8]) -> &'a [u8] {
&key[..self.suffix_len]
&key[..(key.len() - self.suffix_len)]
}
fn in_domain(&mut self, key: &[u8]) -> bool {
......@@ -37,6 +51,15 @@ fn prev_collect<'a>(iter: &mut DBIterator<'a>) -> Vec<Kv> {
buf
}
fn next_collect<'a>(iter: &mut DBIterator<'a>) -> Vec<Kv> {
let mut buf = vec![];
while iter.valid() {
buf.push(iter.kv().unwrap());
iter.next();
}
buf
}
#[test]
pub fn test_iterator() {
let path = TempDir::new("_rust_rocksdb_iteratortest").expect("");
......@@ -203,14 +226,8 @@ fn read_with_upper_bound() {
readopts.set_iterate_upper_bound(b"k2");
let mut iter = db.iter_opt(readopts);
iter.seek(SeekKey::Start);
let mut count = 0;
while iter.valid() {
count += 1;
if !iter.next() {
break;
}
}
assert_eq!(count, 2);
let vec = next_collect(&mut iter);
assert_eq!(vec.len(), 2);
}
}
......@@ -223,45 +240,60 @@ fn test_total_order_seek() {
let mut opts = Options::new();
opts.create_if_missing(true);
opts.set_block_based_table_factory(&bbto);
opts.set_prefix_extractor("FixedSuffixTransform",
Box::new(FixedSuffixTransform { suffix_len: 2 }))
opts.set_prefix_extractor("FixedPrefixTransform",
Box::new(FixedPrefixTransform { prefix_len: 2 }))
.unwrap();
// also create prefix bloom for memtable
opts.set_memtable_prefix_bloom_size_ratio(0.1 as f64);
let keys = vec![b"k1-0", b"k1-1", b"k1-2", b"k2-0", b"k2-1", b"k2-2", b"k3-0", b"k3-1",
b"k3-2"];
let keys = vec![b"k1-1", b"k1-2", b"k1-3", b"k2-1", b"k2-2", b"k2-3", b"k3-1", b"k3-2",
b"k3-3"];
let db = DB::open(opts, path.path().to_str().unwrap()).unwrap();
let wopts = WriteOptions::new();
// sst1
db.put_opt(b"k1-0", b"a", &wopts).unwrap();
db.put_opt(b"k1-1", b"b", &wopts).unwrap();
db.put_opt(b"k1-2", b"c", &wopts).unwrap();
db.put_opt(b"k1-1", b"a", &wopts).unwrap();
db.put_opt(b"k1-2", b"b", &wopts).unwrap();
db.put_opt(b"k1-3", b"c", &wopts).unwrap();
db.put_opt(b"k2-1", b"a", &wopts).unwrap();
db.flush(true /* sync */).unwrap(); // flush memtable to sst file.
// sst2
db.put_opt(b"k2-0", b"a", &wopts).unwrap();
db.put_opt(b"k2-1", b"b", &wopts).unwrap();
db.put_opt(b"k2-2", b"c", &wopts).unwrap();
db.put_opt(b"k2-2", b"b", &wopts).unwrap();
db.put_opt(b"k2-3", b"c", &wopts).unwrap();
db.flush(true /* sync */).unwrap(); // flush memtable to sst file.
// memtable
db.put_opt(b"k3-0", b"a", &wopts).unwrap();
db.put_opt(b"k3-1", b"b", &wopts).unwrap();
db.put_opt(b"k3-2", b"c", &wopts).unwrap();
db.put_opt(b"k3-1", b"a", &wopts).unwrap();
db.put_opt(b"k3-2", b"b", &wopts).unwrap();
db.put_opt(b"k3-3", b"c", &wopts).unwrap();
let mut iter = db.iter();
let mut ropts = ReadOptions::new();
ropts.set_prefix_same_as_start(true);
let mut iter = db.iter_opt(ropts);
// only iterate sst files and memtables that contain keys with the same prefix as b"k1"
// and the keys is iterated as valid when prefixed as b"k1"
iter.seek(SeekKey::Key(b"k1-0"));
let mut key_count = 0;
while iter.valid() {
// only iterator sst files and memtable that contain keys has the same prefix with b"k1-0".
assert_eq!(keys[key_count], iter.key());
key_count = key_count + 1;
iter.next();
}
assert!(key_count == 3);
let mut iter = db.iter();
// only iterate sst files and memtables that contain keys with the same prefix as b"k1"
// but it still can next/prev to the keys which is not prefixed as b"k1" with prefix_same_as_start
iter.seek(SeekKey::Key(b"k1-0"));
let mut key_count = 0;
while iter.valid() {
assert_eq!(keys[key_count], iter.key());
key_count = key_count + 1;
iter.next();
}
assert!(key_count == 4);
let mut ropts = ReadOptions::new();
ropts.set_total_order_seek(true);
let mut iter = db.iter_opt(ropts);
......@@ -275,3 +307,33 @@ fn test_total_order_seek() {
}
assert!(key_count == 9);
}
#[test]
fn test_fixed_suffix_seek() {
let path = TempDir::new("_rust_rocksdb_fixed_suffix_seek").expect("");
let mut bbto = BlockBasedOptions::new();
bbto.set_bloom_filter(10, false);
bbto.set_whole_key_filtering(false);
let mut opts = Options::new();
opts.create_if_missing(true);
opts.set_block_based_table_factory(&bbto);
opts.set_prefix_extractor("FixedSuffixTransform",
Box::new(FixedSuffixTransform { suffix_len: 2 }))
.unwrap();
let db = DB::open(opts, path.path().to_str().unwrap()).unwrap();
db.put(b"k-eghe-5", b"a").unwrap();
db.put(b"k-24yfae-6", b"a").unwrap();
db.put(b"k-h1fwd-7", b"a").unwrap();
db.flush(true).unwrap();
let mut iter = db.iter();
iter.seek(SeekKey::Key(b"k-24yfae-8"));
let vec = prev_collect(&mut iter);
assert!(vec.len() == 2);
let mut iter = db.iter();
iter.seek(SeekKey::Key(b"k-24yfa-9"));
let vec = prev_collect(&mut iter);
assert!(vec.len() == 0);
}
......@@ -14,17 +14,17 @@
use rocksdb::*;
use tempdir::TempDir;
struct FixedSuffixTransform {
pub suffix_len: usize,
struct FixedPrefixTransform {
pub prefix_len: usize,
}
impl SliceTransform for FixedSuffixTransform {
impl SliceTransform for FixedPrefixTransform {
fn transform<'a>(&mut self, key: &'a [u8]) -> &'a [u8] {
&key[..self.suffix_len]
&key[..self.prefix_len]
}
fn in_domain(&mut self, key: &[u8]) -> bool {
key.len() >= self.suffix_len
key.len() >= self.prefix_len
}
}
......@@ -56,8 +56,8 @@ fn test_prefix_extractor_compatibility() {
let mut opts = Options::new();
opts.create_if_missing(false);
opts.set_block_based_table_factory(&bbto);
opts.set_prefix_extractor("FixedSuffixTransform",
Box::new(FixedSuffixTransform { suffix_len: 2 }))
opts.set_prefix_extractor("FixedPrefixTransform",
Box::new(FixedPrefixTransform { prefix_len: 2 }))
.unwrap();
// also create prefix bloom for memtable
opts.set_memtable_prefix_bloom_size_ratio(0.1 as f64);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment