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

Updated rocksdb submodule to v4.11.2. #2

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

Conversation

alexreg
Copy link

@alexreg alexreg commented Oct 25, 2016

Fixed memory leakage bug in tests/c_test.rs

//! Raw binding for RocksDB.
//!
//! This is just a thin binding to the RocksDB C API, mostly generated
//! by rust-bindgen and lightly edited. This is intended to underpin a
Copy link
Owner

Choose a reason for hiding this comment

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

Did you regenerate this with bindgen or some other tool, or manually edit it?

Copy link
Author

Choose a reason for hiding this comment

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

I regenerated it, then manually edited. Sorry, might have lost a few custom changes! Feel free to point them out.

Copy link
Owner

Choose a reason for hiding this comment

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

My concern is larger than that.

Thus far, I've been incrementally updating this file to reflect changes in the RocksDB c.h API, so that changes to this files are more or less 1:1 with changes in c.h.

Your set of changes represent a total rewrite. I'm not sure:

  • which changes are the result of a different generator
  • which changes are bugfixes
  • which changes are aesthetic/formatting fixes
  • which changes are platform porting fixes
  • which changes are RocksDB API changes

It's good that you've started to break it down into separate commits, but it's still far from "one concern per commit".

And as a result, I'm not sure how to maintain this in future. Can I just regenerate it mechanically? If I did, what things would I need to port into the newly generated version to maintain compatibility?

You're also changing the API presented by this crate, which is something that other crates depend on, so you're going to cause downstream breakage. If you're going to do that, there needs to be a good/convincing reason for it.

I would prefer to see:

  • the minimal set of changes needed to update to the new RocksDB
  • the minimal set of changes needed to get it working on Mac OS
  • the minimal set of changes needed to fix the test bugs
  • anything else

as separate commits which we can review individually.

.arg(format!("INSTALL_PATH={}", out_dir));

if let Ok(jobs) = num_jobs {
cmd.arg(format!("-j{}", jobs));
}

cmd.arg("install-static");
cmd.arg("install");
Copy link
Owner

Choose a reason for hiding this comment

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

By default, rocksdb was using its own allocator (tcmalloc), which conflicted with jemalloc used by Rust. The only way I could resolve it was by statically linking rocksdb into the crate so that it uses the Rust allocator.

Also I prefer static linking to avoid more dependencies for the executable. The c<->rust binding is pretty fragile, and I'm sure that the RocksDB ABI doesn't change from version to version, so independently updating rocksdb from the Rust code using it seems risky.

Copy link
Author

Choose a reason for hiding this comment

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

Ah. The problem with static linking is that there is no static libstdc++ on OS X...

Copy link
Owner

Choose a reason for hiding this comment

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

Well, can you statically link rocksdb and dynamically link libstdc++? I think that's what happens on Linux.

Copy link
Author

Choose a reason for hiding this comment

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

I'm afraid you can't dynamically link to a library from a static library. Unless you do it at run-time (rather than load-time), using dlopen or something. This is definitely a problem, although I see why you wanted to avoid bringing two different allocators into play.

Copy link
Owner

Choose a reason for hiding this comment

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

I'm afraid you can't dynamically link to a library from a static library.

Sure, but that's not quite what I'm talking about.

RocksDB is written in C++, so it has a dependency on libstdc++, but the library itself (the .rlib) doesn't have a direct dependency on it - it just needs to make sure when your executable is finally linked it includes a linkage to libstdc++. And because the rest of RocksDB is static, it effectively becomes part of your main executable.

I believe that rustc uses clang++ as its linker on Mac OS, so the requirement for libstdc++ will be automatically fulfilled.

Have you tried this and had it fail? If so, how did it fail?

Copy link
Author

Choose a reason for hiding this comment

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

I've been told rustc uses ld as the linker, in fact, but not 100% sure. Anyway, I got lots of "undefined symbol" errors if I tried to link it statically.

Copy link
Owner

@jsgf jsgf left a comment

Choose a reason for hiding this comment

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

Why? In principle they could be NULL pointers - or did you only remove the option on the functions which must be supplied?

@alexreg
Copy link
Author

alexreg commented Oct 26, 2016

I believe all the functions must be supplied, but I'll double check that.

Copy link
Owner

@jsgf jsgf left a comment

Choose a reason for hiding this comment

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

I think it's better these exactly match the rocksdb headers. These shouldn't ever be visible to application code (ie, some nice wrapper should re-present this API in a cleaner form).

@alexreg
Copy link
Author

alexreg commented Oct 26, 2016

I’ve been told that’s not possible, but will have a look into it…

On 26 Oct 2016, at 17:14, Jeremy Fitzhardinge [email protected] wrote:

