From b83263bbe4fc24c6b3100904efa655717e24ee80 Mon Sep 17 00:00:00 2001 From: Jermy Li Date: Fri, 25 Mar 2022 10:24:58 -0700 Subject: [PATCH] jni: uniformly use GetByteArrayRegion() to copy bytes (#9380) Summary: Uniformly use GetByteArrayRegion() instead of GetByteArrayElements() to copy bytes. In addition, it can avoid an inefficient ReleaseByteArrayElements() operation. Some benefits of GetByteArrayRegion() can be referred to: https://stackoverflow.com/a/2480493 Pull Request resolved: https://github.com/facebook/rocksdb/pull/9380 Reviewed By: ajkr Differential Revision: D35135474 Pulled By: jay-zhuang fbshipit-source-id: a32c1774d37f2d22b9bcd105d83e0bb984b71b54 --- java/rocksjni/rocksjni.cc | 13 ++++++------- java/rocksjni/write_batch_with_index.cc | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/java/rocksjni/rocksjni.cc b/java/rocksjni/rocksjni.cc index a37b76d68..fca7074ed 100644 --- a/java/rocksjni/rocksjni.cc +++ b/java/rocksjni/rocksjni.cc @@ -829,9 +829,11 @@ bool rocksdb_single_delete_helper( const ROCKSDB_NAMESPACE::WriteOptions& write_options, ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle, jbyteArray jkey, jint jkey_len) { - jbyte* key = env->GetByteArrayElements(jkey, nullptr); - if (key == nullptr) { - // exception thrown: OutOfMemoryError + jbyte* key = new jbyte[jkey_len]; + env->GetByteArrayRegion(jkey, 0, jkey_len, key); + if (env->ExceptionCheck()) { + // exception thrown: ArrayIndexOutOfBoundsException + delete[] key; return false; } ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast(key), jkey_len); @@ -844,10 +846,7 @@ bool rocksdb_single_delete_helper( s = db->SingleDelete(write_options, key_slice); } - // trigger java unref on key and value. - // by passing JNI_ABORT, it will simply release the reference without - // copying the result back to the java byte array. - env->ReleaseByteArrayElements(jkey, key, JNI_ABORT); + delete[] key; if (s.ok()) { return true; diff --git a/java/rocksjni/write_batch_with_index.cc b/java/rocksjni/write_batch_with_index.cc index 615921b65..b02ddb672 100644 --- a/java/rocksjni/write_batch_with_index.cc +++ b/java/rocksjni/write_batch_with_index.cc @@ -735,9 +735,11 @@ void Java_org_rocksdb_WBWIRocksIterator_seek0(JNIEnv* env, jobject /*jobj*/, jlong handle, jbyteArray jtarget, jint jtarget_len) { auto* it = reinterpret_cast(handle); - jbyte* target = env->GetByteArrayElements(jtarget, nullptr); - if (target == nullptr) { - // exception thrown: OutOfMemoryError + jbyte* target = new jbyte[jtarget_len]; + env->GetByteArrayRegion(jtarget, 0, jtarget_len, target); + if (env->ExceptionCheck()) { + // exception thrown: ArrayIndexOutOfBoundsException + delete[] target; return; } @@ -746,7 +748,7 @@ void Java_org_rocksdb_WBWIRocksIterator_seek0(JNIEnv* env, jobject /*jobj*/, it->Seek(target_slice); - env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT); + delete[] target; } /* @@ -803,9 +805,11 @@ void Java_org_rocksdb_WBWIRocksIterator_seekForPrev0(JNIEnv* env, jbyteArray jtarget, jint jtarget_len) { auto* it = reinterpret_cast(handle); - jbyte* target = env->GetByteArrayElements(jtarget, nullptr); - if (target == nullptr) { - // exception thrown: OutOfMemoryError + jbyte* target = new jbyte[jtarget_len]; + env->GetByteArrayRegion(jtarget, 0, jtarget_len, target); + if (env->ExceptionCheck()) { + // exception thrown: ArrayIndexOutOfBoundsException + delete[] target; return; } @@ -814,7 +818,7 @@ void Java_org_rocksdb_WBWIRocksIterator_seekForPrev0(JNIEnv* env, it->SeekForPrev(target_slice); - env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT); + delete[] target; } /*