Unverified Commit fa83ff19 authored by JAYICE's avatar JAYICE Committed by GitHub

Reduce boxing in callback (#671)

* reduce extra boxing
close https://github.com/tikv/rust-rocksdb/issues/513Signed-off-by: 's avatarJayice <1185430411@qq.com>

* rename generic
close https://github.com/tikv/rust-rocksdb/issues/513Signed-off-by: 's avatarJayice <1185430411@qq.com>

* format code
close https://github.com/tikv/rust-rocksdb/issues/513Signed-off-by: 's avatarJayice <1185430411@qq.com>
parent 035db162
...@@ -72,22 +72,22 @@ pub trait CompactionFilter { ...@@ -72,22 +72,22 @@ pub trait CompactionFilter {
} }
#[repr(C)] #[repr(C)]
struct CompactionFilterProxy { struct CompactionFilterProxy<C: CompactionFilter> {
name: CString, name: CString,
filter: Box<dyn CompactionFilter>, filter: C,
} }
extern "C" fn name(filter: *mut c_void) -> *const c_char { extern "C" fn name<C: CompactionFilter>(filter: *mut c_void) -> *const c_char {
unsafe { (*(filter as *mut CompactionFilterProxy)).name.as_ptr() } unsafe { (*(filter as *mut CompactionFilterProxy<C>)).name.as_ptr() }
} }
extern "C" fn destructor(filter: *mut c_void) { extern "C" fn destructor<C: CompactionFilter>(filter: *mut c_void) {
unsafe { unsafe {
Box::from_raw(filter as *mut CompactionFilterProxy); Box::from_raw(filter as *mut CompactionFilterProxy<C>);
} }
} }
extern "C" fn filter( extern "C" fn filter<C: CompactionFilter>(
filter: *mut c_void, filter: *mut c_void,
level: c_int, level: c_int,
key: *const u8, key: *const u8,
...@@ -107,7 +107,7 @@ extern "C" fn filter( ...@@ -107,7 +107,7 @@ extern "C" fn filter(
*skip_until = ptr::null_mut(); *skip_until = ptr::null_mut();
*skip_until_length = 0; *skip_until_length = 0;
let filter = &mut (*(filter as *mut CompactionFilterProxy)).filter; let filter = &mut (*(filter as *mut CompactionFilterProxy<C>)).filter;
let key = slice::from_raw_parts(key, key_len); let key = slice::from_raw_parts(key, key_len);
let value = slice::from_raw_parts(value, value_len); let value = slice::from_raw_parts(value, value_len);
match filter.featured_filter(level as usize, key, seqno, value, value_type) { match filter.featured_filter(level as usize, key, seqno, value, value_type) {
...@@ -141,9 +141,9 @@ impl Drop for CompactionFilterHandle { ...@@ -141,9 +141,9 @@ impl Drop for CompactionFilterHandle {
} }
} }
pub unsafe fn new_compaction_filter( pub unsafe fn new_compaction_filter<C: CompactionFilter>(
c_name: CString, c_name: CString,
f: Box<dyn CompactionFilter>, f: C,
) -> CompactionFilterHandle { ) -> CompactionFilterHandle {
let filter = new_compaction_filter_raw(c_name, f); let filter = new_compaction_filter_raw(c_name, f);
CompactionFilterHandle { inner: filter } CompactionFilterHandle { inner: filter }
...@@ -151,18 +151,24 @@ pub unsafe fn new_compaction_filter( ...@@ -151,18 +151,24 @@ pub unsafe fn new_compaction_filter(
/// Just like `new_compaction_filter`, but returns a raw pointer instead of a RAII struct. /// Just like `new_compaction_filter`, but returns a raw pointer instead of a RAII struct.
/// Generally used in `CompactionFilterFactory::create_compaction_filter`. /// Generally used in `CompactionFilterFactory::create_compaction_filter`.
pub unsafe fn new_compaction_filter_raw( pub unsafe fn new_compaction_filter_raw<C: CompactionFilter>(
c_name: CString, c_name: CString,
f: Box<dyn CompactionFilter>, f: C,
) -> *mut DBCompactionFilter { ) -> *mut DBCompactionFilter {
let proxy = Box::into_raw(Box::new(CompactionFilterProxy { let proxy = Box::into_raw(Box::new(CompactionFilterProxy {
name: c_name, name: c_name,
filter: f, filter: f,
})); }));
crocksdb_ffi::crocksdb_compactionfilter_create(proxy as *mut c_void, destructor, filter, name) crocksdb_ffi::crocksdb_compactionfilter_create(
proxy as *mut c_void,
destructor::<C>,
filter::<C>,
name::<C>,
)
} }
pub struct CompactionFilterContext(DBCompactionFilterContext); pub struct CompactionFilterContext(DBCompactionFilterContext);
impl CompactionFilterContext { impl CompactionFilterContext {
pub fn is_full_compaction(&self) -> bool { pub fn is_full_compaction(&self) -> bool {
let ctx = &self.0 as *const DBCompactionFilterContext; let ctx = &self.0 as *const DBCompactionFilterContext;
...@@ -239,47 +245,49 @@ pub trait CompactionFilterFactory { ...@@ -239,47 +245,49 @@ pub trait CompactionFilterFactory {
} }
#[repr(C)] #[repr(C)]
struct CompactionFilterFactoryProxy { struct CompactionFilterFactoryProxy<C: CompactionFilterFactory> {
name: CString, name: CString,
factory: Box<dyn CompactionFilterFactory>, factory: C,
} }
mod factory { mod factory {
use super::{CompactionFilterContext, CompactionFilterFactoryProxy}; use super::{CompactionFilterContext, CompactionFilterFactory, CompactionFilterFactoryProxy};
use crocksdb_ffi::{DBCompactionFilter, DBCompactionFilterContext}; use crocksdb_ffi::{DBCompactionFilter, DBCompactionFilterContext};
use libc::{c_char, c_uchar, c_void}; use libc::{c_char, c_uchar, c_void};
use librocksdb_sys::DBTableFileCreationReason; use librocksdb_sys::DBTableFileCreationReason;
pub(super) extern "C" fn name(factory: *mut c_void) -> *const c_char { pub(super) extern "C" fn name<C: CompactionFilterFactory>(
factory: *mut c_void,
) -> *const c_char {
unsafe { unsafe {
let proxy = &*(factory as *mut CompactionFilterFactoryProxy); let proxy = &*(factory as *mut CompactionFilterFactoryProxy<C>);
proxy.name.as_ptr() proxy.name.as_ptr()
} }
} }
pub(super) extern "C" fn destructor(factory: *mut c_void) { pub(super) extern "C" fn destructor<C: CompactionFilterFactory>(factory: *mut c_void) {
unsafe { unsafe {
Box::from_raw(factory as *mut CompactionFilterFactoryProxy); Box::from_raw(factory as *mut CompactionFilterFactoryProxy<C>);
} }
} }
pub(super) extern "C" fn create_compaction_filter( pub(super) extern "C" fn create_compaction_filter<C: CompactionFilterFactory>(
factory: *mut c_void, factory: *mut c_void,
context: *const DBCompactionFilterContext, context: *const DBCompactionFilterContext,
) -> *mut DBCompactionFilter { ) -> *mut DBCompactionFilter {
unsafe { unsafe {
let factory = &mut *(factory as *mut CompactionFilterFactoryProxy); let factory = &mut *(factory as *mut CompactionFilterFactoryProxy<C>);
let context: &CompactionFilterContext = &*(context as *const CompactionFilterContext); let context: &CompactionFilterContext = &*(context as *const CompactionFilterContext);
factory.factory.create_compaction_filter(context) factory.factory.create_compaction_filter(context)
} }
} }
pub(super) extern "C" fn should_filter_table_file_creation( pub(super) extern "C" fn should_filter_table_file_creation<C: CompactionFilterFactory>(
factory: *const c_void, factory: *const c_void,
reason: DBTableFileCreationReason, reason: DBTableFileCreationReason,
) -> c_uchar { ) -> c_uchar {
unsafe { unsafe {
let factory = &*(factory as *const CompactionFilterFactoryProxy); let factory = &*(factory as *const CompactionFilterFactoryProxy<C>);
let reason: DBTableFileCreationReason = reason as DBTableFileCreationReason; let reason: DBTableFileCreationReason = reason as DBTableFileCreationReason;
factory.factory.should_filter_table_file_creation(reason) factory.factory.should_filter_table_file_creation(reason)
} }
...@@ -298,9 +306,9 @@ impl Drop for CompactionFilterFactoryHandle { ...@@ -298,9 +306,9 @@ impl Drop for CompactionFilterFactoryHandle {
} }
} }
pub unsafe fn new_compaction_filter_factory( pub unsafe fn new_compaction_filter_factory<C: CompactionFilterFactory>(
c_name: CString, c_name: CString,
f: Box<dyn CompactionFilterFactory>, f: C,
) -> Result<CompactionFilterFactoryHandle, String> { ) -> Result<CompactionFilterFactoryHandle, String> {
let proxy = Box::into_raw(Box::new(CompactionFilterFactoryProxy { let proxy = Box::into_raw(Box::new(CompactionFilterFactoryProxy {
name: c_name, name: c_name,
...@@ -309,10 +317,10 @@ pub unsafe fn new_compaction_filter_factory( ...@@ -309,10 +317,10 @@ pub unsafe fn new_compaction_filter_factory(
let factory = crocksdb_ffi::crocksdb_compactionfilterfactory_create( let factory = crocksdb_ffi::crocksdb_compactionfilterfactory_create(
proxy as *mut c_void, proxy as *mut c_void,
self::factory::destructor, self::factory::destructor::<C>,
self::factory::create_compaction_filter, self::factory::create_compaction_filter::<C>,
self::factory::should_filter_table_file_creation, self::factory::should_filter_table_file_creation::<C>,
self::factory::name, self::factory::name::<C>,
); );
Ok(CompactionFilterFactoryHandle { inner: factory }) Ok(CompactionFilterFactoryHandle { inner: factory })
...@@ -334,11 +342,13 @@ mod tests { ...@@ -334,11 +342,13 @@ mod tests {
}; };
struct Factory(SyncSender<()>); struct Factory(SyncSender<()>);
impl Drop for Factory { impl Drop for Factory {
fn drop(&mut self) { fn drop(&mut self) {
self.0.send(()).unwrap(); self.0.send(()).unwrap();
} }
} }
impl CompactionFilterFactory for Factory { impl CompactionFilterFactory for Factory {
fn create_compaction_filter(&self, _: &CompactionFilterContext) -> *mut DBCompactionFilter { fn create_compaction_filter(&self, _: &CompactionFilterContext) -> *mut DBCompactionFilter {
return std::ptr::null_mut(); return std::ptr::null_mut();
...@@ -346,11 +356,13 @@ mod tests { ...@@ -346,11 +356,13 @@ mod tests {
} }
struct Filter(SyncSender<()>); struct Filter(SyncSender<()>);
impl Drop for Filter { impl Drop for Filter {
fn drop(&mut self) { fn drop(&mut self) {
self.0.send(()).unwrap(); self.0.send(()).unwrap();
} }
} }
impl CompactionFilter for Filter { impl CompactionFilter for Filter {
fn filter(&mut self, _: usize, _: &[u8], _: &[u8], _: &mut Vec<u8>, _: &mut bool) -> bool { fn filter(&mut self, _: usize, _: &[u8], _: &[u8], _: &mut Vec<u8>, _: &mut bool) -> bool {
false false
...@@ -358,6 +370,7 @@ mod tests { ...@@ -358,6 +370,7 @@ mod tests {
} }
struct KeyRangeFilter; struct KeyRangeFilter;
impl CompactionFilter for KeyRangeFilter { impl CompactionFilter for KeyRangeFilter {
fn filter(&mut self, _: usize, _: &[u8], _: &[u8], _: &mut Vec<u8>, _: &mut bool) -> bool { fn filter(&mut self, _: usize, _: &[u8], _: &[u8], _: &mut Vec<u8>, _: &mut bool) -> bool {
false false
...@@ -365,6 +378,7 @@ mod tests { ...@@ -365,6 +378,7 @@ mod tests {
} }
struct KeyRangeFactory(SyncSender<Vec<u8>>); struct KeyRangeFactory(SyncSender<Vec<u8>>);
impl CompactionFilterFactory for KeyRangeFactory { impl CompactionFilterFactory for KeyRangeFactory {
fn create_compaction_filter( fn create_compaction_filter(
&self, &self,
...@@ -376,15 +390,18 @@ mod tests { ...@@ -376,15 +390,18 @@ mod tests {
&self.0.send(end_key.to_owned()).unwrap(); &self.0.send(end_key.to_owned()).unwrap();
unsafe { unsafe {
new_compaction_filter_raw( new_compaction_filter_raw::<KeyRangeFilter>(
CString::new("key_range_filter").unwrap(), CString::new("key_range_filter").unwrap(),
Box::new(KeyRangeFilter), KeyRangeFilter,
) )
} }
} }
} }
struct FlushFactory {} struct FlushFactory {}
struct FlushFilter {} struct FlushFilter {}
impl CompactionFilter for FlushFilter { impl CompactionFilter for FlushFilter {
fn filter(&mut self, _: usize, _: &[u8], _: &[u8], _: &mut Vec<u8>, _: &mut bool) -> bool { fn filter(&mut self, _: usize, _: &[u8], _: &[u8], _: &mut Vec<u8>, _: &mut bool) -> bool {
true true
...@@ -400,9 +417,8 @@ mod tests { ...@@ -400,9 +417,8 @@ mod tests {
&self, &self,
_context: &CompactionFilterContext, _context: &CompactionFilterContext,
) -> *mut DBCompactionFilter { ) -> *mut DBCompactionFilter {
let filter = Box::new(FlushFilter {});
let name = CString::new("flush_compaction_filter").unwrap(); let name = CString::new("flush_compaction_filter").unwrap();
unsafe { new_compaction_filter_raw(name, filter) } unsafe { new_compaction_filter_raw::<FlushFilter>(name, FlushFilter {}) }
} }
} }
...@@ -411,9 +427,9 @@ mod tests { ...@@ -411,9 +427,9 @@ mod tests {
let (tx, rx) = mpsc::sync_channel(1); let (tx, rx) = mpsc::sync_channel(1);
let mut cf_opts = ColumnFamilyOptions::default(); let mut cf_opts = ColumnFamilyOptions::default();
let name = CString::new("compaction filter factory").unwrap(); let name = CString::new("compaction filter factory").unwrap();
let factory = Box::new(Factory(tx)) as Box<dyn CompactionFilterFactory>; let factory = Factory(tx);
cf_opts cf_opts
.set_compaction_filter_factory(name, factory) .set_compaction_filter_factory::<CString, Factory>(name, factory)
.unwrap(); .unwrap();
drop(cf_opts); drop(cf_opts);
assert!(rx.recv_timeout(Duration::from_secs(1)).is_ok()); assert!(rx.recv_timeout(Duration::from_secs(1)).is_ok());
...@@ -431,9 +447,9 @@ mod tests { ...@@ -431,9 +447,9 @@ mod tests {
cfds.push(("default", { cfds.push(("default", {
let mut cf_opts = ColumnFamilyOptions::default(); let mut cf_opts = ColumnFamilyOptions::default();
let name = CString::new("compaction filter factory").unwrap(); let name = CString::new("compaction filter factory").unwrap();
let factory = Box::new(Factory(tx)) as Box<dyn CompactionFilterFactory>; let factory = Factory(tx);
cf_opts cf_opts
.set_compaction_filter_factory(name, factory) .set_compaction_filter_factory::<CString, Factory>(name, factory)
.unwrap(); .unwrap();
cf_opts cf_opts
})); }));
...@@ -447,8 +463,10 @@ mod tests { ...@@ -447,8 +463,10 @@ mod tests {
let (tx, rx) = mpsc::sync_channel(1); let (tx, rx) = mpsc::sync_channel(1);
let mut cf_opts = ColumnFamilyOptions::default(); let mut cf_opts = ColumnFamilyOptions::default();
let name = CString::new("compaction filter factory").unwrap(); let name = CString::new("compaction filter factory").unwrap();
let filter = Box::new(Filter(tx)) as Box<dyn CompactionFilter>; let filter = Filter(tx);
cf_opts.set_compaction_filter(name, filter).unwrap(); cf_opts
.set_compaction_filter::<CString, Filter>(name, filter)
.unwrap();
drop(cf_opts); drop(cf_opts);
assert!(rx.recv_timeout(Duration::from_secs(1)).is_ok()); assert!(rx.recv_timeout(Duration::from_secs(1)).is_ok());
...@@ -465,8 +483,10 @@ mod tests { ...@@ -465,8 +483,10 @@ mod tests {
cfds.push(("default", { cfds.push(("default", {
let mut cf_opts = ColumnFamilyOptions::default(); let mut cf_opts = ColumnFamilyOptions::default();
let name = CString::new("compaction filter factory").unwrap(); let name = CString::new("compaction filter factory").unwrap();
let filter = Box::new(Filter(tx)) as Box<dyn CompactionFilter>; let filter = Filter(tx);
cf_opts.set_compaction_filter(name, filter).unwrap(); cf_opts
.set_compaction_filter::<CString, Filter>(name, filter)
.unwrap();
cf_opts cf_opts
})); }));
let db = DB::open_cf(db_opts, path, cfds); let db = DB::open_cf(db_opts, path, cfds);
...@@ -479,9 +499,9 @@ mod tests { ...@@ -479,9 +499,9 @@ mod tests {
let mut cf_opts = ColumnFamilyOptions::default(); let mut cf_opts = ColumnFamilyOptions::default();
let name = CString::new("compaction filter factory").unwrap(); let name = CString::new("compaction filter factory").unwrap();
let (tx, rx) = mpsc::sync_channel(2); let (tx, rx) = mpsc::sync_channel(2);
let factory = Box::new(KeyRangeFactory(tx)) as Box<dyn CompactionFilterFactory>; let factory = KeyRangeFactory(tx);
cf_opts cf_opts
.set_compaction_filter_factory(name, factory) .set_compaction_filter_factory::<CString, KeyRangeFactory>(name, factory)
.unwrap(); .unwrap();
let mut opts = DBOptions::new(); let mut opts = DBOptions::new();
opts.create_if_missing(true); opts.create_if_missing(true);
...@@ -514,10 +534,10 @@ mod tests { ...@@ -514,10 +534,10 @@ mod tests {
fn test_flush_filter() { fn test_flush_filter() {
// cf with filter // cf with filter
let name = CString::new("test_flush_filter_factory").unwrap(); let name = CString::new("test_flush_filter_factory").unwrap();
let factory = Box::new(FlushFactory {}) as Box<dyn CompactionFilterFactory>; let factory = FlushFactory {};
let mut cf_opts_wf = ColumnFamilyOptions::default(); let mut cf_opts_wf = ColumnFamilyOptions::default();
cf_opts_wf cf_opts_wf
.set_compaction_filter_factory(name, factory) .set_compaction_filter_factory::<CString, FlushFactory>(name, factory)
.unwrap(); .unwrap();
cf_opts_wf.set_disable_auto_compactions(true); cf_opts_wf.set_disable_auto_compactions(true);
......
...@@ -1387,20 +1387,17 @@ impl ColumnFamilyOptions { ...@@ -1387,20 +1387,17 @@ impl ColumnFamilyOptions {
/// recent call to GetSnapshot() to filter. /// recent call to GetSnapshot() to filter.
/// ///
/// See also `CompactionFilter`. /// See also `CompactionFilter`.
pub fn set_compaction_filter<S>( pub fn set_compaction_filter<S, C>(&mut self, name: S, filter: C) -> Result<(), String>
&mut self,
name: S,
filter: Box<dyn CompactionFilter>,
) -> Result<(), String>
where where
S: Into<Vec<u8>>, S: Into<Vec<u8>>,
C: CompactionFilter,
{ {
unsafe { unsafe {
let c_name = match CString::new(name) { let c_name = match CString::new(name) {
Ok(s) => s, Ok(s) => s,
Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)), Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)),
}; };
let filter = new_compaction_filter(c_name, filter); let filter = new_compaction_filter::<C>(c_name, filter);
crocksdb_ffi::crocksdb_options_set_compaction_filter(self.inner, filter.inner); crocksdb_ffi::crocksdb_options_set_compaction_filter(self.inner, filter.inner);
self.filter = Some(filter); self.filter = Some(filter);
Ok(()) Ok(())
...@@ -1410,20 +1407,17 @@ impl ColumnFamilyOptions { ...@@ -1410,20 +1407,17 @@ impl ColumnFamilyOptions {
/// Set compaction filter factory. /// Set compaction filter factory.
/// ///
/// See also `CompactionFilterFactory`. /// See also `CompactionFilterFactory`.
pub fn set_compaction_filter_factory<S>( pub fn set_compaction_filter_factory<S, C>(&mut self, name: S, factory: C) -> Result<(), String>
&mut self,
name: S,
factory: Box<dyn CompactionFilterFactory>,
) -> Result<(), String>
where where
S: Into<Vec<u8>>, S: Into<Vec<u8>>,
C: CompactionFilterFactory,
{ {
let c_name = match CString::new(name) { let c_name = match CString::new(name) {
Ok(s) => s, Ok(s) => s,
Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)), Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)),
}; };
unsafe { unsafe {
let factory = new_compaction_filter_factory(c_name, factory)?; let factory = new_compaction_filter_factory::<C>(c_name, factory)?;
crocksdb_ffi::crocksdb_options_set_compaction_filter_factory(self.inner, factory.inner); crocksdb_ffi::crocksdb_options_set_compaction_filter_factory(self.inner, factory.inner);
std::mem::forget(factory); // Deconstructor will be called after `self` is dropped. std::mem::forget(factory); // Deconstructor will be called after `self` is dropped.
Ok(()) Ok(())
...@@ -1789,20 +1783,17 @@ impl ColumnFamilyOptions { ...@@ -1789,20 +1783,17 @@ impl ColumnFamilyOptions {
unsafe { crocksdb_ffi::crocksdb_options_get_num_levels(self.inner) as usize } unsafe { crocksdb_ffi::crocksdb_options_get_num_levels(self.inner) as usize }
} }
pub fn set_prefix_extractor<S>( pub fn set_prefix_extractor<S, ST>(&mut self, name: S, transform: ST) -> Result<(), String>
&mut self,
name: S,
transform: Box<dyn SliceTransform>,
) -> Result<(), String>
where where
S: Into<Vec<u8>>, S: Into<Vec<u8>>,
ST: SliceTransform,
{ {
unsafe { unsafe {
let c_name = match CString::new(name) { let c_name = match CString::new(name) {
Ok(s) => s, Ok(s) => s,
Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)), Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)),
}; };
let transform = new_slice_transform(c_name, transform)?; let transform = new_slice_transform::<ST>(c_name, transform)?;
crocksdb_ffi::crocksdb_options_set_prefix_extractor(self.inner, transform); crocksdb_ffi::crocksdb_options_set_prefix_extractor(self.inner, transform);
Ok(()) Ok(())
} }
...@@ -1814,20 +1805,21 @@ impl ColumnFamilyOptions { ...@@ -1814,20 +1805,21 @@ impl ColumnFamilyOptions {
} }
} }
pub fn set_memtable_insert_hint_prefix_extractor<S>( pub fn set_memtable_insert_hint_prefix_extractor<S, ST>(
&mut self, &mut self,
name: S, name: S,
transform: Box<dyn SliceTransform>, transform: ST,
) -> Result<(), String> ) -> Result<(), String>
where where
S: Into<Vec<u8>>, S: Into<Vec<u8>>,
ST: SliceTransform,
{ {
unsafe { unsafe {
let c_name = match CString::new(name) { let c_name = match CString::new(name) {
Ok(s) => s, Ok(s) => s,
Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)), Err(e) => return Err(format!("failed to convert to cstring: {:?}", e)),
}; };
let transform = new_slice_transform(c_name, transform)?; let transform = new_slice_transform::<ST>(c_name, transform)?;
crocksdb_ffi::crocksdb_options_set_memtable_insert_with_hint_prefix_extractor( crocksdb_ffi::crocksdb_options_set_memtable_insert_with_hint_prefix_extractor(
self.inner, transform, self.inner, transform,
); );
......
...@@ -16,7 +16,7 @@ use libc::{c_char, c_void, size_t}; ...@@ -16,7 +16,7 @@ use libc::{c_char, c_void, size_t};
use std::ffi::CString; use std::ffi::CString;
use std::slice; use std::slice;
// `SliceTranform` is a generic pluggable way of transforming one string // `SliceTransform` is a generic pluggable way of transforming one string
// mainly used for prefix blooms. // mainly used for prefix blooms.
pub trait SliceTransform { pub trait SliceTransform {
// Extract a prefix from a specified key // Extract a prefix from a specified key
...@@ -38,29 +38,29 @@ pub trait SliceTransform { ...@@ -38,29 +38,29 @@ pub trait SliceTransform {
} }
#[repr(C)] #[repr(C)]
pub struct SliceTransformProxy { pub struct SliceTransformProxy<S: SliceTransform> {
name: CString, name: CString,
transform: Box<dyn SliceTransform>, transform: S,
} }
extern "C" fn name(transform: *mut c_void) -> *const c_char { extern "C" fn name<S: SliceTransform>(transform: *mut c_void) -> *const c_char {
unsafe { (*(transform as *mut SliceTransformProxy)).name.as_ptr() } unsafe { (*(transform as *mut SliceTransformProxy<S>)).name.as_ptr() }
} }
extern "C" fn destructor(transform: *mut c_void) { extern "C" fn destructor<S: SliceTransform>(transform: *mut c_void) {
unsafe { unsafe {
Box::from_raw(transform as *mut SliceTransformProxy); Box::from_raw(transform as *mut SliceTransformProxy<S>);
} }
} }
extern "C" fn transform( extern "C" fn transform<S: SliceTransform>(
transform: *mut c_void, transform: *mut c_void,
key: *const u8, key: *const u8,
key_len: size_t, key_len: size_t,
dest_len: *mut size_t, dest_len: *mut size_t,
) -> *const u8 { ) -> *const u8 {
unsafe { unsafe {
let transform = &mut *(transform as *mut SliceTransformProxy); let transform = &mut *(transform as *mut SliceTransformProxy<S>);
let key = slice::from_raw_parts(key, key_len); let key = slice::from_raw_parts(key, key_len);
let prefix = transform.transform.transform(key); let prefix = transform.transform.transform(key);
*dest_len = prefix.len() as size_t; *dest_len = prefix.len() as size_t;
...@@ -68,25 +68,33 @@ extern "C" fn transform( ...@@ -68,25 +68,33 @@ extern "C" fn transform(
} }
} }
extern "C" fn in_domain(transform: *mut c_void, key: *const u8, key_len: size_t) -> u8 { extern "C" fn in_domain<S: SliceTransform>(
transform: *mut c_void,
key: *const u8,
key_len: size_t,
) -> u8 {
unsafe { unsafe {
let transform = &mut *(transform as *mut SliceTransformProxy); let transform = &mut *(transform as *mut SliceTransformProxy<S>);
let key = slice::from_raw_parts(key, key_len); let key = slice::from_raw_parts(key, key_len);
transform.transform.in_domain(key) as u8 transform.transform.in_domain(key) as u8
} }
} }
extern "C" fn in_range(transform: *mut c_void, key: *const u8, key_len: size_t) -> u8 { extern "C" fn in_range<S: SliceTransform>(
transform: *mut c_void,
key: *const u8,
key_len: size_t,
) -> u8 {
unsafe { unsafe {
let transform = &mut *(transform as *mut SliceTransformProxy); let transform = &mut *(transform as *mut SliceTransformProxy<S>);
let key = slice::from_raw_parts(key, key_len); let key = slice::from_raw_parts(key, key_len);
transform.transform.in_range(key) as u8 transform.transform.in_range(key) as u8
} }
} }
pub unsafe fn new_slice_transform( pub unsafe fn new_slice_transform<S: SliceTransform>(
c_name: CString, c_name: CString,
f: Box<dyn SliceTransform>, f: S,
) -> Result<*mut DBSliceTransform, String> { ) -> Result<*mut DBSliceTransform, String> {
let proxy = Box::into_raw(Box::new(SliceTransformProxy { let proxy = Box::into_raw(Box::new(SliceTransformProxy {
name: c_name, name: c_name,
...@@ -94,11 +102,11 @@ pub unsafe fn new_slice_transform( ...@@ -94,11 +102,11 @@ pub unsafe fn new_slice_transform(
})); }));
let transform = crocksdb_ffi::crocksdb_slicetransform_create( let transform = crocksdb_ffi::crocksdb_slicetransform_create(
proxy as *mut c_void, proxy as *mut c_void,
destructor, destructor::<S>,
transform, transform::<S>,
in_domain, in_domain::<S>,
in_range, in_range::<S>,
name, name::<S>,
); );
Ok(transform) Ok(transform)
} }
...@@ -55,12 +55,12 @@ fn test_compaction_filter() { ...@@ -55,12 +55,12 @@ fn test_compaction_filter() {
// reregister with ignore_snapshots set to true // reregister with ignore_snapshots set to true
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
cf_opts cf_opts
.set_compaction_filter( .set_compaction_filter::<&str, Filter>(
"test", "test",
Box::new(Filter { Filter {
drop_called: drop_called.clone(), drop_called: drop_called.clone(),
filtered_kvs: filtered_kvs.clone(), filtered_kvs: filtered_kvs.clone(),
}), },
) )
.unwrap(); .unwrap();
......
...@@ -639,9 +639,9 @@ fn test_delete_range_prefix_bloom_case_1() { ...@@ -639,9 +639,9 @@ fn test_delete_range_prefix_bloom_case_1() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -714,9 +714,9 @@ fn test_delete_range_prefix_bloom_case_2() { ...@@ -714,9 +714,9 @@ fn test_delete_range_prefix_bloom_case_2() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -770,9 +770,9 @@ fn test_delete_range_prefix_bloom_case_2() { ...@@ -770,9 +770,9 @@ fn test_delete_range_prefix_bloom_case_2() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -807,9 +807,9 @@ fn test_delete_range_prefix_bloom_case_3() { ...@@ -807,9 +807,9 @@ fn test_delete_range_prefix_bloom_case_3() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -852,9 +852,9 @@ fn test_delete_range_prefix_bloom_case_3() { ...@@ -852,9 +852,9 @@ fn test_delete_range_prefix_bloom_case_3() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -903,9 +903,9 @@ fn test_delete_range_prefix_bloom_case_4() { ...@@ -903,9 +903,9 @@ fn test_delete_range_prefix_bloom_case_4() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -948,9 +948,9 @@ fn test_delete_range_prefix_bloom_case_4() { ...@@ -948,9 +948,9 @@ fn test_delete_range_prefix_bloom_case_4() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -1000,9 +1000,9 @@ fn test_delete_range_prefix_bloom_case_5() { ...@@ -1000,9 +1000,9 @@ fn test_delete_range_prefix_bloom_case_5() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -1043,9 +1043,9 @@ fn test_delete_range_prefix_bloom_case_5() { ...@@ -1043,9 +1043,9 @@ fn test_delete_range_prefix_bloom_case_5() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -1092,9 +1092,9 @@ fn test_delete_range_prefix_bloom_case_6() { ...@@ -1092,9 +1092,9 @@ fn test_delete_range_prefix_bloom_case_6() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -1137,9 +1137,9 @@ fn test_delete_range_prefix_bloom_case_6() { ...@@ -1137,9 +1137,9 @@ fn test_delete_range_prefix_bloom_case_6() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -1210,9 +1210,9 @@ fn test_delete_range_prefix_bloom_compact_case() { ...@@ -1210,9 +1210,9 @@ fn test_delete_range_prefix_bloom_compact_case() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
...@@ -1255,9 +1255,9 @@ fn test_delete_range_prefix_bloom_compact_case() { ...@@ -1255,9 +1255,9 @@ fn test_delete_range_prefix_bloom_compact_case() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
// Prefix extractor(trim the timestamp at tail) for write cf. // Prefix extractor(trim the timestamp at tail) for write cf.
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixSliceTransform>(
"FixedSuffixSliceTransform", "FixedSuffixSliceTransform",
Box::new(FixedSuffixSliceTransform::new(3)), FixedSuffixSliceTransform::new(3),
) )
.unwrap_or_else(|err| panic!(format!("{:?}", err))); .unwrap_or_else(|err| panic!(format!("{:?}", err)));
// Create prefix bloom filter for memtable. // Create prefix bloom filter for memtable.
......
...@@ -295,9 +295,9 @@ fn test_total_order_seek() { ...@@ -295,9 +295,9 @@ fn test_total_order_seek() {
opts.create_if_missing(true); opts.create_if_missing(true);
cf_opts.set_block_based_table_factory(&bbto); cf_opts.set_block_based_table_factory(&bbto);
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedPrefixTransform>(
"FixedPrefixTransform", "FixedPrefixTransform",
Box::new(FixedPrefixTransform { prefix_len: 2 }), FixedPrefixTransform { prefix_len: 2 },
) )
.unwrap(); .unwrap();
// also create prefix bloom for memtable // also create prefix bloom for memtable
...@@ -383,9 +383,9 @@ fn test_fixed_suffix_seek() { ...@@ -383,9 +383,9 @@ fn test_fixed_suffix_seek() {
opts.create_if_missing(true); opts.create_if_missing(true);
cf_opts.set_block_based_table_factory(&bbto); cf_opts.set_block_based_table_factory(&bbto);
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedSuffixTransform>(
"FixedSuffixTransform", "FixedSuffixTransform",
Box::new(FixedSuffixTransform { suffix_len: 2 }), FixedSuffixTransform { suffix_len: 2 },
) )
.unwrap(); .unwrap();
...@@ -428,7 +428,7 @@ fn test_iter_sequence_number() { ...@@ -428,7 +428,7 @@ fn test_iter_sequence_number() {
} }
} }
let (tx, rx) = mpsc::sync_channel(8); let (tx, rx) = mpsc::sync_channel(8);
let filter = Box::new(TestCompactionFilter(tx)); let filter = TestCompactionFilter(tx);
let path = tempdir_with_prefix("_rust_rocksdb_sequence_number"); let path = tempdir_with_prefix("_rust_rocksdb_sequence_number");
let mut opts = DBOptions::new(); let mut opts = DBOptions::new();
...@@ -436,7 +436,9 @@ fn test_iter_sequence_number() { ...@@ -436,7 +436,9 @@ fn test_iter_sequence_number() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
cf_opts.set_disable_auto_compactions(true); cf_opts.set_disable_auto_compactions(true);
cf_opts.set_num_levels(7); cf_opts.set_num_levels(7);
cf_opts.set_compaction_filter("test", filter).unwrap(); cf_opts
.set_compaction_filter::<&str, TestCompactionFilter>("test", filter)
.unwrap();
let db = DB::open_cf( let db = DB::open_cf(
opts, opts,
path.path().to_str().unwrap(), path.path().to_str().unwrap(),
......
...@@ -60,9 +60,9 @@ fn test_prefix_extractor_compatibility() { ...@@ -60,9 +60,9 @@ fn test_prefix_extractor_compatibility() {
opts.create_if_missing(false); opts.create_if_missing(false);
cf_opts.set_block_based_table_factory(&bbto); cf_opts.set_block_based_table_factory(&bbto);
cf_opts cf_opts
.set_prefix_extractor( .set_prefix_extractor::<&str, FixedPrefixTransform>(
"FixedPrefixTransform", "FixedPrefixTransform",
Box::new(FixedPrefixTransform { prefix_len: 2 }), FixedPrefixTransform { prefix_len: 2 },
) )
.unwrap(); .unwrap();
// also create prefix bloom for memtable // also create prefix bloom for memtable
......
...@@ -124,9 +124,9 @@ fn test_memtable_insert_hint_prefix_extractor() { ...@@ -124,9 +124,9 @@ fn test_memtable_insert_hint_prefix_extractor() {
let mut cf_opts = ColumnFamilyOptions::new(); let mut cf_opts = ColumnFamilyOptions::new();
opts.create_if_missing(true); opts.create_if_missing(true);
cf_opts cf_opts
.set_memtable_insert_hint_prefix_extractor( .set_memtable_insert_hint_prefix_extractor::<&str, FixedPrefixTransform>(
"FixedPrefixTransform", "FixedPrefixTransform",
Box::new(FixedPrefixTransform { prefix_len: 2 }), FixedPrefixTransform { prefix_len: 2 },
) )
.unwrap(); .unwrap();
let db = DB::open_cf( let db = DB::open_cf(
......
...@@ -46,7 +46,10 @@ fn test_slice_transform() { ...@@ -46,7 +46,10 @@ fn test_slice_transform() {
cf_opts.set_memtable_prefix_bloom_size_ratio(0.25); cf_opts.set_memtable_prefix_bloom_size_ratio(0.25);
cf_opts cf_opts
.set_prefix_extractor("test", Box::new(FixedPostfixTransform { postfix_len: 2 })) .set_prefix_extractor::<&str, FixedPostfixTransform>(
"test",
FixedPostfixTransform { postfix_len: 2 },
)
.unwrap(); .unwrap();
opts.create_if_missing(true); opts.create_if_missing(true);
......
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