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 ...@@ -10,4 +10,5 @@ tags
.idea/ .idea/
out/ out/
*.iml *.iml
\ No newline at end of file .vscode
...@@ -2424,6 +2424,11 @@ void crocksdb_readoptions_set_total_order_seek(crocksdb_readoptions_t* opt, ...@@ -2424,6 +2424,11 @@ void crocksdb_readoptions_set_total_order_seek(crocksdb_readoptions_t* opt,
opt->rep.total_order_seek = v; 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() { crocksdb_writeoptions_t* crocksdb_writeoptions_create() {
return new crocksdb_writeoptions_t; return new crocksdb_writeoptions_t;
} }
......
...@@ -955,6 +955,8 @@ extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_readahead_size( ...@@ -955,6 +955,8 @@ extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_readahead_size(
crocksdb_readoptions_t*, size_t); crocksdb_readoptions_t*, size_t);
extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_total_order_seek( extern C_ROCKSDB_LIBRARY_API void crocksdb_readoptions_set_total_order_seek(
crocksdb_readoptions_t*, unsigned char); 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 */ /* Write options */
......
...@@ -374,6 +374,7 @@ extern "C" { ...@@ -374,6 +374,7 @@ extern "C" {
pub fn crocksdb_readoptions_set_read_tier(readopts: *mut DBReadOptions, tier: c_int); 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_tailing(readopts: *mut DBReadOptions, v: bool);
pub fn crocksdb_readoptions_set_total_order_seek(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, pub fn crocksdb_get(db: *const DBInstance,
readopts: *const DBReadOptions, readopts: *const DBReadOptions,
......
...@@ -214,6 +214,12 @@ impl ReadOptions { ...@@ -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 { pub unsafe fn get_inner(&self) -> *const DBReadOptions {
self.inner self.inner
} }
......
...@@ -14,13 +14,27 @@ ...@@ -14,13 +14,27 @@
use rocksdb::*; use rocksdb::*;
use tempdir::TempDir; 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 { struct FixedSuffixTransform {
pub suffix_len: usize, pub suffix_len: usize,
} }
impl SliceTransform for FixedSuffixTransform { impl SliceTransform for FixedSuffixTransform {
fn transform<'a>(&mut self, key: &'a [u8]) -> &'a [u8] { 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 { fn in_domain(&mut self, key: &[u8]) -> bool {
...@@ -37,6 +51,15 @@ fn prev_collect<'a>(iter: &mut DBIterator<'a>) -> Vec<Kv> { ...@@ -37,6 +51,15 @@ fn prev_collect<'a>(iter: &mut DBIterator<'a>) -> Vec<Kv> {
buf 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] #[test]
pub fn test_iterator() { pub fn test_iterator() {
let path = TempDir::new("_rust_rocksdb_iteratortest").expect(""); let path = TempDir::new("_rust_rocksdb_iteratortest").expect("");
...@@ -203,14 +226,8 @@ fn read_with_upper_bound() { ...@@ -203,14 +226,8 @@ fn read_with_upper_bound() {
readopts.set_iterate_upper_bound(b"k2"); readopts.set_iterate_upper_bound(b"k2");
let mut iter = db.iter_opt(readopts); let mut iter = db.iter_opt(readopts);
iter.seek(SeekKey::Start); iter.seek(SeekKey::Start);
let mut count = 0; let vec = next_collect(&mut iter);
while iter.valid() { assert_eq!(vec.len(), 2);
count += 1;
if !iter.next() {
break;
}
}
assert_eq!(count, 2);
} }
} }
...@@ -223,45 +240,60 @@ fn test_total_order_seek() { ...@@ -223,45 +240,60 @@ fn test_total_order_seek() {
let mut opts = Options::new(); let mut opts = Options::new();
opts.create_if_missing(true); opts.create_if_missing(true);
opts.set_block_based_table_factory(&bbto); opts.set_block_based_table_factory(&bbto);
opts.set_prefix_extractor("FixedSuffixTransform", opts.set_prefix_extractor("FixedPrefixTransform",
Box::new(FixedSuffixTransform { suffix_len: 2 })) Box::new(FixedPrefixTransform { prefix_len: 2 }))
.unwrap(); .unwrap();
// also create prefix bloom for memtable // also create prefix bloom for memtable
opts.set_memtable_prefix_bloom_size_ratio(0.1 as f64); 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", 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-2"]; b"k3-3"];
let db = DB::open(opts, path.path().to_str().unwrap()).unwrap(); let db = DB::open(opts, path.path().to_str().unwrap()).unwrap();
let wopts = WriteOptions::new(); let wopts = WriteOptions::new();
// sst1 // sst1
db.put_opt(b"k1-0", b"a", &wopts).unwrap(); db.put_opt(b"k1-1", b"a", &wopts).unwrap();
db.put_opt(b"k1-1", b"b", &wopts).unwrap(); db.put_opt(b"k1-2", b"b", &wopts).unwrap();
db.put_opt(b"k1-2", b"c", &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. db.flush(true /* sync */).unwrap(); // flush memtable to sst file.
// sst2 // sst2
db.put_opt(b"k2-0", b"a", &wopts).unwrap(); db.put_opt(b"k2-2", b"b", &wopts).unwrap();
db.put_opt(b"k2-1", b"b", &wopts).unwrap(); db.put_opt(b"k2-3", b"c", &wopts).unwrap();
db.put_opt(b"k2-2", b"c", &wopts).unwrap();
db.flush(true /* sync */).unwrap(); // flush memtable to sst file. db.flush(true /* sync */).unwrap(); // flush memtable to sst file.
// memtable // memtable
db.put_opt(b"k3-0", b"a", &wopts).unwrap(); db.put_opt(b"k3-1", b"a", &wopts).unwrap();
db.put_opt(b"k3-1", b"b", &wopts).unwrap(); db.put_opt(b"k3-2", b"b", &wopts).unwrap();
db.put_opt(b"k3-2", b"c", &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")); iter.seek(SeekKey::Key(b"k1-0"));
let mut key_count = 0; let mut key_count = 0;
while iter.valid() { 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()); assert_eq!(keys[key_count], iter.key());
key_count = key_count + 1; key_count = key_count + 1;
iter.next(); iter.next();
} }
assert!(key_count == 3); 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(); let mut ropts = ReadOptions::new();
ropts.set_total_order_seek(true); ropts.set_total_order_seek(true);
let mut iter = db.iter_opt(ropts); let mut iter = db.iter_opt(ropts);
...@@ -275,3 +307,33 @@ fn test_total_order_seek() { ...@@ -275,3 +307,33 @@ fn test_total_order_seek() {
} }
assert!(key_count == 9); 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 @@ ...@@ -14,17 +14,17 @@
use rocksdb::*; use rocksdb::*;
use tempdir::TempDir; use tempdir::TempDir;
struct FixedSuffixTransform { struct FixedPrefixTransform {
pub suffix_len: usize, pub prefix_len: usize,
} }
impl SliceTransform for FixedSuffixTransform { impl SliceTransform for FixedPrefixTransform {
fn transform<'a>(&mut self, key: &'a [u8]) -> &'a [u8] { 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 { 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() { ...@@ -56,8 +56,8 @@ fn test_prefix_extractor_compatibility() {
let mut opts = Options::new(); let mut opts = Options::new();
opts.create_if_missing(false); opts.create_if_missing(false);
opts.set_block_based_table_factory(&bbto); opts.set_block_based_table_factory(&bbto);
opts.set_prefix_extractor("FixedSuffixTransform", opts.set_prefix_extractor("FixedPrefixTransform",
Box::new(FixedSuffixTransform { suffix_len: 2 })) Box::new(FixedPrefixTransform { prefix_len: 2 }))
.unwrap(); .unwrap();
// also create prefix bloom for memtable // also create prefix bloom for memtable
opts.set_memtable_prefix_bloom_size_ratio(0.1 as f64); 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