[JNI] Avoid a potential byte-array-copy btw c++ and java in RocksDB.get(byte[], byte[]).

Summary: Avoid a JNI call to GetByteArrayElements, which may introduce a byte-array-copy.

Test Plan: make jtest

Reviewers: haobo, sdong, dhruba

CC: leveldb

Differential Revision: https://reviews.facebook.net/D17451
This commit is contained in:
Yueh-Hsuan Chiang 2014-04-02 23:54:50 -07:00
parent 92d2766001
commit e3511841fa

View File

@ -178,9 +178,7 @@ jint Java_org_rocksdb_RocksDB_get__J_3BI_3BI(
static const int kStatusError = -2; static const int kStatusError = -2;
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle); auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
jboolean isCopy; jbyte* key = env->GetByteArrayElements(jkey, 0);
jbyte* key = env->GetByteArrayElements(jkey, &isCopy);
jbyte* value = env->GetByteArrayElements(jvalue, &isCopy);
rocksdb::Slice key_slice( rocksdb::Slice key_slice(
reinterpret_cast<char*>(key), jkey_len); reinterpret_cast<char*>(key), jkey_len);
@ -196,10 +194,8 @@ jint Java_org_rocksdb_RocksDB_get__J_3BI_3BI(
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT); env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
if (s.IsNotFound()) { if (s.IsNotFound()) {
env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
return kNotFound; return kNotFound;
} else if (!s.ok()) { } else if (!s.ok()) {
env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
// Here since we are throwing a Java exception from c++ side. // Here since we are throwing a Java exception from c++ side.
// As a result, c++ does not know calling this function will in fact // As a result, c++ does not know calling this function will in fact
// throwing an exception. As a result, the execution flow will // throwing an exception. As a result, the execution flow will
@ -215,9 +211,10 @@ jint Java_org_rocksdb_RocksDB_get__J_3BI_3BI(
int cvalue_len = static_cast<int>(cvalue.size()); int cvalue_len = static_cast<int>(cvalue.size());
int length = std::min(jvalue_len, cvalue_len); int length = std::min(jvalue_len, cvalue_len);
memcpy(value, cvalue.c_str(), length); env->SetByteArrayRegion(
env->ReleaseByteArrayElements(jvalue, value, JNI_COMMIT); jvalue, 0, length,
return static_cast<jint>(cvalue_len); reinterpret_cast<const jbyte*>(cvalue.c_str()));
return cvalue_len;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////