|
|
|
@ -10,6 +10,7 @@ |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <jni.h> |
|
|
|
|
#include <string> |
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
#include "include/org_rocksdb_RocksDB.h" |
|
|
|
|
#include "rocksjni/portal.h" |
|
|
|
@ -244,6 +245,91 @@ jint rocksdb_get_helper( |
|
|
|
|
return cvalue_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db, |
|
|
|
|
const rocksdb::ReadOptions& rOpt, jobject jkey_list, jint jkeys_count) { |
|
|
|
|
std::vector<rocksdb::Slice> keys; |
|
|
|
|
std::vector<jbyte*> keys_to_free; |
|
|
|
|
|
|
|
|
|
// get iterator
|
|
|
|
|
jobject iteratorObj = env->CallObjectMethod( |
|
|
|
|
jkey_list, rocksdb::ListJni::getIteratorMethod(env)); |
|
|
|
|
|
|
|
|
|
// iterate over keys and convert java byte array to slice
|
|
|
|
|
while(env->CallBooleanMethod( |
|
|
|
|
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { |
|
|
|
|
jbyteArray jkey = (jbyteArray) env->CallObjectMethod( |
|
|
|
|
iteratorObj, rocksdb::ListJni::getNextMethod(env)); |
|
|
|
|
jint key_length = env->GetArrayLength(jkey); |
|
|
|
|
|
|
|
|
|
jbyte* key = new jbyte[key_length]; |
|
|
|
|
env->GetByteArrayRegion(jkey, 0, key_length, key); |
|
|
|
|
// store allocated jbyte to free it after multiGet call
|
|
|
|
|
keys_to_free.push_back(key);
|
|
|
|
|
|
|
|
|
|
rocksdb::Slice key_slice( |
|
|
|
|
reinterpret_cast<char*>(key), key_length); |
|
|
|
|
keys.push_back(key_slice); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::vector<std::string> values; |
|
|
|
|
std::vector<rocksdb::Status> s = db->MultiGet(rOpt, keys, &values); |
|
|
|
|
|
|
|
|
|
// Don't reuse class pointer
|
|
|
|
|
jclass jclazz = env->FindClass("java/util/ArrayList");
|
|
|
|
|
jmethodID mid = rocksdb::ListJni::getArrayListConstructorMethodId( |
|
|
|
|
env, jclazz);
|
|
|
|
|
jobject jvalue_list = env->NewObject(jclazz, mid, jkeys_count); |
|
|
|
|
|
|
|
|
|
// insert in java list
|
|
|
|
|
for(std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) { |
|
|
|
|
if(s[i].ok()) { |
|
|
|
|
jbyteArray jvalue = env->NewByteArray(values[i].size()); |
|
|
|
|
env->SetByteArrayRegion( |
|
|
|
|
jvalue, 0, values[i].size(), |
|
|
|
|
reinterpret_cast<const jbyte*>(values[i].c_str())); |
|
|
|
|
env->CallBooleanMethod( |
|
|
|
|
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), jvalue); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
env->CallBooleanMethod( |
|
|
|
|
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), nullptr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// free up allocated byte arrays
|
|
|
|
|
for(std::vector<jbyte*>::size_type i = 0; i != keys_to_free.size(); i++) { |
|
|
|
|
delete[] keys_to_free[i]; |
|
|
|
|
} |
|
|
|
|
keys_to_free.clear(); |
|
|
|
|
|
|
|
|
|
return jvalue_list; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: org_rocksdb_RocksDB |
|
|
|
|
* Method: multiGet |
|
|
|
|
* Signature: (JLjava/util/List;I)Ljava/util/List; |
|
|
|
|
*/ |
|
|
|
|
jobject Java_org_rocksdb_RocksDB_multiGet( |
|
|
|
|
JNIEnv* env, jobject jdb, jlong jdb_handle, |
|
|
|
|
jobject jkey_list, jint jkeys_count) { |
|
|
|
|
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), |
|
|
|
|
rocksdb::ReadOptions(), jkey_list, jkeys_count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: org_rocksdb_RocksDB |
|
|
|
|
* Method: multiGet |
|
|
|
|
* Signature: (JJLjava/util/List;I)Ljava/util/List; |
|
|
|
|
*/ |
|
|
|
|
jobject Java_org_rocksdb_RocksDB_multiGet( |
|
|
|
|
JNIEnv* env, jobject jdb, jlong jdb_handle, |
|
|
|
|
jlong jropt_handle, jobject jkey_list, jint jkeys_count) { |
|
|
|
|
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), |
|
|
|
|
*reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkey_list, |
|
|
|
|
jkeys_count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: org_rocksdb_RocksDB |
|
|
|
|
* Method: get |
|
|
|
|