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

Add jni Support for API CreateColumnFamilyWithImport #11646

Closed
wants to merge 9 commits into from

Conversation

mayuehappy
Copy link
Contributor

@mayuehappy mayuehappy commented Jul 27, 2023

  • Add the following missing options to src/main/java/org/rocksdb/ImportColumnFamilyOptions.java and in java/rocksjni/import_column_family_options.cc in RocksJava.
  • Add the struct to src/main/java/org/rocksdb/ExportImportFilesMetaData.java and in java/rocksjni/export_import_files_metadatajni.cc in RocksJava.
  • Add New Java API createColumnFamilyWithImport to src/main/java/org/rocksdb/RocksDB.java
  • Add New Java API exportColumnFamily to src/main/java/org/rocksdb/Checkpoint.java

Test plan:

  • added unit tests for exportColumnFamily in org.rocksdb.CheckpointTest
  • added unit tests for createColumnFamilyWithImport to org.rocksdb.ImportColumnFamilyTest

Copy link
Collaborator

@adamretter adamretter left a comment

Choose a reason for hiding this comment

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

This looks like a great start, thanks for your contribution :-)
I just have a few questions around object ownership please

/**
* Called from JNI C++
*/
public ExportImportFilesMetaData(final byte[] dbComparatorName, final LiveFileMetaData[] files) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is only called from JNI, it can be made private please

return Arrays.asList(files);
}

public long newExportImportFilesMetaDataHandle() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this should be in this class. I see it is called from RocksDB. I think it would be better if the processing was done in RocksDB as the native handles are not used here.

