From 5fe97452dacbc5f1c12c1275e5d39e6c5e6293e0 Mon Sep 17 00:00:00 2001 From: Alan Paxton Date: Tue, 26 Sep 2023 14:13:45 +0100 Subject: [PATCH] =?UTF-8?q?Ah=20no,=20static=20doesn=E2=80=99t=20work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need the MultiGetKeys object to hold a vector of byte* which are part of the Slices, but need to be deallocated. That’s what RAII is for.. --- java/rocksjni/jni_get_helpers.cc | 31 +++++++++++++++++++++---------- java/rocksjni/jni_get_helpers.h | 11 +++++++++-- java/rocksjni/rocksjni.cc | 10 +++++----- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/java/rocksjni/jni_get_helpers.cc b/java/rocksjni/jni_get_helpers.cc index 9af299a41b21..9a642284934b 100644 --- a/java/rocksjni/jni_get_helpers.cc +++ b/java/rocksjni/jni_get_helpers.cc @@ -107,47 +107,58 @@ jint rocksjni_get_helper(JNIEnv* env, const ROCKSDB_NAMESPACE::FnGet& fn_get, return pinnable_value_len; } -std::unique_ptr> MultiGetKeys::fromByteArrays(JNIEnv* env, jobjectArray jkeys, jintArray jkey_offs, - jintArray jkey_lens) { +MultiGetKeys::~MultiGetKeys() { + for (auto key : key_bufs_to_free) { + delete[] key; + } + key_bufs_to_free.clear(); +} +bool MultiGetKeys::fromByteArrays(JNIEnv* env, jobjectArray jkeys, + jintArray jkey_offs, jintArray jkey_lens) { const jsize num_keys = env->GetArrayLength(jkeys); std::unique_ptr key_offs = std::make_unique(num_keys); env->GetIntArrayRegion(jkey_offs, 0, num_keys, key_offs.get()); if (env->ExceptionCheck()) { - return nullptr; // exception thrown: ArrayIndexOutOfBoundsException + return false; // exception thrown: ArrayIndexOutOfBoundsException } std::unique_ptr key_lens = std::make_unique(num_keys); env->GetIntArrayRegion(jkey_lens, 0, num_keys, key_lens.get()); if (env->ExceptionCheck()) { - return nullptr; // exception thrown: ArrayIndexOutOfBoundsException + return false; // exception thrown: ArrayIndexOutOfBoundsException } - auto slices = std::make_unique>(0); for (jsize i = 0; i < num_keys; i++) { jobject jkey = env->GetObjectArrayElement(jkeys, i); if (env->ExceptionCheck()) { // exception thrown: ArrayIndexOutOfBoundsException - return nullptr; + return false; } jbyteArray jkey_ba = reinterpret_cast(jkey); const jint len_key = key_lens[i]; jbyte* key = new jbyte[len_key]; + key_bufs_to_free.push_back(key); env->GetByteArrayRegion(jkey_ba, key_offs[i], len_key, key); if (env->ExceptionCheck()) { // exception thrown: ArrayIndexOutOfBoundsException - delete[] key; env->DeleteLocalRef(jkey); - return nullptr; + return false; } - slices->push_back( + slices.push_back( ROCKSDB_NAMESPACE::Slice(reinterpret_cast(key), len_key)); env->DeleteLocalRef(jkey); } - return slices; + return true; +} + +ROCKSDB_NAMESPACE::Slice* MultiGetKeys::data() { return slices.data(); } + +std::vector::size_type MultiGetKeys::size() { + return slices.size(); } template diff --git a/java/rocksjni/jni_get_helpers.h b/java/rocksjni/jni_get_helpers.h index a0107781ba13..75024fe42b7c 100644 --- a/java/rocksjni/jni_get_helpers.h +++ b/java/rocksjni/jni_get_helpers.h @@ -36,11 +36,18 @@ jint rocksjni_get_helper(JNIEnv* env, const ROCKSDB_NAMESPACE::FnGet& fn_get, * */ class MultiGetKeys { + private: + std::vector slices; + std::vector key_bufs_to_free; public: - static std::unique_ptr> fromByteArrays(JNIEnv* env, jobjectArray jkeys, jintArray jkey_offs, - jintArray jkey_lens); + ~MultiGetKeys(); + bool fromByteArrays(JNIEnv* env, jobjectArray jkeys, jintArray jkey_offs, + jintArray jkey_lens); + + ROCKSDB_NAMESPACE::Slice* data(); + std::vector::size_type size(); }; /** diff --git a/java/rocksjni/rocksjni.cc b/java/rocksjni/rocksjni.cc index ca82a5ff46c6..cbb822df23c3 100644 --- a/java/rocksjni/rocksjni.cc +++ b/java/rocksjni/rocksjni.cc @@ -1991,16 +1991,16 @@ void multi_get_helper_direct(JNIEnv* env, jobject, ROCKSDB_NAMESPACE::DB* db, jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I( JNIEnv* env, jobject, jlong jdb_handle, jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) { + ROCKSDB_NAMESPACE::MultiGetKeys keys; - auto keys = ROCKSDB_NAMESPACE::MultiGetKeys::fromByteArrays(env, jkeys, jkey_offs, jkey_lens); - if (!keys) { + if (!keys.fromByteArrays(env, jkeys, jkey_offs, jkey_lens)) { return nullptr; } - std::vector values(keys->size()); - std::vector statuses(keys->size()); + std::vector values(keys.size()); + std::vector statuses(keys.size()); auto* db = reinterpret_cast(jdb_handle); db->MultiGet(ROCKSDB_NAMESPACE::ReadOptions(), db->DefaultColumnFamily(), - keys->size(), keys->data(), values.data(), statuses.data(), + keys.size(), keys.data(), values.data(), statuses.data(), false /* sorted_input*/); return ROCKSDB_NAMESPACE::MultiGetValues::byteArrays(env, values, statuses); }