-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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 support for Wide columns in Java #12334
base: main
Are you sure you want to change the base?
Conversation
33d9052
to
a0a634e
Compare
47a2294
to
31e973b
Compare
31e973b
to
6b75fb2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have done a partial review... There are three main things that you might want to look at IMHO:
-
Whether you really need
std::make_unique
for a pointer that never escapes its function scope. It seems superfluous to me. -
Clean up of JNI resources you have allocated before you return from a function when an error condition occurs (or even when the function completes normally)
-
String conversion from JNI types to C++ standard types. There are functions in
portal.h
to assist in doing this correctly. If they don't suit, we can consider adding an additional one for your use-case.
"ByteBuffer)"); | ||
return; | ||
} | ||
auto name = reinterpret_cast<char*>(_name) + namesOffset[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are utility methods in portal.h to go from jstring
to std::string
or char*
- could we use those here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not working with jstring
but with void*
here. I cast it to char*
so that I can add offset to it.
|
||
const auto columns_len = static_cast<int>(env->GetArrayLength(jNames)); | ||
|
||
auto namesOffset = std::make_unique<jint[]>(columns_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make_unique seems an unnecessary overhead here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's true, but it allows me to automatically release all the memory allocated here and simplify return statements.
auto j_value = | ||
static_cast<jbyteArray>(env->GetObjectArrayElement(jvalues, i)); | ||
if (env->ExceptionCheck()) { | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to free the JNI local references for name/jname here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we don't need to. doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it, GetObjectArrayElement
returns a jobject
and when you are finished with this (on either success or error paths), you should call DeleteLocalRef
on that object. There are other examples of this pattern already in the existing code-base, for example: https://github.com/facebook/rocksdb/blob/main/java/rocksjni/rocksjni.cc#L462
auto value = std::make_unique<jbyte[]>(jvalue_len); | ||
env->GetByteArrayRegion(j_value, 0, jvalue_len, value.get()); | ||
if (env->ExceptionCheck()) { | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to free the JNI local references for name/jname and value/jvalue here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we don't need to. GetByteArrayRegion
only copies data from java arrays to provide memory. This memory is allocated as a smart pointer and is automatically released when we exit the method.
auto value = reinterpret_cast<char*>(_value) + valuesOffset[i]; | ||
valuesRequiredSize[i] = static_cast<jint>(column.value().size()); | ||
max_data_len = std::min(valuesRequiredSize[i], (valuesLen[i])); | ||
std::memcpy(value, column.value().data(), max_data_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is explicit memcpy needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, See previous comment
env->SetIntArrayRegion(jnamesRequiredSize, 0, max_items, | ||
namesRequiredSize.get()); | ||
if (env->ExceptionCheck()) { | ||
return nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to free the previous JNI array fetches and local-references here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we don't need to. See previous comment
env->SetIntArrayRegion(jvaluesRequiredSize, 0, max_items, | ||
valuesRequiredSize.get()); | ||
if (env->ExceptionCheck()) { | ||
return nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to free the previous JNI array fetches and local-references here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we don't need to. See previous comment
java/rocksjni/rocksjni.cc
Outdated
"Invalid key argument (argument is not a valid direct ByteBuffer)"); | ||
return nullptr; | ||
} | ||
auto key = reinterpret_cast<char*>(_key) + key_offset; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this use portal.h for string conversion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. See previous comment
jlong jcf_handle) { | ||
auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle); | ||
|
||
auto key = std::make_unique<jbyte[]>(keyLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::make_unique seems superfluous here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, See previous comment
239f9df
to
a9f7753
Compare
a9f7753
to
aa1fd9a
Compare
Hello, after I finished compiling, the run encountered the following error: |
Hello @test-wangxiaoyu
This is a very strange error. Considering you have a macbook air 2022, these models have ARM CPU ( You can also check what native library is inside the jar archive. For example this is how it looks like on my linux machine. $ jar -t --file java/target/rocksdbjni-9.2.0-linux64.jar | grep librocksdbjni
librocksdbjni-linux64.so Radek |
aa1fd9a
to
55716e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@pdillinger @ajkr Can we get this one merged please? |
3a7a3ae
to
a427a7f
Compare
Hi, Thank you for the great work on this feature! I am very interested in using wide columns in RocksDB. Could you please let me know if this feature is planned to be merged? Also, do you have an estimated timeline for when it might be available in a release? Thank you! |
a427a7f
to
1c944f2
Compare
1c944f2
to
e1d45d1
Compare
This PR adds support for wide columns in Java. First implementation is primarily focused on correctness rather than performance. We would like to merge this first and hear feedback from RocksDB Java community before refining it.
Fix #12113