提交 c6d464a9 编写于 作者: A Adam Retter 提交者: Facebook Github Bot

Fixed various memory leaks and Java 8 JNI Compatibility

Summary:
I have manually audited the entire RocksJava code base.

Sorry for the large pull-request, I have broken it down into many small atomic commits though.

My initial intention was to fix the warnings that appear when running RocksJava on Java 8 with `-Xcheck:jni`, for example when running `make jtest` you would see many errors similar to:

```
WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethod
WARNING in native method: JNI call made without checking exceptions when required to from CallVoidMethod
WARNING in native method: JNI call made without checking exceptions when required to from CallStaticVoidMethod
...
```

A few of those warnings still remain, however they seem to come directly from the JVM and are not directly related to RocksJava; I am in contact with the OpenJDK hostpot-dev mailing list about these - http://mail.openjdk.java.net/pipermail/hotspot-dev/2017-February/025981.html.

As a result of fixing these, I realised we were not r
Closes https://github.com/facebook/rocksdb/pull/1890

Differential Revision: D4591758

Pulled By: siying

fbshipit-source-id: 7f7fdf4
上级 be3e5568
......@@ -18,7 +18,6 @@ NATIVE_JAVA_CLASSES = org.rocksdb.AbstractCompactionFilter\
org.rocksdb.ExternalSstFileInfo\
org.rocksdb.FlushOptions\
org.rocksdb.Filter\
org.rocksdb.GenericRateLimiterConfig\
org.rocksdb.HashLinkedListMemTableConfig\
org.rocksdb.HashSkipListMemTableConfig\
org.rocksdb.Logger\
......@@ -91,6 +90,7 @@ JAVA_TESTS = org.rocksdb.BackupableDBOptionsTest\
org.rocksdb.NativeLibraryLoaderTest\
org.rocksdb.OptionsTest\
org.rocksdb.PlainTableConfigTest\
org.rocksdb.RateLimiterTest\
org.rocksdb.ReadOnlyTest\
org.rocksdb.ReadOptionsTest\
org.rocksdb.RocksDBTest\
......@@ -136,6 +136,14 @@ JAVA_TESTCLASSPATH = $(JAVA_JUNIT_JAR):$(JAVA_HAMCR_JAR):$(JAVA_MOCKITO_JAR):$(J
MVN_LOCAL = ~/.m2/repository
# Set the default JAVA_ARGS to "" for DEBUG_LEVEL=0
JAVA_ARGS? =
# When debugging add -Xcheck:jni to the java args
ifneq ($(DEBUG_LEVEL),0)
JAVA_ARGS = -ea -Xcheck:jni
endif
clean:
$(AM_V_at)rm -rf include/*
$(AM_V_at)rm -rf test-libs/
......@@ -164,7 +172,7 @@ sample: java
$(AM_V_at)javac -cp $(MAIN_CLASSES) -d $(SAMPLES_MAIN_CLASSES) $(SAMPLES_MAIN_SRC)/RocksDBSample.java
$(AM_V_at)@rm -rf /tmp/rocksdbjni
$(AM_V_at)@rm -rf /tmp/rocksdbjni_not_found
java -ea -Xcheck:jni -Djava.library.path=target -cp $(MAIN_CLASSES):$(SAMPLES_MAIN_CLASSES) RocksDBSample /tmp/rocksdbjni
java $(JAVA_ARGS) -Djava.library.path=target -cp $(MAIN_CLASSES):$(SAMPLES_MAIN_CLASSES) RocksDBSample /tmp/rocksdbjni
$(AM_V_at)@rm -rf /tmp/rocksdbjni
$(AM_V_at)@rm -rf /tmp/rocksdbjni_not_found
......@@ -172,7 +180,7 @@ column_family_sample: java
$(AM_V_GEN)mkdir -p $(SAMPLES_MAIN_CLASSES)
$(AM_V_at)javac -cp $(MAIN_CLASSES) -d $(SAMPLES_MAIN_CLASSES) $(SAMPLES_MAIN_SRC)/RocksDBColumnFamilySample.java
$(AM_V_at)@rm -rf /tmp/rocksdbjni
java -ea -Xcheck:jni -Djava.library.path=target -cp $(MAIN_CLASSES):$(SAMPLES_MAIN_CLASSES) RocksDBColumnFamilySample /tmp/rocksdbjni
java $(JAVA_ARGS) -Djava.library.path=target -cp $(MAIN_CLASSES):$(SAMPLES_MAIN_CLASSES) RocksDBColumnFamilySample /tmp/rocksdbjni
$(AM_V_at)@rm -rf /tmp/rocksdbjni
resolve_test_deps:
......@@ -194,7 +202,7 @@ java_test: java resolve_test_deps
test: java java_test run_test
run_test:
java -ea -Djava.library.path=target -cp "$(MAIN_CLASSES):$(TEST_CLASSES):$(JAVA_TESTCLASSPATH):target/*" org.rocksdb.test.RocksJunitRunner $(JAVA_TESTS)
java $(JAVA_ARGS) -Djava.library.path=target -cp "$(MAIN_CLASSES):$(TEST_CLASSES):$(JAVA_TESTCLASSPATH):target/*" org.rocksdb.test.RocksJunitRunner $(JAVA_TESTS)
db_bench: java
$(AM_V_GEN)mkdir -p $(BENCHMARK_MAIN_CLASSES)
......
......@@ -572,7 +572,7 @@ public class DbBenchmark {
(Integer)flags_.get(Flag.num_levels));
options.setTargetFileSizeBase(
(Integer)flags_.get(Flag.target_file_size_base));
options.setTargetFileSizeMultiplier((Double) flags_.get(Flag.target_file_size_multiplier));
options.setTargetFileSizeMultiplier((Integer)flags_.get(Flag.target_file_size_multiplier));
options.setMaxBytesForLevelBase(
(Integer)flags_.get(Flag.max_bytes_for_level_base));
options.setMaxBytesForLevelMultiplier((Double) flags_.get(Flag.max_bytes_for_level_multiplier));
......@@ -588,12 +588,10 @@ public class DbBenchmark {
(Double)flags_.get(Flag.hard_rate_limit));
options.setRateLimitDelayMaxMilliseconds(
(Integer)flags_.get(Flag.rate_limit_delay_max_milliseconds));
options.setMaxGrandparentOverlapFactor(
(Integer)flags_.get(Flag.max_grandparent_overlap_factor));
options.setMaxCompactionBytes(
(Long) flags_.get(Flag.max_compaction_bytes));
options.setDisableAutoCompactions(
(Boolean)flags_.get(Flag.disable_auto_compactions));
options.setSourceCompactionFactor(
(Integer)flags_.get(Flag.source_compaction_factor));
options.setMaxSuccessiveMerges(
(Integer)flags_.get(Flag.max_successive_merges));
options.setWalTtlSeconds((Long)flags_.get(Flag.wal_ttl_seconds));
......@@ -978,7 +976,7 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
write_buffer_size(4 * SizeUnit.MB,
write_buffer_size(4L * SizeUnit.MB,
"Number of bytes to buffer in memtable before compacting\n" +
"\t(initialized to default value by 'main'.)") {
@Override public Object parseValue(String value) {
......@@ -1056,7 +1054,7 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
numdistinct(1000,
numdistinct(1000L,
"Number of distinct keys to use. Used in RandomWithVerify to\n" +
"\tread/write on fewer keys so that gets are more likely to find the\n" +
"\tkey and puts are more likely to update the same key.") {
......@@ -1064,7 +1062,7 @@ public class DbBenchmark {
return Long.parseLong(value);
}
},
merge_keys(-1,
merge_keys(-1L,
"Number of distinct keys to use for MergeRandom and\n" +
"\tReadRandomMergeRandom.\n" +
"\tIf negative, there will be FLAGS_num keys.") {
......@@ -1169,7 +1167,7 @@ public class DbBenchmark {
return Long.parseLong(value);
}
},
compressed_cache_size(-1,
compressed_cache_size(-1L,
"Number of bytes to use as a cache of compressed data.") {
@Override public Object parseValue(String value) {
return Long.parseLong(value);
......@@ -1188,7 +1186,7 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
memtable_bloom_size_ratio(0, "Ratio of memtable used by the bloom filter.\n"
memtable_bloom_size_ratio(0.0d, "Ratio of memtable used by the bloom filter.\n"
+ "\t0 means no bloom filter.") {
@Override public Object parseValue(String value) {
return Double.parseDouble(value);
......@@ -1212,7 +1210,7 @@ public class DbBenchmark {
return parseBoolean(value);
}
},
writes(-1,"Number of write operations to do. If negative, do\n" +
writes(-1L, "Number of write operations to do. If negative, do\n" +
"\t--num reads.") {
@Override public Object parseValue(String value) {
return Long.parseLong(value);
......@@ -1255,7 +1253,7 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
max_bytes_for_level_multiplier(10,
max_bytes_for_level_multiplier(10.0d,
"A multiplier to compute max bytes for level-N (N >= 2)") {
@Override public Object parseValue(String value) {
return Double.parseDouble(value);
......@@ -1337,7 +1335,7 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
stats_interval(0,"Stats are reported every N operations when\n" +
stats_interval(0L, "Stats are reported every N operations when\n" +
"\tthis is greater than zero. When 0 the interval grows over time.") {
@Override public Object parseValue(String value) {
return Long.parseLong(value);
......@@ -1354,12 +1352,12 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
soft_rate_limit(0.0,"") {
soft_rate_limit(0.0d,"") {
@Override public Object parseValue(String value) {
return Double.parseDouble(value);
}
},
hard_rate_limit(0.0,"When not equal to 0 this make threads\n" +
hard_rate_limit(0.0d,"When not equal to 0 this make threads\n" +
"\tsleep at each stats reporting interval until the compaction\n" +
"\tscore for all levels is less than or equal to this value.") {
@Override public Object parseValue(String value) {
......@@ -1373,11 +1371,10 @@ public class DbBenchmark {
return Integer.parseInt(value);
}
},
max_grandparent_overlap_factor(10,"Control maximum bytes of\n" +
"\toverlaps in grandparent (i.e., level+2) before we stop building a\n" +
"\tsingle file in a level->level+1 compaction.") {
max_compaction_bytes(0L, "Limit number of bytes in one compaction to be lower than this\n" +
"\threshold. But it's not guaranteed.") {
@Override public Object parseValue(String value) {
return Integer.parseInt(value);
return Long.parseLong(value);
}
},
readonly(false,"Run read only benchmarks.") {
......@@ -1390,13 +1387,6 @@ public class DbBenchmark {
return parseBoolean(value);
}
},
source_compaction_factor(1,"Cap the size of data in level-K for\n" +
"\ta compaction run that compacts Level-K with Level-(K+1) (for\n" +
"\tK >= 1)") {
@Override public Object parseValue(String value) {
return Integer.parseInt(value);
}
},
wal_ttl_seconds(0L,"Set the TTL for the WAL Files in seconds.") {
@Override public Object parseValue(String value) {
return Long.parseLong(value);
......
......@@ -27,8 +27,12 @@
*/
jlong Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions(
JNIEnv* env, jclass jcls, jstring jpath) {
const char* cpath = env->GetStringUTFChars(jpath, NULL);
auto bopt = new rocksdb::BackupableDBOptions(cpath);
const char* cpath = env->GetStringUTFChars(jpath, nullptr);
if(cpath == nullptr) {
// exception thrown: OutOfMemoryError
return 0;
}
auto* bopt = new rocksdb::BackupableDBOptions(cpath);
env->ReleaseStringUTFChars(jpath, cpath);
return reinterpret_cast<jlong>(bopt);
}
......@@ -40,7 +44,7 @@ jlong Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions(
*/
jstring Java_org_rocksdb_BackupableDBOptions_backupDir(
JNIEnv* env, jobject jopt, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return env->NewStringUTF(bopt->backup_dir.c_str());
}
......@@ -51,7 +55,7 @@ jstring Java_org_rocksdb_BackupableDBOptions_backupDir(
*/
void Java_org_rocksdb_BackupableDBOptions_setShareTableFiles(
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->share_table_files = flag;
}
......@@ -62,7 +66,7 @@ void Java_org_rocksdb_BackupableDBOptions_setShareTableFiles(
*/
jboolean Java_org_rocksdb_BackupableDBOptions_shareTableFiles(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->share_table_files;
}
......@@ -73,7 +77,7 @@ jboolean Java_org_rocksdb_BackupableDBOptions_shareTableFiles(
*/
void Java_org_rocksdb_BackupableDBOptions_setSync(
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->sync = flag;
}
......@@ -84,7 +88,7 @@ void Java_org_rocksdb_BackupableDBOptions_setSync(
*/
jboolean Java_org_rocksdb_BackupableDBOptions_sync(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->sync;
}
......@@ -95,7 +99,7 @@ jboolean Java_org_rocksdb_BackupableDBOptions_sync(
*/
void Java_org_rocksdb_BackupableDBOptions_setDestroyOldData(
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->destroy_old_data = flag;
}
......@@ -106,7 +110,7 @@ void Java_org_rocksdb_BackupableDBOptions_setDestroyOldData(
*/
jboolean Java_org_rocksdb_BackupableDBOptions_destroyOldData(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->destroy_old_data;
}
......@@ -117,7 +121,7 @@ jboolean Java_org_rocksdb_BackupableDBOptions_destroyOldData(
*/
void Java_org_rocksdb_BackupableDBOptions_setBackupLogFiles(
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->backup_log_files = flag;
}
......@@ -128,7 +132,7 @@ void Java_org_rocksdb_BackupableDBOptions_setBackupLogFiles(
*/
jboolean Java_org_rocksdb_BackupableDBOptions_backupLogFiles(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->backup_log_files;
}
......@@ -139,7 +143,7 @@ jboolean Java_org_rocksdb_BackupableDBOptions_backupLogFiles(
*/
void Java_org_rocksdb_BackupableDBOptions_setBackupRateLimit(
JNIEnv* env, jobject jobj, jlong jhandle, jlong jbackup_rate_limit) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->backup_rate_limit = jbackup_rate_limit;
}
......@@ -150,7 +154,7 @@ void Java_org_rocksdb_BackupableDBOptions_setBackupRateLimit(
*/
jlong Java_org_rocksdb_BackupableDBOptions_backupRateLimit(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->backup_rate_limit;
}
......@@ -161,7 +165,7 @@ jlong Java_org_rocksdb_BackupableDBOptions_backupRateLimit(
*/
void Java_org_rocksdb_BackupableDBOptions_setRestoreRateLimit(
JNIEnv* env, jobject jobj, jlong jhandle, jlong jrestore_rate_limit) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->restore_rate_limit = jrestore_rate_limit;
}
......@@ -172,7 +176,7 @@ void Java_org_rocksdb_BackupableDBOptions_setRestoreRateLimit(
*/
jlong Java_org_rocksdb_BackupableDBOptions_restoreRateLimit(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->restore_rate_limit;
}
......@@ -183,7 +187,7 @@ jlong Java_org_rocksdb_BackupableDBOptions_restoreRateLimit(
*/
void Java_org_rocksdb_BackupableDBOptions_setShareFilesWithChecksum(
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
bopt->share_files_with_checksum = flag;
}
......@@ -194,7 +198,7 @@ void Java_org_rocksdb_BackupableDBOptions_setShareFilesWithChecksum(
*/
jboolean Java_org_rocksdb_BackupableDBOptions_shareFilesWithChecksum(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
return bopt->share_files_with_checksum;
}
......@@ -205,7 +209,7 @@ jboolean Java_org_rocksdb_BackupableDBOptions_shareFilesWithChecksum(
*/
void Java_org_rocksdb_BackupableDBOptions_disposeInternal(
JNIEnv* env, jobject jopt, jlong jhandle) {
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
assert(bopt);
auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
assert(bopt != nullptr);
delete bopt;
}
......@@ -82,11 +82,15 @@ jintArray Java_org_rocksdb_BackupEngine_getCorruptedBackups(
backup_engine->GetCorruptedBackups(&backup_ids);
// store backupids in int array
std::vector<jint> int_backup_ids(backup_ids.begin(), backup_ids.end());
// Store ints in java array
jintArray ret_backup_ids;
// Its ok to loose precision here (64->32)
jsize ret_backup_ids_size = static_cast<jsize>(backup_ids.size());
ret_backup_ids = env->NewIntArray(ret_backup_ids_size);
jintArray ret_backup_ids = env->NewIntArray(ret_backup_ids_size);
if(ret_backup_ids == nullptr) {
// exception thrown: OutOfMemoryError
return nullptr;
}
env->SetIntArrayRegion(ret_backup_ids, 0, ret_backup_ids_size,
int_backup_ids.data());
return ret_backup_ids;
......@@ -155,14 +159,24 @@ void Java_org_rocksdb_BackupEngine_restoreDbFromBackup(
JNIEnv* env, jobject jbe, jlong jbe_handle, jint jbackup_id,
jstring jdb_dir, jstring jwal_dir, jlong jrestore_options_handle) {
auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
const char* db_dir = env->GetStringUTFChars(jdb_dir, 0);
const char* wal_dir = env->GetStringUTFChars(jwal_dir, 0);
const char* db_dir = env->GetStringUTFChars(jdb_dir, nullptr);
if(db_dir == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
if(wal_dir == nullptr) {
// exception thrown: OutOfMemoryError
env->ReleaseStringUTFChars(jdb_dir, db_dir);
return;
}
auto* restore_options =
reinterpret_cast<rocksdb::RestoreOptions*>(jrestore_options_handle);
auto status =
backup_engine->RestoreDBFromBackup(
static_cast<rocksdb::BackupID>(jbackup_id), db_dir, wal_dir,
*restore_options);
env->ReleaseStringUTFChars(jwal_dir, wal_dir);
env->ReleaseStringUTFChars(jdb_dir, db_dir);
......@@ -182,13 +196,23 @@ void Java_org_rocksdb_BackupEngine_restoreDbFromLatestBackup(
JNIEnv* env, jobject jbe, jlong jbe_handle, jstring jdb_dir,
jstring jwal_dir, jlong jrestore_options_handle) {
auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
const char* db_dir = env->GetStringUTFChars(jdb_dir, 0);
const char* wal_dir = env->GetStringUTFChars(jwal_dir, 0);
const char* db_dir = env->GetStringUTFChars(jdb_dir, nullptr);
if(db_dir == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
if(wal_dir == nullptr) {
// exception thrown: OutOfMemoryError
env->ReleaseStringUTFChars(jdb_dir, db_dir);
return;
}
auto* restore_options =
reinterpret_cast<rocksdb::RestoreOptions*>(jrestore_options_handle);
auto status =
backup_engine->RestoreDBFromLatestBackup(db_dir, wal_dir,
*restore_options);
env->ReleaseStringUTFChars(jwal_dir, wal_dir);
env->ReleaseStringUTFChars(jdb_dir, db_dir);
......@@ -206,5 +230,7 @@ void Java_org_rocksdb_BackupEngine_restoreDbFromLatestBackup(
*/
void Java_org_rocksdb_BackupEngine_disposeInternal(
JNIEnv* env, jobject jbe, jlong jbe_handle) {
delete reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
auto* be = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
assert(be != nullptr);
delete be;
}
......@@ -22,7 +22,7 @@
*/
jlong Java_org_rocksdb_Checkpoint_newCheckpoint(JNIEnv* env,
jclass jclazz, jlong jdb_handle) {
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
rocksdb::Checkpoint* checkpoint;
rocksdb::Checkpoint::Create(db, &checkpoint);
return reinterpret_cast<jlong>(checkpoint);
......@@ -35,8 +35,8 @@ jlong Java_org_rocksdb_Checkpoint_newCheckpoint(JNIEnv* env,
*/
void Java_org_rocksdb_Checkpoint_disposeInternal(JNIEnv* env, jobject jobj,
jlong jhandle) {
auto checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(jhandle);
assert(checkpoint);
auto* checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(jhandle);
assert(checkpoint != nullptr);
delete checkpoint;
}
......@@ -48,13 +48,20 @@ void Java_org_rocksdb_Checkpoint_disposeInternal(JNIEnv* env, jobject jobj,
void Java_org_rocksdb_Checkpoint_createCheckpoint(
JNIEnv* env, jobject jobj, jlong jcheckpoint_handle,
jstring jcheckpoint_path) {
auto checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(
jcheckpoint_handle);
const char* checkpoint_path = env->GetStringUTFChars(
jcheckpoint_path, 0);
if(checkpoint_path == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
auto* checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(
jcheckpoint_handle);
rocksdb::Status s = checkpoint->CreateCheckpoint(
checkpoint_path);
env->ReleaseStringUTFChars(jcheckpoint_path, checkpoint_path);
if (!s.ok()) {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
......
......@@ -20,6 +20,7 @@
*/
void Java_org_rocksdb_ColumnFamilyHandle_disposeInternal(
JNIEnv* env, jobject jobj, jlong handle) {
auto it = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(handle);
delete it;
auto* cfh = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(handle);
assert(cfh != nullptr);
delete cfh;
}
......@@ -20,6 +20,8 @@
*/
void Java_org_rocksdb_AbstractCompactionFilter_disposeInternal(
JNIEnv* env, jobject jobj, jlong handle) {
delete reinterpret_cast<rocksdb::CompactionFilter*>(handle);
auto* cf = reinterpret_cast<rocksdb::CompactionFilter*>(handle);
assert(cf != nullptr);
delete cf;
}
// </editor-fold>
......@@ -27,7 +27,9 @@
*/
void Java_org_rocksdb_AbstractComparator_disposeInternal(
JNIEnv* env, jobject jobj, jlong handle) {
delete reinterpret_cast<rocksdb::BaseComparatorJniCallback*>(handle);
auto* bcjc = reinterpret_cast<rocksdb::BaseComparatorJniCallback*>(handle);
assert(bcjc != nullptr);
delete bcjc;
}
// </editor-fold>
......
......@@ -17,35 +17,60 @@ BaseComparatorJniCallback::BaseComparatorJniCallback(
mtx_findShortestSeparator(new port::Mutex(copt->use_adaptive_mutex)) {
// Note: Comparator methods may be accessed by multiple threads,
// so we ref the jvm not the env
const jint rs __attribute__((unused)) = env->GetJavaVM(&m_jvm);
assert(rs == JNI_OK);
const jint rs = env->GetJavaVM(&m_jvm);
if(rs != JNI_OK) {
// exception thrown
return;
}
// Note: we want to access the Java Comparator instance
// across multiple method calls, so we create a global ref
assert(jComparator != nullptr);
m_jComparator = env->NewGlobalRef(jComparator);
if(m_jComparator == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
// Note: The name of a Comparator will not change during it's lifetime,
// so we cache it in a global var
jmethodID jNameMethodId = AbstractComparatorJni::getNameMethodId(env);
if(jNameMethodId == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return;
}
jstring jsName = (jstring)env->CallObjectMethod(m_jComparator, jNameMethodId);
m_name = JniUtil::copyString(env, jsName); // also releases jsName
if(env->ExceptionCheck()) {
// exception thrown
return;
}
jboolean has_exception = JNI_FALSE;
m_name = JniUtil::copyString(env, jsName,
&has_exception); // also releases jsName
if (has_exception == JNI_TRUE) {
// exception thrown
return;
}
m_jCompareMethodId = AbstractComparatorJni::getCompareMethodId(env);
if(m_jCompareMethodId == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return;
}
m_jFindShortestSeparatorMethodId =
AbstractComparatorJni::getFindShortestSeparatorMethodId(env);
if(m_jFindShortestSeparatorMethodId == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return;
}
m_jFindShortSuccessorMethodId =
AbstractComparatorJni::getFindShortSuccessorMethodId(env);
}
/**
* Attach/Get a JNIEnv for the current native thread
*/
JNIEnv* BaseComparatorJniCallback::getJniEnv() const {
JNIEnv *env;
jint rs __attribute__((unused)) =
m_jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);
assert(rs == JNI_OK);
return env;
if(m_jFindShortSuccessorMethodId == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return;
}
}
const char* BaseComparatorJniCallback::Name() const {
......@@ -53,22 +78,50 @@ const char* BaseComparatorJniCallback::Name() const {
}
int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
JNIEnv* m_env = getJniEnv();
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
// TODO(adamretter): slice objects can potentially be cached using thread
// local variables to avoid locking. Could make this configurable depending on
// performance.
mtx_compare->Lock();
AbstractSliceJni::setHandle(m_env, m_jSliceA, &a, JNI_FALSE);
AbstractSliceJni::setHandle(m_env, m_jSliceB, &b, JNI_FALSE);
bool pending_exception =
AbstractSliceJni::setHandle(env, m_jSliceA, &a, JNI_FALSE);
if(pending_exception) {
if(env->ExceptionCheck()) {
// exception thrown from setHandle or descendant
env->ExceptionDescribe(); // print out exception to stderr
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return 0;
}
pending_exception =
AbstractSliceJni::setHandle(env, m_jSliceB, &b, JNI_FALSE);
if(pending_exception) {
if(env->ExceptionCheck()) {
// exception thrown from setHandle or descendant
env->ExceptionDescribe(); // print out exception to stderr
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return 0;
}
jint result =
m_env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA,
env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA,
m_jSliceB);
mtx_compare->Unlock();
m_jvm->DetachCurrentThread();
if(env->ExceptionCheck()) {
// exception thrown from CallIntMethod
env->ExceptionDescribe(); // print out exception to stderr
result = 0; // we could not get a result from java callback so use 0
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return result;
}
......@@ -79,32 +132,80 @@ void BaseComparatorJniCallback::FindShortestSeparator(
return;
}
JNIEnv* m_env = getJniEnv();
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
const char* startUtf = start->c_str();
jstring jsStart = m_env->NewStringUTF(startUtf);
jstring jsStart = env->NewStringUTF(startUtf);
if(jsStart == nullptr) {
// unable to construct string
if(env->ExceptionCheck()) {
env->ExceptionDescribe(); // print out exception to stderr
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
if(env->ExceptionCheck()) {
// exception thrown: OutOfMemoryError
env->ExceptionDescribe(); // print out exception to stderr
env->DeleteLocalRef(jsStart);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
// TODO(adamretter): slice object can potentially be cached using thread local
// variable to avoid locking. Could make this configurable depending on
// performance.
mtx_findShortestSeparator->Lock();
AbstractSliceJni::setHandle(m_env, m_jSliceLimit, &limit, JNI_FALSE);
bool pending_exception =
AbstractSliceJni::setHandle(env, m_jSliceLimit, &limit, JNI_FALSE);
if(pending_exception) {
if(env->ExceptionCheck()) {
// exception thrown from setHandle or descendant
env->ExceptionDescribe(); // print out exception to stderr
}
if(jsStart != nullptr) {
env->DeleteLocalRef(jsStart);
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
jstring jsResultStart =
(jstring)m_env->CallObjectMethod(m_jComparator,
(jstring)env->CallObjectMethod(m_jComparator,
m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit);
mtx_findShortestSeparator->Unlock();
m_env->DeleteLocalRef(jsStart);
if(env->ExceptionCheck()) {
// exception thrown from CallObjectMethod
env->ExceptionDescribe(); // print out exception to stderr
env->DeleteLocalRef(jsStart);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
env->DeleteLocalRef(jsStart);
if (jsResultStart != nullptr) {
// update start with result
*start =
JniUtil::copyString(m_env, jsResultStart); // also releases jsResultStart
jboolean has_exception = JNI_FALSE;
std::string result = JniUtil::copyString(env, jsResultStart,
&has_exception); // also releases jsResultStart
if (has_exception == JNI_TRUE) {
if (env->ExceptionCheck()) {
env->ExceptionDescribe(); // print out exception to stderr
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
*start = result;
}
m_jvm->DetachCurrentThread();
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
void BaseComparatorJniCallback::FindShortSuccessor(std::string* key) const {
......@@ -112,34 +213,69 @@ void BaseComparatorJniCallback::FindShortSuccessor(std::string* key) const {
return;
}
JNIEnv* m_env = getJniEnv();
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
const char* keyUtf = key->c_str();
jstring jsKey = m_env->NewStringUTF(keyUtf);
jstring jsKey = env->NewStringUTF(keyUtf);
if(jsKey == nullptr) {
// unable to construct string
if(env->ExceptionCheck()) {
env->ExceptionDescribe(); // print out exception to stderr
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
} else if(env->ExceptionCheck()) {
// exception thrown: OutOfMemoryError
env->ExceptionDescribe(); // print out exception to stderr
env->DeleteLocalRef(jsKey);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
jstring jsResultKey =
(jstring)m_env->CallObjectMethod(m_jComparator,
(jstring)env->CallObjectMethod(m_jComparator,
m_jFindShortSuccessorMethodId, jsKey);
m_env->DeleteLocalRef(jsKey);
if(env->ExceptionCheck()) {
// exception thrown from CallObjectMethod
env->ExceptionDescribe(); // print out exception to stderr
env->DeleteLocalRef(jsKey);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
env->DeleteLocalRef(jsKey);
if (jsResultKey != nullptr) {
// updates key with result, also releases jsResultKey.
*key = JniUtil::copyString(m_env, jsResultKey);
jboolean has_exception = JNI_FALSE;
std::string result = JniUtil::copyString(env, jsResultKey, &has_exception);
if (has_exception == JNI_TRUE) {
if (env->ExceptionCheck()) {
env->ExceptionDescribe(); // print out exception to stderr
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
*key = result;
}
m_jvm->DetachCurrentThread();
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
BaseComparatorJniCallback::~BaseComparatorJniCallback() {
JNIEnv* m_env = getJniEnv();
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
m_env->DeleteGlobalRef(m_jComparator);
if(m_jComparator != nullptr) {
env->DeleteGlobalRef(m_jComparator);
}
// Note: do not need to explicitly detach, as this function is effectively
// called from the Java class's disposeInternal method, and so already
// has an attached thread, getJniEnv above is just a no-op Attach to get
// the env jvm->DetachCurrentThread();
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
ComparatorJniCallback::ComparatorJniCallback(
......@@ -147,15 +283,42 @@ ComparatorJniCallback::ComparatorJniCallback(
const ComparatorJniCallbackOptions* copt) :
BaseComparatorJniCallback(env, jComparator, copt) {
m_jSliceA = env->NewGlobalRef(SliceJni::construct0(env));
if(m_jSliceA == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
m_jSliceB = env->NewGlobalRef(SliceJni::construct0(env));
if(m_jSliceB == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
m_jSliceLimit = env->NewGlobalRef(SliceJni::construct0(env));
if(m_jSliceLimit == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
}
ComparatorJniCallback::~ComparatorJniCallback() {
JNIEnv* m_env = getJniEnv();
m_env->DeleteGlobalRef(m_jSliceA);
m_env->DeleteGlobalRef(m_jSliceB);
m_env->DeleteGlobalRef(m_jSliceLimit);
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
if(m_jSliceA != nullptr) {
env->DeleteGlobalRef(m_jSliceA);
}
if(m_jSliceB != nullptr) {
env->DeleteGlobalRef(m_jSliceB);
}
if(m_jSliceLimit != nullptr) {
env->DeleteGlobalRef(m_jSliceLimit);
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
DirectComparatorJniCallback::DirectComparatorJniCallback(
......@@ -163,14 +326,41 @@ DirectComparatorJniCallback::DirectComparatorJniCallback(
const ComparatorJniCallbackOptions* copt) :
BaseComparatorJniCallback(env, jComparator, copt) {
m_jSliceA = env->NewGlobalRef(DirectSliceJni::construct0(env));
if(m_jSliceA == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
m_jSliceB = env->NewGlobalRef(DirectSliceJni::construct0(env));
if(m_jSliceB == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
m_jSliceLimit = env->NewGlobalRef(DirectSliceJni::construct0(env));
if(m_jSliceLimit == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
}
DirectComparatorJniCallback::~DirectComparatorJniCallback() {
JNIEnv* m_env = getJniEnv();
m_env->DeleteGlobalRef(m_jSliceA);
m_env->DeleteGlobalRef(m_jSliceB);
m_env->DeleteGlobalRef(m_jSliceLimit);
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
if(m_jSliceA != nullptr) {
env->DeleteGlobalRef(m_jSliceA);
}
if(m_jSliceB != nullptr) {
env->DeleteGlobalRef(m_jSliceB);
}
if(m_jSliceLimit != nullptr) {
env->DeleteGlobalRef(m_jSliceLimit);
}
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
} // namespace rocksdb
......@@ -61,7 +61,6 @@ class BaseComparatorJniCallback : public Comparator {
port::Mutex* mtx_compare;
// used for synchronisation in findShortestSeparator method
port::Mutex* mtx_findShortestSeparator;
JavaVM* m_jvm;
jobject m_jComparator;
std::string m_name;
jmethodID m_jCompareMethodId;
......@@ -69,7 +68,7 @@ class BaseComparatorJniCallback : public Comparator {
jmethodID m_jFindShortSuccessorMethodId;
protected:
JNIEnv* getJniEnv() const;
JavaVM* m_jvm;
jobject m_jSliceA;
jobject m_jSliceB;
jobject m_jSliceLimit;
......
......@@ -75,5 +75,7 @@ jlong Java_org_rocksdb_RocksMemEnv_createMemEnv(
*/
void Java_org_rocksdb_RocksMemEnv_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::Env*>(jhandle);
auto* e = reinterpret_cast<rocksdb::Env*>(jhandle);
assert(e != nullptr);
delete e;
}
......@@ -44,7 +44,9 @@ jlong Java_org_rocksdb_EnvOptions_newEnvOptions(JNIEnv *env, jclass jcls) {
*/
void Java_org_rocksdb_EnvOptions_disposeInternal(JNIEnv *env, jobject jobj,
jlong jhandle) {
delete reinterpret_cast<rocksdb::EnvOptions *>(jhandle);
auto* eo = reinterpret_cast<rocksdb::EnvOptions *>(jhandle);
assert(eo != nullptr);
delete eo;
}
/*
......@@ -288,7 +290,8 @@ jlong Java_org_rocksdb_EnvOptions_writableFileMaxBufferSize(JNIEnv *env,
void Java_org_rocksdb_EnvOptions_setRateLimiter(JNIEnv *env, jobject jobj,
jlong jhandle,
jlong rl_handle) {
auto *rate_limiter = reinterpret_cast<rocksdb::RateLimiter *>(rl_handle);
auto *env_opt = reinterpret_cast<rocksdb::EnvOptions *>(jhandle);
env_opt->rate_limiter = rate_limiter;
auto* sptr_rate_limiter =
reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(rl_handle);
auto* env_opt = reinterpret_cast<rocksdb::EnvOptions *>(jhandle);
env_opt->rate_limiter = sptr_rate_limiter->get();
}
......@@ -31,17 +31,35 @@ jlong Java_org_rocksdb_ExternalSstFileInfo_newExternalSstFileInfo__Ljava_lang_St
JNIEnv *env, jclass jcls, jstring jfile_path, jstring jsmallest_key,
jstring jlargest_key, jlong jsequence_number, jlong jfile_size,
jint jnum_entries, jint jversion) {
const char *file_path = env->GetStringUTFChars(jfile_path, NULL);
const char *smallest_key = env->GetStringUTFChars(jsmallest_key, NULL);
const char *largest_key = env->GetStringUTFChars(jlargest_key, NULL);
const char *file_path = env->GetStringUTFChars(jfile_path, nullptr);
if(file_path == nullptr) {
// exception thrown: OutOfMemoryError
return 0;
}
const char *smallest_key = env->GetStringUTFChars(jsmallest_key, nullptr);
if(smallest_key == nullptr) {
// exception thrown: OutOfMemoryError
env->ReleaseStringUTFChars(jfile_path, file_path);
return 0;
}
const char *largest_key = env->GetStringUTFChars(jlargest_key, nullptr);
if(largest_key == nullptr) {
// exception thrown: OutOfMemoryError
env->ReleaseStringUTFChars(jsmallest_key, smallest_key);
env->ReleaseStringUTFChars(jfile_path, file_path);
return 0;
}
auto *external_sst_file_info = new rocksdb::ExternalSstFileInfo(
file_path, smallest_key, largest_key,
static_cast<rocksdb::SequenceNumber>(jsequence_number),
static_cast<uint64_t>(jfile_size), static_cast<int32_t>(jnum_entries),
static_cast<int32_t>(jversion));
env->ReleaseStringUTFChars(jfile_path, file_path);
env->ReleaseStringUTFChars(jsmallest_key, smallest_key);
env->ReleaseStringUTFChars(jlargest_key, largest_key);
env->ReleaseStringUTFChars(jsmallest_key, smallest_key);
env->ReleaseStringUTFChars(jfile_path, file_path);
return reinterpret_cast<jlong>(external_sst_file_info);
}
......@@ -55,7 +73,11 @@ void Java_org_rocksdb_ExternalSstFileInfo_setFilePath(JNIEnv *env, jobject jobj,
jstring jfile_path) {
auto *external_sst_file_info =
reinterpret_cast<rocksdb::ExternalSstFileInfo *>(jhandle);
const char *file_path = env->GetStringUTFChars(jfile_path, NULL);
const char *file_path = env->GetStringUTFChars(jfile_path, nullptr);
if(file_path == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
external_sst_file_info->file_path = file_path;
env->ReleaseStringUTFChars(jfile_path, file_path);
}
......@@ -81,7 +103,11 @@ void Java_org_rocksdb_ExternalSstFileInfo_setSmallestKey(
JNIEnv *env, jobject jobj, jlong jhandle, jstring jsmallest_key) {
auto *external_sst_file_info =
reinterpret_cast<rocksdb::ExternalSstFileInfo *>(jhandle);
const char *smallest_key = env->GetStringUTFChars(jsmallest_key, NULL);
const char *smallest_key = env->GetStringUTFChars(jsmallest_key, nullptr);
if(smallest_key == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
external_sst_file_info->smallest_key = smallest_key;
env->ReleaseStringUTFChars(jsmallest_key, smallest_key);
}
......@@ -111,6 +137,10 @@ void Java_org_rocksdb_ExternalSstFileInfo_setLargestKey(JNIEnv *env,
auto *external_sst_file_info =
reinterpret_cast<rocksdb::ExternalSstFileInfo *>(jhandle);
const char *largest_key = env->GetStringUTFChars(jlargest_key, NULL);
if(largest_key == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
external_sst_file_info->largest_key = largest_key;
env->ReleaseStringUTFChars(jlargest_key, largest_key);
}
......@@ -238,5 +268,7 @@ jint Java_org_rocksdb_ExternalSstFileInfo_version(JNIEnv *env, jobject jobj,
void Java_org_rocksdb_ExternalSstFileInfo_disposeInternal(JNIEnv *env,
jobject jobj,
jlong jhandle) {
delete reinterpret_cast<rocksdb::ExternalSstFileInfo *>(jhandle);
auto* esfi = reinterpret_cast<rocksdb::ExternalSstFileInfo *>(jhandle);
assert(esfi != nullptr);
delete esfi;
}
......@@ -24,12 +24,10 @@
jlong Java_org_rocksdb_BloomFilter_createNewBloomFilter(
JNIEnv* env, jclass jcls, jint bits_per_key,
jboolean use_block_base_builder) {
auto* fp = const_cast<rocksdb::FilterPolicy *>(
rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder));
auto* pFilterPolicy =
new std::shared_ptr<rocksdb::FilterPolicy>;
*pFilterPolicy = std::shared_ptr<rocksdb::FilterPolicy>(fp);
return reinterpret_cast<jlong>(pFilterPolicy);
auto* sptr_filter =
new std::shared_ptr<const rocksdb::FilterPolicy>(
rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder));
return reinterpret_cast<jlong>(sptr_filter);
}
/*
......@@ -39,8 +37,7 @@ jlong Java_org_rocksdb_BloomFilter_createNewBloomFilter(
*/
void Java_org_rocksdb_Filter_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) {
std::shared_ptr<rocksdb::FilterPolicy> *handle =
reinterpret_cast<std::shared_ptr<rocksdb::FilterPolicy> *>(jhandle);
handle->reset();
auto* handle =
reinterpret_cast<std::shared_ptr<const rocksdb::FilterPolicy> *>(jhandle);
delete handle; // delete std::shared_ptr
}
......@@ -21,7 +21,8 @@
*/
void Java_org_rocksdb_RocksIterator_disposeInternal(
JNIEnv* env, jobject jobj, jlong handle) {
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
assert(it != nullptr);
delete it;
}
......@@ -83,11 +84,16 @@ void Java_org_rocksdb_RocksIterator_prev0(
void Java_org_rocksdb_RocksIterator_seek0(
JNIEnv* env, jobject jobj, jlong handle,
jbyteArray jtarget, jint jtarget_len) {
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
jbyte* target = env->GetByteArrayElements(jtarget, 0);
jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
if(target == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
rocksdb::Slice target_slice(
reinterpret_cast<char*>(target), jtarget_len);
auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
it->Seek(target_slice);
env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
......@@ -100,7 +106,7 @@ void Java_org_rocksdb_RocksIterator_seek0(
*/
void Java_org_rocksdb_RocksIterator_status0(
JNIEnv* env, jobject jobj, jlong handle) {
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
rocksdb::Status s = it->status();
if (s.ok()) {
......@@ -117,10 +123,14 @@ void Java_org_rocksdb_RocksIterator_status0(
*/
jbyteArray Java_org_rocksdb_RocksIterator_key0(
JNIEnv* env, jobject jobj, jlong handle) {
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
rocksdb::Slice key_slice = it->key();
jbyteArray jkey = env->NewByteArray(static_cast<jsize>(key_slice.size()));
if(jkey == nullptr) {
// exception thrown: OutOfMemoryError
return nullptr;
}
env->SetByteArrayRegion(jkey, 0, static_cast<jsize>(key_slice.size()),
reinterpret_cast<const jbyte*>(key_slice.data()));
return jkey;
......@@ -133,11 +143,15 @@ jbyteArray Java_org_rocksdb_RocksIterator_key0(
*/
jbyteArray Java_org_rocksdb_RocksIterator_value0(
JNIEnv* env, jobject jobj, jlong handle) {
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
rocksdb::Slice value_slice = it->value();
jbyteArray jkeyValue =
env->NewByteArray(static_cast<jsize>(value_slice.size()));
if(jkeyValue == nullptr) {
// exception thrown: OutOfMemoryError
return nullptr;
}
env->SetByteArrayRegion(jkeyValue, 0, static_cast<jsize>(value_slice.size()),
reinterpret_cast<const jbyte*>(value_slice.data()));
return jkeyValue;
......
......@@ -10,53 +10,106 @@
#include "rocksjni/loggerjnicallback.h"
#include "rocksjni/portal.h"
#include <cstdarg>
#include <cstdio>
namespace rocksdb {
LoggerJniCallback::LoggerJniCallback(
JNIEnv* env, jobject jlogger) {
const jint rs __attribute__((unused)) = env->GetJavaVM(&m_jvm);
assert(rs == JNI_OK);
// Note: Logger methods may be accessed by multiple threads,
// so we ref the jvm not the env
const jint rs = env->GetJavaVM(&m_jvm);
if(rs != JNI_OK) {
// exception thrown
return;
}
// Note: we want to access the Java Logger instance
// across multiple method calls, so we create a global ref
assert(jlogger != nullptr);
m_jLogger = env->NewGlobalRef(jlogger);
if(m_jLogger == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
m_jLogMethodId = LoggerJni::getLogMethodId(env);
if(m_jLogMethodId == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return;
}
jobject jdebug_level = InfoLogLevelJni::DEBUG_LEVEL(env);
assert(jdebug_level != nullptr);
if(jdebug_level == nullptr) {
// exception thrown: NoSuchFieldError, ExceptionInInitializerError
// or OutOfMemoryError
return;
}
m_jdebug_level = env->NewGlobalRef(jdebug_level);
if(m_jdebug_level == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
jobject jinfo_level = InfoLogLevelJni::INFO_LEVEL(env);
assert(jinfo_level != nullptr);
if(jinfo_level == nullptr) {
// exception thrown: NoSuchFieldError, ExceptionInInitializerError
// or OutOfMemoryError
return;
}
m_jinfo_level = env->NewGlobalRef(jinfo_level);
if(m_jinfo_level == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
jobject jwarn_level = InfoLogLevelJni::WARN_LEVEL(env);
assert(jwarn_level != nullptr);
if(jwarn_level == nullptr) {
// exception thrown: NoSuchFieldError, ExceptionInInitializerError
// or OutOfMemoryError
return;
}
m_jwarn_level = env->NewGlobalRef(jwarn_level);
if(m_jwarn_level == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
jobject jerror_level = InfoLogLevelJni::ERROR_LEVEL(env);
assert(jerror_level != nullptr);
if(jerror_level == nullptr) {
// exception thrown: NoSuchFieldError, ExceptionInInitializerError
// or OutOfMemoryError
return;
}
m_jerror_level = env->NewGlobalRef(jerror_level);
if(m_jerror_level == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
jobject jfatal_level = InfoLogLevelJni::FATAL_LEVEL(env);
assert(jfatal_level != nullptr);
if(jfatal_level == nullptr) {
// exception thrown: NoSuchFieldError, ExceptionInInitializerError
// or OutOfMemoryError
return;
}
m_jfatal_level = env->NewGlobalRef(jfatal_level);
if(m_jfatal_level == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
jobject jheader_level = InfoLogLevelJni::HEADER_LEVEL(env);
assert(jheader_level != nullptr);
if(jheader_level == nullptr) {
// exception thrown: NoSuchFieldError, ExceptionInInitializerError
// or OutOfMemoryError
return;
}
m_jheader_level = env->NewGlobalRef(jheader_level);
}
/**
* Get JNIEnv for current native thread
*/
JNIEnv* LoggerJniCallback::getJniEnv() const {
JNIEnv *env;
jint rs __attribute__((unused)) =
m_jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);
assert(rs == JNI_OK);
return env;
if(m_jheader_level == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
}
void LoggerJniCallback::Logv(const char* format, va_list ap) {
......@@ -94,69 +147,96 @@ void LoggerJniCallback::Logv(const InfoLogLevel log_level,
break;
}
// We try twice: the first time with a fixed-size stack allocated buffer,
// and the second time with a much larger dynamically allocated buffer.
char buffer[500];
for (int iter = 0; iter < 2; iter++) {
char* base;
int bufsize;
if (iter == 0) {
bufsize = sizeof(buffer);
base = buffer;
} else {
bufsize = 30000;
base = new char[bufsize];
}
char* p = base;
char* limit = base + bufsize;
// Print the message
if (p < limit) {
va_list backup_ap;
va_copy(backup_ap, ap);
p += vsnprintf(p, limit - p, format, backup_ap);
va_end(backup_ap);
}
// Truncate to available space if necessary
if (p >= limit) {
if (iter == 0) {
continue; // Try again with larger buffer
} else {
p = limit - 1;
}
}
assert(p < limit);
*p++ = '\0';
JNIEnv* env = getJniEnv();
assert(format != nullptr);
assert(ap != nullptr);
const std::unique_ptr<char[]> msg = format_str(format, ap);
// pass java string to callback handler
env->CallVoidMethod(
m_jLogger,
m_jLogMethodId,
jlog_level,
env->NewStringUTF(base));
// pass msg to java callback handler
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
if (base != buffer) {
delete[] base;
jstring jmsg = env->NewStringUTF(msg.get());
if(jmsg == nullptr) {
// unable to construct string
if(env->ExceptionCheck()) {
env->ExceptionDescribe(); // print out exception to stderr
}
break;
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
if(env->ExceptionCheck()) {
// exception thrown: OutOfMemoryError
env->ExceptionDescribe(); // print out exception to stderr
env->DeleteLocalRef(jmsg);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
env->CallVoidMethod(m_jLogger, m_jLogMethodId, jlog_level, jmsg);
if(env->ExceptionCheck()) {
// exception thrown
env->ExceptionDescribe(); // print out exception to stderr
env->DeleteLocalRef(jmsg);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
return;
}
m_jvm->DetachCurrentThread();
env->DeleteLocalRef(jmsg);
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
}
std::unique_ptr<char[]> LoggerJniCallback::format_str(const char* format, va_list ap) const {
va_list ap_copy;
va_copy(ap_copy, ap);
const size_t required = vsnprintf(nullptr, 0, format, ap_copy) + 1; // Extra space for '\0'
va_end(ap_copy);
std::unique_ptr<char[]> buf(new char[required]);
va_copy(ap_copy, ap);
vsnprintf(buf.get(), required, format, ap_copy);
va_end(ap_copy);
return buf;
}
LoggerJniCallback::~LoggerJniCallback() {
JNIEnv* env = getJniEnv();
env->DeleteGlobalRef(m_jLogger);
jboolean attached_thread = JNI_FALSE;
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
assert(env != nullptr);
if(m_jLogger != nullptr) {
env->DeleteGlobalRef(m_jLogger);
}
if(m_jdebug_level != nullptr) {
env->DeleteGlobalRef(m_jdebug_level);
}
if(m_jinfo_level != nullptr) {
env->DeleteGlobalRef(m_jinfo_level);
}
if(m_jwarn_level != nullptr) {
env->DeleteGlobalRef(m_jwarn_level);
}
if(m_jerror_level != nullptr) {
env->DeleteGlobalRef(m_jerror_level);
}
if(m_jfatal_level != nullptr) {
env->DeleteGlobalRef(m_jfatal_level);
}
env->DeleteGlobalRef(m_jdebug_level);
env->DeleteGlobalRef(m_jinfo_level);
env->DeleteGlobalRef(m_jwarn_level);
env->DeleteGlobalRef(m_jerror_level);
env->DeleteGlobalRef(m_jfatal_level);
env->DeleteGlobalRef(m_jheader_level);
if(m_jheader_level != nullptr) {
env->DeleteGlobalRef(m_jheader_level);
}
m_jvm->DetachCurrentThread();
JniUtil::releaseJniEnv(m_jvm, attached_thread);
}
} // namespace rocksdb
......@@ -168,15 +248,14 @@ LoggerJniCallback::~LoggerJniCallback() {
*/
jlong Java_org_rocksdb_Logger_createNewLoggerOptions(
JNIEnv* env, jobject jobj, jlong joptions) {
rocksdb::LoggerJniCallback* c =
new rocksdb::LoggerJniCallback(env, jobj);
auto* sptr_logger = new std::shared_ptr<rocksdb::LoggerJniCallback>(
new rocksdb::LoggerJniCallback(env, jobj));
// set log level
c->SetInfoLogLevel(reinterpret_cast<rocksdb::Options*>
(joptions)->info_log_level);
std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback =
new std::shared_ptr<rocksdb::LoggerJniCallback>;
*pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c);
return reinterpret_cast<jlong>(pLoggerJniCallback);
auto* options = reinterpret_cast<rocksdb::Options*>(joptions);
sptr_logger->get()->SetInfoLogLevel(options->info_log_level);
return reinterpret_cast<jlong>(sptr_logger);
}
/*
......@@ -186,15 +265,14 @@ jlong Java_org_rocksdb_Logger_createNewLoggerOptions(
*/
jlong Java_org_rocksdb_Logger_createNewLoggerDbOptions(
JNIEnv* env, jobject jobj, jlong jdb_options) {
rocksdb::LoggerJniCallback* c =
new rocksdb::LoggerJniCallback(env, jobj);
auto* sptr_logger = new std::shared_ptr<rocksdb::LoggerJniCallback>(
new rocksdb::LoggerJniCallback(env, jobj));
// set log level
c->SetInfoLogLevel(reinterpret_cast<rocksdb::DBOptions*>
(jdb_options)->info_log_level);
std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback =
new std::shared_ptr<rocksdb::LoggerJniCallback>;
*pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c);
return reinterpret_cast<jlong>(pLoggerJniCallback);
auto* db_options = reinterpret_cast<rocksdb::DBOptions*>(jdb_options);
sptr_logger->get()->SetInfoLogLevel(db_options->info_log_level);
return reinterpret_cast<jlong>(sptr_logger);
}
/*
......@@ -204,9 +282,10 @@ jlong Java_org_rocksdb_Logger_createNewLoggerDbOptions(
*/
void Java_org_rocksdb_Logger_setInfoLogLevel(
JNIEnv* env, jobject jobj, jlong jhandle, jbyte jlog_level) {
std::shared_ptr<rocksdb::LoggerJniCallback> *handle =
auto* handle =
reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback> *>(jhandle);
(*handle)->SetInfoLogLevel(static_cast<rocksdb::InfoLogLevel>(jlog_level));
handle->get()->
SetInfoLogLevel(static_cast<rocksdb::InfoLogLevel>(jlog_level));
}
/*
......@@ -216,9 +295,9 @@ void Java_org_rocksdb_Logger_setInfoLogLevel(
*/
jbyte Java_org_rocksdb_Logger_infoLogLevel(
JNIEnv* env, jobject jobj, jlong jhandle) {
std::shared_ptr<rocksdb::LoggerJniCallback> *handle =
auto* handle =
reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback> *>(jhandle);
return static_cast<jbyte>((*handle)->GetInfoLogLevel());
return static_cast<jbyte>(handle->get()->GetInfoLogLevel());
}
/*
......@@ -228,7 +307,7 @@ jbyte Java_org_rocksdb_Logger_infoLogLevel(
*/
void Java_org_rocksdb_Logger_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) {
std::shared_ptr<rocksdb::LoggerJniCallback> *handle =
auto* handle =
reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback> *>(jhandle);
handle->reset();
delete handle; // delete std::shared_ptr
}
......@@ -10,6 +10,7 @@
#define JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_
#include <jni.h>
#include <memory>
#include <string>
#include "port/port.h"
#include "rocksdb/env.h"
......@@ -32,8 +33,6 @@ namespace rocksdb {
virtual void Logv(const InfoLogLevel log_level,
const char* format, va_list ap);
protected:
JNIEnv* getJniEnv() const;
private:
JavaVM* m_jvm;
jobject m_jLogger;
......@@ -44,6 +43,7 @@ namespace rocksdb {
jobject m_jerror_level;
jobject m_jfatal_level;
jobject m_jheader_level;
std::unique_ptr<char[]> format_str(const char* format, va_list ap) const;
};
} // namespace rocksdb
......
......@@ -25,13 +25,24 @@
/*
* Class: org_rocksdb_StringAppendOperator
* Method: newMergeOperatorHandle
* Method: newSharedStringAppendOperator
* Signature: ()J
*/
jlong Java_org_rocksdb_StringAppendOperator_newMergeOperatorHandleImpl
(JNIEnv* env, jobject jobj) {
std::shared_ptr<rocksdb::MergeOperator> *op =
new std::shared_ptr<rocksdb::MergeOperator>();
*op = rocksdb::MergeOperators::CreateFromStringId("stringappend");
return reinterpret_cast<jlong>(op);
jlong Java_org_rocksdb_StringAppendOperator_newSharedStringAppendOperator
(JNIEnv* env, jclass jclazz) {
auto* sptr_string_append_op = new std::shared_ptr<rocksdb::MergeOperator>(
rocksdb::MergeOperators::CreateFromStringId("stringappend"));
return reinterpret_cast<jlong>(sptr_string_append_op);
}
/*
* Class: org_rocksdb_StringAppendOperator
* Method: disposeInternal
* Signature: (J)V
*/
void Java_org_rocksdb_StringAppendOperator_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) {
auto* sptr_string_append_op =
reinterpret_cast<std::shared_ptr<rocksdb::MergeOperator>* >(jhandle);
delete sptr_string_append_op; // delete std::shared_ptr
}
此差异已折叠。
此差异已折叠。
......@@ -6,24 +6,9 @@
// This file implements the "bridge" between Java and C++ for RateLimiter.
#include "rocksjni/portal.h"
#include "include/org_rocksdb_GenericRateLimiterConfig.h"
#include "include/org_rocksdb_RateLimiter.h"
#include "rocksdb/rate_limiter.h"
/*
* Class: org_rocksdb_GenericRateLimiterConfig
* Method: newRateLimiterHandle
* Signature: (JJI)J
*/
jlong Java_org_rocksdb_GenericRateLimiterConfig_newRateLimiterHandle(
JNIEnv* env, jobject jobj, jlong jrate_bytes_per_second,
jlong jrefill_period_micros, jint jfairness) {
return reinterpret_cast<jlong>(rocksdb::NewGenericRateLimiter(
static_cast<int64_t>(jrate_bytes_per_second),
static_cast<int64_t>(jrefill_period_micros),
static_cast<int32_t>(jfairness)));
}
/*
* Class: org_rocksdb_RateLimiter
* Method: newRateLimiterHandle
......@@ -32,16 +17,13 @@ jlong Java_org_rocksdb_GenericRateLimiterConfig_newRateLimiterHandle(
jlong Java_org_rocksdb_RateLimiter_newRateLimiterHandle(
JNIEnv* env, jclass jclazz, jlong jrate_bytes_per_second,
jlong jrefill_period_micros, jint jfairness) {
auto* rate_limiter = rocksdb::NewGenericRateLimiter(
static_cast<int64_t>(jrate_bytes_per_second),
static_cast<int64_t>(jrefill_period_micros),
static_cast<int32_t>(jfairness));
auto * sptr_rate_limiter =
new std::shared_ptr<rocksdb::RateLimiter>(rocksdb::NewGenericRateLimiter(
static_cast<int64_t>(jrate_bytes_per_second),
static_cast<int64_t>(jrefill_period_micros),
static_cast<int32_t>(jfairness)));
std::shared_ptr<rocksdb::RateLimiter> *ptr_sptr_rate_limiter =
new std::shared_ptr<rocksdb::RateLimiter>;
*ptr_sptr_rate_limiter = std::shared_ptr<rocksdb::RateLimiter>(rate_limiter);
return reinterpret_cast<jlong>(ptr_sptr_rate_limiter);
return reinterpret_cast<jlong>(sptr_rate_limiter);
}
/*
......@@ -51,10 +33,9 @@ jlong Java_org_rocksdb_RateLimiter_newRateLimiterHandle(
*/
void Java_org_rocksdb_RateLimiter_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) {
std::shared_ptr<rocksdb::RateLimiter> *handle =
auto* handle =
reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(jhandle);
handle->reset();
delete handle;
delete handle; // delete std::shared_ptr
}
/*
......@@ -65,8 +46,8 @@ void Java_org_rocksdb_RateLimiter_disposeInternal(
void Java_org_rocksdb_RateLimiter_setBytesPerSecond(
JNIEnv* env, jobject jobj, jlong handle,
jlong jbytes_per_second) {
reinterpret_cast<rocksdb::RateLimiter*>(
handle)->SetBytesPerSecond(jbytes_per_second);
reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(handle)->get()->
SetBytesPerSecond(jbytes_per_second);
}
/*
......@@ -77,9 +58,8 @@ void Java_org_rocksdb_RateLimiter_setBytesPerSecond(
void Java_org_rocksdb_RateLimiter_request(
JNIEnv* env, jobject jobj, jlong handle,
jlong jbytes) {
reinterpret_cast<rocksdb::RateLimiter*>(
handle)->Request(jbytes,
rocksdb::Env::IO_TOTAL);
reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(handle)->get()->
Request(jbytes, rocksdb::Env::IO_TOTAL);
}
/*
......@@ -88,10 +68,9 @@ void Java_org_rocksdb_RateLimiter_request(
* Signature: (J)J
*/
jlong Java_org_rocksdb_RateLimiter_getSingleBurstBytes(
JNIEnv* env, jobject jobj, jlong handle,
jlong jbytes) {
return reinterpret_cast<rocksdb::RateLimiter*>(
handle)->GetSingleBurstBytes();
JNIEnv* env, jobject jobj, jlong handle) {
return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(handle)->
get()->GetSingleBurstBytes();
}
/*
......@@ -100,10 +79,9 @@ jlong Java_org_rocksdb_RateLimiter_getSingleBurstBytes(
* Signature: (J)J
*/
jlong Java_org_rocksdb_RateLimiter_getTotalBytesThrough(
JNIEnv* env, jobject jobj, jlong handle,
jlong jbytes) {
return reinterpret_cast<rocksdb::RateLimiter*>(
handle)->GetTotalBytesThrough();
JNIEnv* env, jobject jobj, jlong handle) {
return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(handle)->
get()->GetTotalBytesThrough();
}
/*
......@@ -112,8 +90,7 @@ jlong Java_org_rocksdb_RateLimiter_getTotalBytesThrough(
* Signature: (J)J
*/
jlong Java_org_rocksdb_RateLimiter_getTotalRequests(
JNIEnv* env, jobject jobj, jlong handle,
jlong jbytes) {
return reinterpret_cast<rocksdb::RateLimiter*>(
handle)->GetTotalRequests();
JNIEnv* env, jobject jobj, jlong handle) {
return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(handle)->
get()->GetTotalRequests();
}
......@@ -22,7 +22,7 @@
*/
jlong Java_org_rocksdb_RestoreOptions_newRestoreOptions(JNIEnv* env,
jclass jcls, jboolean keep_log_files) {
auto ropt = new rocksdb::RestoreOptions(keep_log_files);
auto* ropt = new rocksdb::RestoreOptions(keep_log_files);
return reinterpret_cast<jlong>(ropt);
}
......@@ -33,7 +33,7 @@ jlong Java_org_rocksdb_RestoreOptions_newRestoreOptions(JNIEnv* env,
*/
void Java_org_rocksdb_RestoreOptions_disposeInternal(JNIEnv* env, jobject jobj,
jlong jhandle) {
auto ropt = reinterpret_cast<rocksdb::RestoreOptions*>(jhandle);
auto* ropt = reinterpret_cast<rocksdb::RestoreOptions*>(jhandle);
assert(ropt);
delete ropt;
}
此差异已折叠。
此差异已折叠。
......@@ -42,7 +42,11 @@ jlong Java_org_rocksdb_SstFileWriter_newSstFileWriter(JNIEnv *env, jclass jcls,
*/
void Java_org_rocksdb_SstFileWriter_open(JNIEnv *env, jobject jobj,
jlong jhandle, jstring jfile_path) {
const char *file_path = env->GetStringUTFChars(jfile_path, NULL);
const char *file_path = env->GetStringUTFChars(jfile_path, nullptr);
if(file_path == nullptr) {
// exception thrown: OutOfMemoryError
return;
}
rocksdb::Status s =
reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Open(file_path);
env->ReleaseStringUTFChars(jfile_path, file_path);
......@@ -62,8 +66,9 @@ void Java_org_rocksdb_SstFileWriter_add(JNIEnv *env, jobject jobj,
jlong jvalue_handle) {
auto *key_slice = reinterpret_cast<rocksdb::Slice *>(jkey_handle);
auto *value_slice = reinterpret_cast<rocksdb::Slice *>(jvalue_handle);
rocksdb::Status s = reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Add(
*key_slice, *value_slice);
rocksdb::Status s =
reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Add(*key_slice,
*value_slice);
if (!s.ok()) {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
......
......@@ -21,9 +21,8 @@
*/
jlong Java_org_rocksdb_Statistics_getTickerCount0(
JNIEnv* env, jobject jobj, jint tickerType, jlong handle) {
auto st = reinterpret_cast<rocksdb::Statistics*>(handle);
auto* st = reinterpret_cast<rocksdb::Statistics*>(handle);
assert(st != nullptr);
return st->getTickerCount(static_cast<rocksdb::Tickers>(tickerType));
}
......@@ -34,17 +33,28 @@ jlong Java_org_rocksdb_Statistics_getTickerCount0(
*/
jobject Java_org_rocksdb_Statistics_getHistogramData0(
JNIEnv* env, jobject jobj, jint histogramType, jlong handle) {
auto st = reinterpret_cast<rocksdb::Statistics*>(handle);
auto* st = reinterpret_cast<rocksdb::Statistics*>(handle);
assert(st != nullptr);
rocksdb::HistogramData data;
st->histogramData(static_cast<rocksdb::Histograms>(histogramType),
&data);
// Don't reuse class pointer
jclass jclazz = env->FindClass("org/rocksdb/HistogramData");
jclass jclazz = rocksdb::HistogramDataJni::getJClass(env);
if(jclazz == nullptr) {
// exception occurred accessing class
return nullptr;
}
jmethodID mid = rocksdb::HistogramDataJni::getConstructorMethodId(
env, jclazz);
return env->NewObject(jclazz, mid, data.median, data.percentile95,
data.percentile99, data.average, data.standard_deviation);
env);
if(mid == nullptr) {
// exception occurred accessing method
return nullptr;
}
return env->NewObject(
jclazz,
mid, data.median, data.percentile95,data.percentile99, data.average,
data.standard_deviation);
}
......@@ -67,12 +67,5 @@ jobject Java_org_rocksdb_TransactionLogIterator_getBatch(
JNIEnv* env, jobject jobj, jlong handle) {
rocksdb::BatchResult batch_result =
reinterpret_cast<rocksdb::TransactionLogIterator*>(handle)->GetBatch();
jclass jclazz = env->FindClass(
"org/rocksdb/TransactionLogIterator$BatchResult");
assert(jclazz != nullptr);
jmethodID mid = env->GetMethodID(
jclazz, "<init>", "(Lorg/rocksdb/TransactionLogIterator;JJ)V");
assert(mid != nullptr);
return env->NewObject(jclazz, mid, jobj,
batch_result.sequence, batch_result.writeBatchPtr.release());
return rocksdb::BatchResultJni::construct(env, batch_result);
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册