final List<ExportImportFilesMetaData> metadatas) throws RocksDBException {
final int metadataNum = metadatas.size();
final long[] metadataHandeList = new long[metadataNum];
for (int i = 0; i < metadataNum; i++) {
Copy link
Collaborator

@adamretter adamretter Jul 28, 2023

Choose a reason for hiding this comment

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

I am a bit confused between the relationship you have chosen between the Java class org.rocksdb.ExportImportFilesMetaData and the C++ class ROCKSDB_NAMESPACE::ExportImportFilesMetaData.

Normally where there is a Java class that may need to have ownership of a C++ object, we typically follow the pattern of inheriting from RocksObject where possible, or if you need references to C++ objects which should not be owned by the Java Object then you may extend AbstractImmutableNativeReference.

I am wondering if there is a reason why you have chosen not to follow that pattern? It is important in RocksJava that we understand the ownership model so that we don't leak memory by not deleting C++ objects that we own, and/or causing crashes by deleting C++ objects that we don't own.

Copy link
Contributor Author

@mayuehappy mayuehappy Jul 30, 2023

Choose a reason for hiding this comment

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

@adamretter

Thank you very much for Review code, it is my honor to contribute code.

I‘v read your comment. Before I modify the code I would like to ask a question, PTAL

ExportImportFilesMetaData may be used in two places. One situation is that we can create ExportImportFilesMetaData through Checkpoint.exportColumnFamily, from here it seems that org.rocksdb.ExportImportFilesMetaData and org.rocksdb.LiveFileMetaData are similar, Called from JNI C++, so i did not to follow that pattern.
But in another case, ExportImportFilesMetaData needs to be passed in when calling createColumnFamilyWithImport. In this case we need to follow the pattern of inheriting from RocksObject.
So if this is the case, do LiveFileMetaData and SstFileMetaData also need to follow this pattern?

Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. So in C++ when you call Checkpoint::ExportColumnFamily the caller will be the owner of the new ExportImportFilesMetaData object that is created and returned. So if you are calling this from Java, then the Java caller is now the owner of this, and is responsible for freeing it - for this something like RocksObject in Java is perfect.

  2. In C++ when you call DB::CreateColumnFamilyWithImport as the caller you have to provide an ExportImportFilesMetaData object. As you are in C++ you may choose to create this object either on the stack or on the heap. From Java though if you want to have a Java object which represents this C++ object, then you will need to call JNI and create the object on the heap, at which point you are the owner of that object, and so therefore again RocksObject in Java again becomes the correct choice.

@mayuehappy Is that helpful?

@mayuehappy
Copy link
Contributor Author

@adamretter @cbi42 Ping~ , Can anyone help me look at this PR?

@adamretter
Copy link
Collaborator

@mayuehappy I just replied to your comment above - let me know if you need any more guidance...

@mayuehappy
Copy link
Contributor Author

@adamretter
Thanks for the guidance, I've updated the PR. Change ExportImportFilesMetaData to extends RocksObject, please help and take a look

private ExportImportFilesMetaData(final long nativeHandle) {
super(nativeHandle);
// We do not own the native object!
disOwnNativeHandle();
Copy link
Collaborator

Choose a reason for hiding this comment

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

@mayuehappy can you explain why you are callng disOwnNativeHandle here please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@adamretter Thanks for the reviewing, I thought about this place again. org.rocksdb.ExportImportFilesMetaData should indeed own ROCKSDB_NAMESPACE::ExportImportFilesMetaData's nativeHandle. My initial idea was a little wrong, so I deleted these two lines of code.

@pnowojski
Copy link

Hi @mayuehappy and @adamretter. Thank you both for your efforts so far on this and other related PRs! I'm eagerly waiting for this feature to be merged. Is there something that I could do to help pushing this PR over the line? If there are still some issues to be resolved, me or my colleagues would be happy to help.

@mayuehappy
Copy link
Contributor Author

Hi @mayuehappy and @adamretter. Thank you both for your efforts so far on this and other related PRs! I'm eagerly waiting for this feature to be merged. Is there something that I could do to help pushing this PR over the line? If there are still some issues to be resolved, me or my colleagues would be happy to help.

@pnowojski Hi ~ Thank you for your attention. I alse hope this PR can be merged soon so that Flink can use this new feature to speed up state recovery!

@adamretter .If there is anything that needs to be modified in this PR, please comment and I will fix it as soon as possible.
cc @cbi42

@adamretter
Copy link
Collaborator

@mayuehappy I think this looks good. I would like my colleague @alanpaxton to also give it a quick once over too. @alanpaxton could you just check the "ownership" semantics as discussed above, I am pretty certain we have them correct now - but a second pair of eyes is always valuable.

Copy link
Contributor

@alanpaxton alanpaxton left a comment

Choose a reason for hiding this comment

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

@adamretter @mayuehappy I have looked at this w.r.t. "ownership" semantics, and it appears correct to me for that. I noticed a couple of small issues in passing that I commented..

final ImportColumnFamilyOptions importColumnFamilyOptions,
final List<ExportImportFilesMetaData> metadatas) throws RocksDBException {
final int metadataNum = metadatas.size();
final long[] metadataHandeList = new long[metadataNum];
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo - metadataHandleList

/**
* ImportColumnFamilyOptions is used by ImportColumnFamily()
* <p>
* Note that dispose() must be called before this instance become out-of-scope
Copy link
Contributor

Choose a reason for hiding this comment

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

This behaves the same as any other RocksObject. If you need a specific comment, it should note that the should be close()d (since close is the public method which ultimately calls disposeInternal()), and ideally that should use a try-with-resources construct.

if (metadata != nullptr) {
jexport_import_files_meta_data =
ROCKSDB_NAMESPACE::ExportImportFilesMetaDataJni::
fromCppExportImportFilesMetaData(env, metadata);
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it not be easier to return metadata as a jlong (GET_CPLUS_PLUS_PTR) and then call new ExportImportFilesMetaData(metadata_native_) in Java ? Then you would not need to add the extra class to portal.h, I believe ?

@facebook-github-bot
Copy link
Contributor

@cbi42 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@cbi42
Copy link
Member

cbi42 commented Nov 1, 2023

LGTM, I'll merge it once the other comments are addressed.

@facebook-github-bot
Copy link
Contributor

@mayuehappy has updated the pull request. You must reimport the pull request before landing.

@mayuehappy
Copy link
Contributor Author

@cbi42 @adamretter @alanpaxton
Thanks a lot for reviewing the code, I've updated the PR as suggested by @alanpaxton . Mainly include the following changes:

  1. fix metadataHandeList typo issues
  2. Updated ImportColumnFamilyOptions class comment. And use try-with-resources in unit tests to create ImportColumnFamilyOptions
  3. change Java_org_rocksdb_Checkpoint_exportColumnFamily returns types to jlong, then call new ExportImportFilesMetaData(metadata_native_) to create ExportImportFilesMetaData and delete portal.h related changes

@facebook-github-bot
Copy link
Contributor

@mayuehappy has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mayuehappy has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@cbi42 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mayuehappy has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@mayuehappy has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@cbi42 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@cbi42 merged this pull request in 19768a9.

fredia pushed a commit to fredia/frocksdb that referenced this pull request Nov 16, 2023
Summary:
- Add the following missing options to src/main/java/org/rocksdb/ImportColumnFamilyOptions.java and in java/rocksjni/import_column_family_options.cc in RocksJava.
- Add the struct to src/main/java/org/rocksdb/ExportImportFilesMetaData.java and in java/rocksjni/export_import_files_metadatajni.cc in RocksJava.
- Add New Java API `createColumnFamilyWithImport` to src/main/java/org/rocksdb/RocksDB.java
- Add New Java API `exportColumnFamily` to src/main/java/org/rocksdb/Checkpoint.java

Pull Request resolved: facebook/rocksdb#11646

Test Plan:
- added unit tests for exportColumnFamily in org.rocksdb.CheckpointTest
- added unit tests for createColumnFamilyWithImport to org.rocksdb.ImportColumnFamilyTest

Reviewed By: ajkr

Differential Revision: D50889700

Pulled By: cbi42

fbshipit-source-id: d623b35e445bba62a0d3c007d74352e937678f6c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants