Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use bindgen to auto generate ffi rust code #398

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

fredchenbj
Copy link
Member

@fredchenbj fredchenbj commented Dec 3, 2019

refer to #381.

just use old c.h and bindgen to gen ffi's rust code. and fix to pass cargo build.

this is step 1, later replace with rocksdb's c.h to gen code.

Signed-off-by: fredchenbj [email protected]

@fredchenbj fredchenbj changed the title [DNM] use bindgen to auto generate ffi rs code [DNM] use bindgen to auto generate ffi rust code Dec 3, 2019
@Connor1996 Connor1996 changed the title [DNM] use bindgen to auto generate ffi rust code use bindgen to auto generate ffi rust code Dec 4, 2019
@Connor1996
Copy link
Member

Please fix the conflicts

@fredchenbj
Copy link
Member Author

fredchenbj commented Dec 4, 2019

Please fix the conflicts

@Connor1996 I have fixed the conficts.

@@ -940,10 +943,10 @@ extern C_ROCKSDB_LIBRARY_API void crocksdb_options_enable_statistics(
crocksdb_options_t*, unsigned char);
extern C_ROCKSDB_LIBRARY_API void crocksdb_options_reset_statistics(
crocksdb_options_t*);
extern C_ROCKSDB_LIBRARY_API bool crocksdb_load_latest_options(
extern C_ROCKSDB_LIBRARY_API unsigned char crocksdb_load_latest_options(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bindgen generates FFI based on c.h, but why we modify c.h?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Connor1996 this function was added by us, so not conform to c's style.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rocksdb's c.h has convention:
Bools have the type unsigned char (0 == false; rest == true)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you extract them to a separate PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

step 1 finished.

Signed-off-by: fredchenbj <[email protected]>
Signed-off-by: fredchenbj <[email protected]>
@fredchenbj fredchenbj force-pushed the fredchenbj/bindgen_ffi branch from cc31d36 to 7f4b70e Compare December 4, 2019 03:54
@yiwu-arbug
Copy link
Collaborator

@fredchenbj awesome changes! Some general questions:

  1. Can you summarize what's changed in this PR? Seems mostly typing changes. Why are they needed?
  2. The PR seems not including the generated code. Should we checkin the generated code or not?
  3. What's the overall plan for migration?

Thanks.

@BusyJay
Copy link
Member

BusyJay commented Dec 4, 2019

It introduces clang dependency, which can be a pain to fix. You can learn how to avoid it from tikv/grpc-rs.

@Connor1996
Copy link
Member

@BusyJay You mean pre-generate binding? Yeah, that's what we plan to do. For easy reviewing, we plan to do it step by step.

@@ -26,7 +28,7 @@ use std::slice;
/// TablePropertiesCollector object per table and then call it sequentially
pub trait TablePropertiesCollector {
/// Will be called when a new key/value pair is inserted into the table.
fn add(&mut self, key: &[u8], value: &[u8], entry_type: DBEntryType, seq: u64, file_size: u64);
fn add(&mut self, key: &[i8], value: &[i8], entry_type: DBEntryType, seq: u64, file_size: u64);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why changing u8 to i8?

Copy link
Member Author

@fredchenbj fredchenbj Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for const char* in c.h is transferred to *const libc::c_char by bindgen, which requires i8. All transfer like this is for that. @Connor1996

Copy link
Member

@Connor1996 Connor1996 Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see references:

i8 or u8 is only due to how C char represents in different platforms. But the data is always one-byte long. As str in Rust is represented as &[u8], so we must convert it to u8.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it. I would fix it.


impl WriteStallInfo {
pub fn cf_name(&self) -> &str {
unsafe { fetch_str!(crocksdb_writestallinfo_cf_name(&self.0)) }
}
pub fn cur(&self) -> WriteStallCondition {
pub fn cur(&self) -> crocksdb_writestallcondition_t {
Copy link
Member

@Connor1996 Connor1996 Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All public functions/traits of src/xxx.rs should be unchanged, otherwise TiKV or other users may change code dramatically. Consider rename type crocksdb_writestallcondition_t to WriteStallCondition. Same for other enums like DBEntryType.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@fredchenbj
Copy link
Member Author

fredchenbj commented Dec 4, 2019

@fredchenbj awesome changes! Some general questions:

  1. Can you summarize what's changed in this PR? Seems mostly typing changes. Why are they needed?
  2. The PR seems not including the generated code. Should we checkin the generated code or not?
  3. What's the overall plan for migration?

Thanks.

@yiwu-arbug Thanks for your questions.

for 3, the migration plan has three steps: 1) use the old crocksdb's c.h and bindgen to generate ffi rust code, and make it work for all dependency code; 2) replace with rocksdb's c.h, and make all code in c.h conform to rocksdb's style, here we would only include rocksdb's c.h and not change it at all; 3) try to use rocksdb cpp api to generate ffi rust code. This pr is only step 1.

for 1, this pr has mainly three changes: 1) change crocksdb's c.h and c.cc to conform to bindgen's requirement; 2) use bindgen to generate ffi rust code; 3) change code in rust-rocksdb, including many type changes, to make those code could call the code geneated by bindgen.

for 2, the generated code is in target/debug/build/librocksdb_sys-f21a7cfdab79a481/out/bindings.rs, which is auto generated by cargo build. IMHO, we don't need checkin it.

@yiwu-arbug
Copy link
Collaborator

@fredchenbj for 3, can you give more details for step 1)? Does the generated code provide difference interface than the existing rust API? If so, how much work is it to update tikv? If that work is huge, is there way to split the work into small bits?

Also for 3, if we will trying generating code from c++ directly, how useful step 2) would be?

Currently the wrapper doesn't handle Status return from rocksdb well. It convert the struct to string and miss the typing. I hope with step 3) we can change it to convert to rust Result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants