2016-02-10 00:12:00 +01:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-16 01:03:42 +02:00
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
2014-11-17 19:22:44 +01:00
|
|
|
//
|
|
|
|
// This file implements the "bridge" between Java and C++ and enables
|
|
|
|
// calling c++ rocksdb::TtlDB methods.
|
|
|
|
// from Java side.
|
|
|
|
|
2015-01-13 22:56:37 +01:00
|
|
|
#include <jni.h>
|
2014-11-17 19:22:44 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2018-04-13 02:55:14 +02:00
|
|
|
#include <memory>
|
2014-11-17 19:22:44 +01:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "include/org_rocksdb_TtlDB.h"
|
|
|
|
#include "rocksdb/utilities/db_ttl.h"
|
2015-01-13 22:56:37 +01:00
|
|
|
#include "rocksjni/portal.h"
|
2014-11-17 19:22:44 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_rocksdb_TtlDB
|
|
|
|
* Method: open
|
2016-01-20 18:05:41 +01:00
|
|
|
* Signature: (JLjava/lang/String;IZ)J
|
2014-11-17 19:22:44 +01:00
|
|
|
*/
|
2019-02-22 23:36:38 +01:00
|
|
|
jlong Java_org_rocksdb_TtlDB_open(
|
|
|
|
JNIEnv* env, jclass, jlong joptions_handle, jstring jdb_path, jint jttl,
|
|
|
|
jboolean jread_only) {
|
2017-02-28 01:26:12 +01:00
|
|
|
const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
|
2018-04-13 02:55:14 +02:00
|
|
|
if (db_path == nullptr) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: OutOfMemoryError
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-01-19 22:19:58 +01:00
|
|
|
auto* opt = reinterpret_cast<rocksdb::Options*>(joptions_handle);
|
2014-11-17 19:22:44 +01:00
|
|
|
rocksdb::DBWithTTL* db = nullptr;
|
2018-04-13 02:55:14 +02:00
|
|
|
rocksdb::Status s =
|
|
|
|
rocksdb::DBWithTTL::Open(*opt, db_path, &db, jttl, jread_only);
|
2014-11-17 19:22:44 +01:00
|
|
|
env->ReleaseStringUTFChars(jdb_path, db_path);
|
|
|
|
|
|
|
|
// as TTLDB extends RocksDB on the java side, we can reuse
|
|
|
|
// the RocksDB portal here.
|
|
|
|
if (s.ok()) {
|
2016-01-20 18:05:41 +01:00
|
|
|
return reinterpret_cast<jlong>(db);
|
|
|
|
} else {
|
|
|
|
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
|
|
|
return 0;
|
2014-11-17 19:22:44 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-21 23:38:17 +01:00
|
|
|
|
2015-01-13 22:56:37 +01:00
|
|
|
/*
|
|
|
|
* Class: org_rocksdb_TtlDB
|
2015-01-17 23:28:54 +01:00
|
|
|
* Method: openCF
|
2016-01-20 18:05:41 +01:00
|
|
|
* Signature: (JLjava/lang/String;[[B[J[IZ)[J
|
2015-01-13 22:56:37 +01:00
|
|
|
*/
|
2019-02-22 23:36:38 +01:00
|
|
|
jlongArray Java_org_rocksdb_TtlDB_openCF(
|
|
|
|
JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
|
|
|
|
jobjectArray jcolumn_names, jlongArray jcolumn_options,
|
|
|
|
jintArray jttls, jboolean jread_only) {
|
2017-02-28 01:26:12 +01:00
|
|
|
const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
|
2018-04-13 02:55:14 +02:00
|
|
|
if (db_path == nullptr) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: OutOfMemoryError
|
|
|
|
return 0;
|
|
|
|
}
|
2016-01-20 18:05:41 +01:00
|
|
|
|
2017-02-28 01:26:12 +01:00
|
|
|
const jsize len_cols = env->GetArrayLength(jcolumn_names);
|
|
|
|
jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr);
|
2018-04-13 02:55:14 +02:00
|
|
|
if (jco == nullptr) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: OutOfMemoryError
|
|
|
|
env->ReleaseStringUTFChars(jdb_path, db_path);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-01-20 18:05:41 +01:00
|
|
|
|
2017-02-28 01:26:12 +01:00
|
|
|
std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
|
|
|
|
jboolean has_exception = JNI_FALSE;
|
|
|
|
rocksdb::JniUtil::byteStrings<std::string>(
|
2018-04-13 02:55:14 +02:00
|
|
|
env, jcolumn_names,
|
|
|
|
[](const char* str_data, const size_t str_len) {
|
|
|
|
return std::string(str_data, str_len);
|
|
|
|
},
|
|
|
|
[&jco, &column_families](size_t idx, std::string cf_name) {
|
|
|
|
rocksdb::ColumnFamilyOptions* cf_options =
|
|
|
|
reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[idx]);
|
|
|
|
column_families.push_back(
|
|
|
|
rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
|
|
|
|
},
|
|
|
|
&has_exception);
|
2016-01-20 18:05:41 +01:00
|
|
|
|
|
|
|
env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
|
|
|
|
|
2018-04-13 02:55:14 +02:00
|
|
|
if (has_exception == JNI_TRUE) {
|
2017-06-05 20:23:31 +02:00
|
|
|
// exception occurred
|
2017-02-28 01:26:12 +01:00
|
|
|
env->ReleaseStringUTFChars(jdb_path, db_path);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-01-20 18:05:41 +01:00
|
|
|
|
|
|
|
std::vector<int32_t> ttl_values;
|
2017-02-28 01:26:12 +01:00
|
|
|
jint* jttlv = env->GetIntArrayElements(jttls, nullptr);
|
2018-04-13 02:55:14 +02:00
|
|
|
if (jttlv == nullptr) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: OutOfMemoryError
|
|
|
|
env->ReleaseStringUTFChars(jdb_path, db_path);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
const jsize len_ttls = env->GetArrayLength(jttls);
|
2018-04-13 02:55:14 +02:00
|
|
|
for (jsize i = 0; i < len_ttls; i++) {
|
2016-01-20 18:05:41 +01:00
|
|
|
ttl_values.push_back(jttlv[i]);
|
2015-01-13 22:56:37 +01:00
|
|
|
}
|
2016-01-20 18:05:41 +01:00
|
|
|
env->ReleaseIntArrayElements(jttls, jttlv, JNI_ABORT);
|
|
|
|
|
2017-02-28 01:26:12 +01:00
|
|
|
auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
|
|
|
|
std::vector<rocksdb::ColumnFamilyHandle*> handles;
|
|
|
|
rocksdb::DBWithTTL* db = nullptr;
|
2018-04-13 02:55:14 +02:00
|
|
|
rocksdb::Status s = rocksdb::DBWithTTL::Open(
|
|
|
|
*opt, db_path, column_families, &handles, &db, ttl_values, jread_only);
|
2015-01-13 22:56:37 +01:00
|
|
|
|
2017-02-28 01:26:12 +01:00
|
|
|
// we have now finished with db_path
|
|
|
|
env->ReleaseStringUTFChars(jdb_path, db_path);
|
|
|
|
|
2015-01-13 22:56:37 +01:00
|
|
|
// check if open operation was successful
|
|
|
|
if (s.ok()) {
|
2018-04-13 02:55:14 +02:00
|
|
|
const jsize resultsLen = 1 + len_cols; // db handle + column family handles
|
2016-07-26 22:18:31 +02:00
|
|
|
std::unique_ptr<jlong[]> results =
|
|
|
|
std::unique_ptr<jlong[]>(new jlong[resultsLen]);
|
2016-01-20 18:05:41 +01:00
|
|
|
results[0] = reinterpret_cast<jlong>(db);
|
2018-04-13 02:55:14 +02:00
|
|
|
for (int i = 1; i <= len_cols; i++) {
|
2016-01-20 18:05:41 +01:00
|
|
|
results[i] = reinterpret_cast<jlong>(handles[i - 1]);
|
2015-01-13 22:56:37 +01:00
|
|
|
}
|
|
|
|
|
2016-01-20 18:05:41 +01:00
|
|
|
jlongArray jresults = env->NewLongArray(resultsLen);
|
2018-04-13 02:55:14 +02:00
|
|
|
if (jresults == nullptr) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: OutOfMemoryError
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-07-22 19:17:10 +02:00
|
|
|
env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
|
2018-04-13 02:55:14 +02:00
|
|
|
if (env->ExceptionCheck()) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: ArrayIndexOutOfBoundsException
|
|
|
|
env->DeleteLocalRef(jresults);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-01-20 18:05:41 +01:00
|
|
|
return jresults;
|
|
|
|
} else {
|
|
|
|
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
|
|
|
return NULL;
|
2015-01-13 22:56:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-22 23:36:38 +01:00
|
|
|
/*
|
|
|
|
* Class: org_rocksdb_TtlDB
|
|
|
|
* Method: disposeInternal
|
|
|
|
* Signature: (J)V
|
|
|
|
*/
|
|
|
|
void Java_org_rocksdb_TtlDB_disposeInternal(
|
|
|
|
JNIEnv*, jobject, jlong jhandle) {
|
|
|
|
auto* ttl_db = reinterpret_cast<rocksdb::DBWithTTL*>(jhandle);
|
|
|
|
assert(ttl_db != nullptr);
|
|
|
|
delete ttl_db;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_rocksdb_TtlDB
|
|
|
|
* Method: closeDatabase
|
|
|
|
* Signature: (J)V
|
|
|
|
*/
|
|
|
|
void Java_org_rocksdb_TtlDB_closeDatabase(
|
|
|
|
JNIEnv* /* env */, jclass, jlong /* jhandle */) {
|
|
|
|
//auto* ttl_db = reinterpret_cast<rocksdb::DBWithTTL*>(jhandle);
|
|
|
|
//assert(ttl_db != nullptr);
|
|
|
|
//rocksdb::Status s = ttl_db->Close();
|
|
|
|
//rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
|
|
|
|
|
|
|
//TODO(AR) this is disabled until https://github.com/facebook/rocksdb/issues/4818 is resolved!
|
|
|
|
}
|
|
|
|
|
2014-11-21 23:38:17 +01:00
|
|
|
/*
|
|
|
|
* Class: org_rocksdb_TtlDB
|
|
|
|
* Method: createColumnFamilyWithTtl
|
2016-02-01 21:00:40 +01:00
|
|
|
* Signature: (JLorg/rocksdb/ColumnFamilyDescriptor;[BJI)J;
|
2014-11-21 23:38:17 +01:00
|
|
|
*/
|
|
|
|
jlong Java_org_rocksdb_TtlDB_createColumnFamilyWithTtl(
|
2019-02-22 23:36:38 +01:00
|
|
|
JNIEnv* env, jobject, jlong jdb_handle, jbyteArray jcolumn_name,
|
2018-04-13 02:55:14 +02:00
|
|
|
jlong jcolumn_options, jint jttl) {
|
2017-02-28 01:26:12 +01:00
|
|
|
jbyte* cfname = env->GetByteArrayElements(jcolumn_name, nullptr);
|
2018-04-13 02:55:14 +02:00
|
|
|
if (cfname == nullptr) {
|
2017-02-28 01:26:12 +01:00
|
|
|
// exception thrown: OutOfMemoryError
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
const jsize len = env->GetArrayLength(jcolumn_name);
|
2016-02-01 21:00:40 +01:00
|
|
|
|
|
|
|
auto* cfOptions =
|
|
|
|
reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcolumn_options);
|
2015-01-31 14:43:21 +01:00
|
|
|
|
2017-02-28 01:26:12 +01:00
|
|
|
auto* db_handle = reinterpret_cast<rocksdb::DBWithTTL*>(jdb_handle);
|
|
|
|
rocksdb::ColumnFamilyHandle* handle;
|
2014-11-21 23:38:17 +01:00
|
|
|
rocksdb::Status s = db_handle->CreateColumnFamilyWithTtl(
|
2018-04-13 02:55:14 +02:00
|
|
|
*cfOptions, std::string(reinterpret_cast<char*>(cfname), len), &handle,
|
|
|
|
jttl);
|
2017-02-28 01:26:12 +01:00
|
|
|
|
2016-02-01 21:00:40 +01:00
|
|
|
env->ReleaseByteArrayElements(jcolumn_name, cfname, 0);
|
2014-11-21 23:38:17 +01:00
|
|
|
|
|
|
|
if (s.ok()) {
|
|
|
|
return reinterpret_cast<jlong>(handle);
|
|
|
|
}
|
|
|
|
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
|
|
|
return 0;
|
|
|
|
}
|