@jsgf commented on this pull request.

In build.rs #2:

     .arg(format!("INSTALL_PATH={}", out_dir));
 if let Ok(jobs) = num_jobs {
     cmd.arg(format!("-j{}", jobs));
 }
  • cmd.arg("install-static");
  • cmd.arg("install");
    Well, can you statically link rocksdb and dynamically link libstdc++? I think that's what happens on Linux.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub #2, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEF3KEXnqd5jWDBpOfqgrOC0SgTjTZXks5q33xbgaJpZM4KgmM9.

@alexreg
Copy link
Author

alexreg commented Oct 26, 2016

What bit of code were you referring to with your last comment? (I think you just submitted it as a regular comment.)

@alexreg
Copy link
Author

alexreg commented Oct 27, 2016

Hmm. I force-pushed a modified commit, and that seems to have made Travis unhappy, even though all the tests should be succeeding now. Sorry about that.

@@ -1,8 +1,3 @@
/*
Copyright (c) 2011 The LevelDB Authors. All rights reserved.
Copy link
Owner

Choose a reason for hiding this comment

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

Don't strip off copyright headers.

Copy link
Author

Choose a reason for hiding this comment

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

This was probably something accidental. Easy enough to put back. (I guess you ported the C test code directly?)

pub const rocksdb_block_based_table_index_type_binary_search: c_uint = 0;
pub const rocksdb_block_based_table_index_type_hash_search: c_uint = 1;

pub const rocksdb_no_compression: c_uint = 0;
Copy link
Owner

Choose a reason for hiding this comment

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

Leave all these as they are, to exactly match the C headers. You can wrap them up as Rust enums in the higher-level API.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, I reverted to the constants after all. I'm not sure you can say they exactly match the C headers, since the C header defines a nameless enum, but there you go! The semantics are similar.

Copy link
Author

Choose a reason for hiding this comment

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

As for the API changes, I see what you mean. What I did is regenerate the bindings using bindgen, to make things easier, then edit by hand. As far as I could tell your bindings were missing a lot of functions that are (now) in RocksDB... maybe we could just take a look at where the API clashes with your old definitions? The types should now all agree, at least.

//! Raw binding for RocksDB.
//!
//! This is just a thin binding to the RocksDB C API, mostly generated
//! by rust-bindgen and lightly edited. This is intended to underpin a
Copy link
Owner

Choose a reason for hiding this comment

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

My concern is larger than that.

Thus far, I've been incrementally updating this file to reflect changes in the RocksDB c.h API, so that changes to this files are more or less 1:1 with changes in c.h.

Your set of changes represent a total rewrite. I'm not sure:

  • which changes are the result of a different generator
  • which changes are bugfixes
  • which changes are aesthetic/formatting fixes
  • which changes are platform porting fixes
  • which changes are RocksDB API changes

It's good that you've started to break it down into separate commits, but it's still far from "one concern per commit".

And as a result, I'm not sure how to maintain this in future. Can I just regenerate it mechanically? If I did, what things would I need to port into the newly generated version to maintain compatibility?

You're also changing the API presented by this crate, which is something that other crates depend on, so you're going to cause downstream breakage. If you're going to do that, there needs to be a good/convincing reason for it.

I would prefer to see:

  • the minimal set of changes needed to update to the new RocksDB
  • the minimal set of changes needed to get it working on Mac OS
  • the minimal set of changes needed to fix the test bugs
  • anything else

as separate commits which we can review individually.

@jsgf
Copy link
Owner

jsgf commented Oct 28, 2016

I just pushed a "rocksdb-4.11.2" branch with a minimal set of changes to support the changes in c.h. I haven't tested it yet, so I'd appreciate it if you could double-check my changes.

"cargo test" also works on my Mac (Mac OS 10.11.6), which just needed the JEMALLOC change in build.rs.

@jsgf
Copy link
Owner

jsgf commented Oct 28, 2016

Ah, that was xcode 7.something. Xcode 8 fails.

@alexreg
Copy link
Author

alexreg commented Oct 29, 2016

@jsgf Okay, so I tried this on a new machine in fact, and initially got some errors when running cargo test.

dyld: Library not loaded: /usr/local/opt/lz4/lib/liblz4.1.dylib
  Referenced from: /Users/alex/Software/rocksdb-sys/target/debug/build/rocksdb-sys-979ce3bc9a6df222/out/lib/librocksdb.4.11.dylib
  Reason: image not found

Also got similar errors for snappy, lz, jemalloc. When I installed them all, the build worked. This is on OS X 10.11 however, not 10.12. What error did you get with Xcode 8 tools?

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.

2 participants