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
This commit is contained in:
parent
be3e5568be
commit
c6d464a9da
@ -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';
|
||||
assert(format != nullptr);
|
||||
assert(ap != nullptr);
|
||||
const std::unique_ptr<char[]> msg = format_str(format, ap);
|
||||
|
||||
JNIEnv* env = getJniEnv();
|
||||
// pass msg to java callback handler
|
||||
jboolean attached_thread = JNI_FALSE;
|
||||
JNIEnv* env = JniUtil::getJniEnv(m_jvm, &attached_thread);
|
||||
assert(env != nullptr);
|
||||
|
||||
// pass java string to callback handler
|
||||
env->CallVoidMethod(
|
||||
m_jLogger,
|
||||
m_jLogMethodId,
|
||||
jlog_level,
|
||||
env->NewStringUTF(base));
|
||||
|
||||
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;
|
||||
}
|
||||
m_jvm->DetachCurrentThread();
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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_jLogger != nullptr) {
|
||||
env->DeleteGlobalRef(m_jLogger);
|
||||
}
|
||||
|
||||
m_jvm->DetachCurrentThread();
|
||||
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);
|
||||
}
|
||||
|
||||
if(m_jheader_level != nullptr) {
|
||||
env->DeleteGlobalRef(m_jheader_level);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
* Signature: ()J
|
||||
*/
|
||||
jlong Java_org_rocksdb_Options_newOptions__(JNIEnv* env, jclass jcls) {
|
||||
rocksdb::Options* op = new rocksdb::Options();
|
||||
auto* op = new rocksdb::Options();
|
||||
return reinterpret_cast<jlong>(op);
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ jlong Java_org_rocksdb_Options_newOptions__JJ(JNIEnv* env, jclass jcls,
|
||||
auto* dbOpt = reinterpret_cast<const rocksdb::DBOptions*>(jdboptions);
|
||||
auto* cfOpt = reinterpret_cast<const rocksdb::ColumnFamilyOptions*>(
|
||||
jcfoptions);
|
||||
rocksdb::Options* op = new rocksdb::Options(*dbOpt, *cfOpt);
|
||||
auto* op = new rocksdb::Options(*dbOpt, *cfOpt);
|
||||
return reinterpret_cast<jlong>(op);
|
||||
}
|
||||
|
||||
@ -64,7 +64,9 @@ jlong Java_org_rocksdb_Options_newOptions__JJ(JNIEnv* env, jclass jcls,
|
||||
*/
|
||||
void Java_org_rocksdb_Options_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::Options*>(handle);
|
||||
auto* op = reinterpret_cast<rocksdb::Options*>(handle);
|
||||
assert(op != nullptr);
|
||||
delete op;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -157,10 +159,16 @@ void Java_org_rocksdb_Options_setComparatorHandle__JJ(
|
||||
*/
|
||||
void Java_org_rocksdb_Options_setMergeOperatorName(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jstring jop_name) {
|
||||
auto options = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
const char* op_name = env->GetStringUTFChars(jop_name, 0);
|
||||
const char* op_name = env->GetStringUTFChars(jop_name, nullptr);
|
||||
if(op_name == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
|
||||
auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
options->merge_operator = rocksdb::MergeOperators::CreateFromStringId(
|
||||
op_name);
|
||||
|
||||
env->ReleaseStringUTFChars(jop_name, op_name);
|
||||
}
|
||||
|
||||
@ -231,7 +239,7 @@ void Java_org_rocksdb_Options_createStatistics(
|
||||
*/
|
||||
jlong Java_org_rocksdb_Options_statisticsPtr(
|
||||
JNIEnv* env, jobject jobj, jlong jOptHandle) {
|
||||
auto st = reinterpret_cast<rocksdb::Options*>(jOptHandle)->statistics.get();
|
||||
auto* st = reinterpret_cast<rocksdb::Options*>(jOptHandle)->statistics.get();
|
||||
return reinterpret_cast<jlong>(st);
|
||||
}
|
||||
|
||||
@ -381,7 +389,11 @@ jstring Java_org_rocksdb_Options_dbLogDir(
|
||||
*/
|
||||
void Java_org_rocksdb_Options_setDbLogDir(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jstring jdb_log_dir) {
|
||||
const char* log_dir = env->GetStringUTFChars(jdb_log_dir, 0);
|
||||
const char* log_dir = env->GetStringUTFChars(jdb_log_dir, nullptr);
|
||||
if(log_dir == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<rocksdb::Options*>(jhandle)->db_log_dir.assign(log_dir);
|
||||
env->ReleaseStringUTFChars(jdb_log_dir, log_dir);
|
||||
}
|
||||
@ -404,7 +416,11 @@ jstring Java_org_rocksdb_Options_walDir(
|
||||
*/
|
||||
void Java_org_rocksdb_Options_setWalDir(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jstring jwal_dir) {
|
||||
const char* wal_dir = env->GetStringUTFChars(jwal_dir, 0);
|
||||
const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
|
||||
if(wal_dir == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<rocksdb::Options*>(jhandle)->wal_dir.assign(wal_dir);
|
||||
env->ReleaseStringUTFChars(jwal_dir, wal_dir);
|
||||
}
|
||||
@ -494,8 +510,7 @@ void Java_org_rocksdb_Options_setMaxSubcompactions(
|
||||
*/
|
||||
jint Java_org_rocksdb_Options_maxSubcompactions(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
return reinterpret_cast<rocksdb::Options*>(jhandle)
|
||||
->max_subcompactions;
|
||||
return reinterpret_cast<rocksdb::Options*>(jhandle)->max_subcompactions;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -641,7 +656,7 @@ jlong Java_org_rocksdb_Options_maxManifestFileSize(
|
||||
*/
|
||||
jstring Java_org_rocksdb_Options_memTableFactoryName(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
auto opt = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
rocksdb::MemTableRepFactory* tf = opt->memtable_factory.get();
|
||||
|
||||
// Should never be nullptr.
|
||||
@ -677,17 +692,6 @@ void Java_org_rocksdb_Options_setMemTableFactory(
|
||||
reinterpret_cast<rocksdb::MemTableRepFactory*>(jfactory_handle));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Options
|
||||
* Method: setOldRateLimiter
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_Options_setOldRateLimiter(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jlong jrate_limiter_handle) {
|
||||
reinterpret_cast<rocksdb::Options*>(jhandle)->rate_limiter.reset(
|
||||
reinterpret_cast<rocksdb::RateLimiter*>(jrate_limiter_handle));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Options
|
||||
* Method: setRateLimiter
|
||||
@ -1144,7 +1148,7 @@ jlong Java_org_rocksdb_Options_writeThreadSlowYieldUsec(
|
||||
*/
|
||||
jstring Java_org_rocksdb_Options_tableFactoryName(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
auto opt = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
rocksdb::TableFactory* tf = opt->table_factory.get();
|
||||
|
||||
// Should never be nullptr.
|
||||
@ -1224,46 +1228,78 @@ jbyte Java_org_rocksdb_Options_compressionType(
|
||||
return reinterpret_cast<rocksdb::Options*>(jhandle)->compression;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method to convert a Java list to a CompressionType
|
||||
* vector.
|
||||
/**
|
||||
* Helper method to convert a Java byte array of compression levels
|
||||
* to a C++ vector of rocksdb::CompressionType
|
||||
*
|
||||
* @param env A pointer to the Java environment
|
||||
* @param jcompression_levels A reference to a java byte array
|
||||
* where each byte indicates a compression level
|
||||
*
|
||||
* @return A unique_ptr to the vector, or unique_ptr(nullptr) if a JNI exception occurs
|
||||
*/
|
||||
std::vector<rocksdb::CompressionType> rocksdb_compression_vector_helper(
|
||||
JNIEnv* env, jbyteArray jcompressionLevels) {
|
||||
std::vector<rocksdb::CompressionType> compressionLevels;
|
||||
|
||||
jsize len = env->GetArrayLength(jcompressionLevels);
|
||||
jbyte* jcompressionLevel = env->GetByteArrayElements(jcompressionLevels,
|
||||
NULL);
|
||||
for(int i = 0; i < len; i++) {
|
||||
jbyte jcl;
|
||||
jcl = jcompressionLevel[i];
|
||||
compressionLevels.push_back(static_cast<rocksdb::CompressionType>(jcl));
|
||||
std::unique_ptr<std::vector<rocksdb::CompressionType>> rocksdb_compression_vector_helper(
|
||||
JNIEnv* env, jbyteArray jcompression_levels) {
|
||||
jsize len = env->GetArrayLength(jcompression_levels);
|
||||
jbyte* jcompression_level =
|
||||
env->GetByteArrayElements(jcompression_levels, nullptr);
|
||||
if(jcompression_level == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return std::unique_ptr<std::vector<rocksdb::CompressionType>>();
|
||||
}
|
||||
env->ReleaseByteArrayElements(jcompressionLevels, jcompressionLevel,
|
||||
|
||||
auto* compression_levels = new std::vector<rocksdb::CompressionType>();
|
||||
std::unique_ptr<std::vector<rocksdb::CompressionType>> uptr_compression_levels(compression_levels);
|
||||
|
||||
for(jsize i = 0; i < len; i++) {
|
||||
jbyte jcl = jcompression_level[i];
|
||||
compression_levels->push_back(static_cast<rocksdb::CompressionType>(jcl));
|
||||
}
|
||||
|
||||
env->ReleaseByteArrayElements(jcompression_levels, jcompression_level,
|
||||
JNI_ABORT);
|
||||
|
||||
return compressionLevels;
|
||||
return uptr_compression_levels;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method to convert a CompressionType vector to a Java
|
||||
* List.
|
||||
/**
|
||||
* Helper method to convert a C++ vector of rocksdb::CompressionType
|
||||
* to a Java byte array of compression levels
|
||||
*
|
||||
* @param env A pointer to the Java environment
|
||||
* @param jcompression_levels A reference to a java byte array
|
||||
* where each byte indicates a compression level
|
||||
*
|
||||
* @return A jbytearray or nullptr if an exception occurs
|
||||
*/
|
||||
jbyteArray rocksdb_compression_list_helper(JNIEnv* env,
|
||||
std::vector<rocksdb::CompressionType> compressionLevels) {
|
||||
std::unique_ptr<jbyte[]> jbuf =
|
||||
std::unique_ptr<jbyte[]>(new jbyte[compressionLevels.size()]);
|
||||
for (std::vector<rocksdb::CompressionType>::size_type i = 0;
|
||||
i != compressionLevels.size(); i++) {
|
||||
jbuf[i] = compressionLevels[i];
|
||||
std::vector<rocksdb::CompressionType> compression_levels) {
|
||||
const size_t len = compression_levels.size();
|
||||
jbyte* jbuf = new jbyte[len];
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
jbuf[i] = compression_levels[i];
|
||||
}
|
||||
|
||||
// insert in java array
|
||||
jbyteArray jcompressionLevels = env->NewByteArray(
|
||||
static_cast<jsize>(compressionLevels.size()));
|
||||
env->SetByteArrayRegion(jcompressionLevels, 0,
|
||||
static_cast<jsize>(compressionLevels.size()), jbuf.get());
|
||||
return jcompressionLevels;
|
||||
jbyteArray jcompression_levels = env->NewByteArray(static_cast<jsize>(len));
|
||||
if(jcompression_levels == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
delete [] jbuf;
|
||||
return nullptr;
|
||||
}
|
||||
env->SetByteArrayRegion(jcompression_levels, 0, static_cast<jsize>(len),
|
||||
jbuf);
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(jcompression_levels);
|
||||
delete [] jbuf;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
delete [] jbuf;
|
||||
|
||||
return jcompression_levels;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1274,10 +1310,14 @@ jbyteArray rocksdb_compression_list_helper(JNIEnv* env,
|
||||
void Java_org_rocksdb_Options_setCompressionPerLevel(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle,
|
||||
jbyteArray jcompressionLevels) {
|
||||
auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
std::vector<rocksdb::CompressionType> compressionLevels =
|
||||
auto uptr_compression_levels =
|
||||
rocksdb_compression_vector_helper(env, jcompressionLevels);
|
||||
options->compression_per_level = compressionLevels;
|
||||
if(!uptr_compression_levels) {
|
||||
// exception occurred
|
||||
return;
|
||||
}
|
||||
auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
options->compression_per_level = *(uptr_compression_levels.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1946,7 +1986,6 @@ jlong Java_org_rocksdb_Options_memtableHugePageSize(
|
||||
void Java_org_rocksdb_Options_setMemtableHugePageSize(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle,
|
||||
jlong jmemtable_huge_page_size) {
|
||||
|
||||
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(
|
||||
jmemtable_huge_page_size);
|
||||
if (s.ok()) {
|
||||
@ -2083,8 +2122,9 @@ void Java_org_rocksdb_Options_setLevel0StopWritesTrigger(
|
||||
*/
|
||||
jintArray Java_org_rocksdb_Options_maxBytesForLevelMultiplierAdditional(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
auto mbflma = reinterpret_cast<rocksdb::Options*>(
|
||||
jhandle)->max_bytes_for_level_multiplier_additional;
|
||||
auto mbflma =
|
||||
reinterpret_cast<rocksdb::Options*>(jhandle)->
|
||||
max_bytes_for_level_multiplier_additional;
|
||||
|
||||
const size_t size = mbflma.size();
|
||||
|
||||
@ -2095,7 +2135,19 @@ jintArray Java_org_rocksdb_Options_maxBytesForLevelMultiplierAdditional(
|
||||
|
||||
jsize jlen = static_cast<jsize>(size);
|
||||
jintArray result = env->NewIntArray(jlen);
|
||||
if(result == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
delete [] additionals;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
env->SetIntArrayRegion(result, 0, jlen, additionals);
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(result);
|
||||
delete [] additionals;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
delete [] additionals;
|
||||
|
||||
@ -2112,12 +2164,20 @@ void Java_org_rocksdb_Options_setMaxBytesForLevelMultiplierAdditional(
|
||||
jintArray jmax_bytes_for_level_multiplier_additional) {
|
||||
jsize len = env->GetArrayLength(jmax_bytes_for_level_multiplier_additional);
|
||||
jint *additionals =
|
||||
env->GetIntArrayElements(jmax_bytes_for_level_multiplier_additional, 0);
|
||||
env->GetIntArrayElements(jmax_bytes_for_level_multiplier_additional, nullptr);
|
||||
if(additionals == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
|
||||
auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
|
||||
opt->max_bytes_for_level_multiplier_additional.clear();
|
||||
for (jsize i = 0; i < len; i++) {
|
||||
opt->max_bytes_for_level_multiplier_additional.push_back(static_cast<int32_t>(additionals[i]));
|
||||
}
|
||||
|
||||
env->ReleaseIntArrayElements(jmax_bytes_for_level_multiplier_additional,
|
||||
additionals, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2153,7 +2213,7 @@ void Java_org_rocksdb_Options_setParanoidFileChecks(
|
||||
*/
|
||||
jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions(
|
||||
JNIEnv* env, jclass jcls) {
|
||||
rocksdb::ColumnFamilyOptions* op = new rocksdb::ColumnFamilyOptions();
|
||||
auto* op = new rocksdb::ColumnFamilyOptions();
|
||||
return reinterpret_cast<jlong>(op);
|
||||
}
|
||||
|
||||
@ -2164,14 +2224,20 @@ jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions(
|
||||
*/
|
||||
jlong Java_org_rocksdb_ColumnFamilyOptions_getColumnFamilyOptionsFromProps(
|
||||
JNIEnv* env, jclass jclazz, jstring jopt_string) {
|
||||
jlong ret_value = 0;
|
||||
rocksdb::ColumnFamilyOptions* cf_options =
|
||||
new rocksdb::ColumnFamilyOptions();
|
||||
const char* opt_string = env->GetStringUTFChars(jopt_string, 0);
|
||||
const char* opt_string = env->GetStringUTFChars(jopt_string, nullptr);
|
||||
if(opt_string == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto* cf_options = new rocksdb::ColumnFamilyOptions();
|
||||
rocksdb::Status status = rocksdb::GetColumnFamilyOptionsFromString(
|
||||
rocksdb::ColumnFamilyOptions(), opt_string, cf_options);
|
||||
|
||||
env->ReleaseStringUTFChars(jopt_string, opt_string);
|
||||
|
||||
// Check if ColumnFamilyOptions creation was possible.
|
||||
jlong ret_value = 0;
|
||||
if (status.ok()) {
|
||||
ret_value = reinterpret_cast<jlong>(cf_options);
|
||||
} else {
|
||||
@ -2189,7 +2255,9 @@ jlong Java_org_rocksdb_ColumnFamilyOptions_getColumnFamilyOptionsFromProps(
|
||||
*/
|
||||
void Java_org_rocksdb_ColumnFamilyOptions_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::ColumnFamilyOptions*>(handle);
|
||||
auto* cfo = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(handle);
|
||||
assert(cfo != nullptr);
|
||||
delete cfo;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2265,10 +2333,15 @@ void Java_org_rocksdb_ColumnFamilyOptions_setComparatorHandle__JJ(
|
||||
*/
|
||||
void Java_org_rocksdb_ColumnFamilyOptions_setMergeOperatorName(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jstring jop_name) {
|
||||
auto options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
const char* op_name = env->GetStringUTFChars(jop_name, 0);
|
||||
options->merge_operator = rocksdb::MergeOperators::CreateFromStringId(
|
||||
op_name);
|
||||
auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
const char* op_name = env->GetStringUTFChars(jop_name, nullptr);
|
||||
if(op_name == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
|
||||
options->merge_operator =
|
||||
rocksdb::MergeOperators::CreateFromStringId(op_name);
|
||||
env->ReleaseStringUTFChars(jop_name, op_name);
|
||||
}
|
||||
|
||||
@ -2364,7 +2437,7 @@ void Java_org_rocksdb_ColumnFamilyOptions_setMemTableFactory(
|
||||
*/
|
||||
jstring Java_org_rocksdb_ColumnFamilyOptions_memTableFactoryName(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
auto opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
auto* opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
rocksdb::MemTableRepFactory* tf = opt->memtable_factory.get();
|
||||
|
||||
// Should never be nullptr.
|
||||
@ -2418,7 +2491,7 @@ void Java_org_rocksdb_ColumnFamilyOptions_setTableFactory(
|
||||
*/
|
||||
jstring Java_org_rocksdb_ColumnFamilyOptions_tableFactoryName(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
auto opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
auto* opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
rocksdb::TableFactory* tf = opt->table_factory.get();
|
||||
|
||||
// Should never be nullptr.
|
||||
@ -2508,9 +2581,13 @@ void Java_org_rocksdb_ColumnFamilyOptions_setCompressionPerLevel(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle,
|
||||
jbyteArray jcompressionLevels) {
|
||||
auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
std::vector<rocksdb::CompressionType> compressionLevels =
|
||||
auto uptr_compression_levels =
|
||||
rocksdb_compression_vector_helper(env, jcompressionLevels);
|
||||
options->compression_per_level = compressionLevels;
|
||||
if(!uptr_compression_levels) {
|
||||
// exception occurred
|
||||
return;
|
||||
}
|
||||
options->compression_per_level = *(uptr_compression_levels.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2520,9 +2597,9 @@ void Java_org_rocksdb_ColumnFamilyOptions_setCompressionPerLevel(
|
||||
*/
|
||||
jbyteArray Java_org_rocksdb_ColumnFamilyOptions_compressionPerLevel(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
return rocksdb_compression_list_helper(env,
|
||||
options->compression_per_level);
|
||||
cf_options->compression_per_level);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2668,7 +2745,7 @@ void Java_org_rocksdb_ColumnFamilyOptions_setLevelZeroStopWritesTrigger(
|
||||
*/
|
||||
jint Java_org_rocksdb_ColumnFamilyOptions_maxMemCompactionLevel(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
return 0;
|
||||
return 0; // deprecated and intentionally not implemented, see the Java code
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2677,7 +2754,9 @@ jint Java_org_rocksdb_ColumnFamilyOptions_maxMemCompactionLevel(
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
void Java_org_rocksdb_ColumnFamilyOptions_setMaxMemCompactionLevel(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jint jmax_mem_compaction_level) {}
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jint jmax_mem_compaction_level) {
|
||||
// deprecated and intentionally not implemented, see the Java code
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_ColumnFamilyOptions
|
||||
@ -3308,9 +3387,19 @@ jintArray Java_org_rocksdb_ColumnFamilyOptions_maxBytesForLevelMultiplierAdditio
|
||||
}
|
||||
|
||||
jsize jlen = static_cast<jsize>(size);
|
||||
jintArray result;
|
||||
result = env->NewIntArray(jlen);
|
||||
jintArray result = env->NewIntArray(jlen);
|
||||
if(result == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
delete [] additionals;
|
||||
return nullptr;
|
||||
}
|
||||
env->SetIntArrayRegion(result, 0, jlen, additionals);
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(result);
|
||||
delete [] additionals;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
delete [] additionals;
|
||||
|
||||
@ -3328,11 +3417,19 @@ void Java_org_rocksdb_ColumnFamilyOptions_setMaxBytesForLevelMultiplierAdditiona
|
||||
jsize len = env->GetArrayLength(jmax_bytes_for_level_multiplier_additional);
|
||||
jint *additionals =
|
||||
env->GetIntArrayElements(jmax_bytes_for_level_multiplier_additional, 0);
|
||||
if(additionals == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
|
||||
auto* cf_opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
|
||||
cf_opt->max_bytes_for_level_multiplier_additional.clear();
|
||||
for (jsize i = 0; i < len; i++) {
|
||||
cf_opt->max_bytes_for_level_multiplier_additional.push_back(static_cast<int32_t>(additionals[i]));
|
||||
}
|
||||
|
||||
env->ReleaseIntArrayElements(jmax_bytes_for_level_multiplier_additional,
|
||||
additionals, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3369,7 +3466,7 @@ void Java_org_rocksdb_ColumnFamilyOptions_setParanoidFileChecks(
|
||||
*/
|
||||
jlong Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env,
|
||||
jclass jcls) {
|
||||
rocksdb::DBOptions* dbop = new rocksdb::DBOptions();
|
||||
auto* dbop = new rocksdb::DBOptions();
|
||||
return reinterpret_cast<jlong>(dbop);
|
||||
}
|
||||
|
||||
@ -3380,14 +3477,20 @@ jlong Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env,
|
||||
*/
|
||||
jlong Java_org_rocksdb_DBOptions_getDBOptionsFromProps(
|
||||
JNIEnv* env, jclass jclazz, jstring jopt_string) {
|
||||
jlong ret_value = 0;
|
||||
rocksdb::DBOptions* db_options =
|
||||
new rocksdb::DBOptions();
|
||||
const char* opt_string = env->GetStringUTFChars(jopt_string, 0);
|
||||
const char* opt_string = env->GetStringUTFChars(jopt_string, nullptr);
|
||||
if(opt_string == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto* db_options = new rocksdb::DBOptions();
|
||||
rocksdb::Status status = rocksdb::GetDBOptionsFromString(
|
||||
rocksdb::DBOptions(), opt_string, db_options);
|
||||
|
||||
env->ReleaseStringUTFChars(jopt_string, opt_string);
|
||||
|
||||
// Check if DBOptions creation was possible.
|
||||
jlong ret_value = 0;
|
||||
if (status.ok()) {
|
||||
ret_value = reinterpret_cast<jlong>(db_options);
|
||||
} else {
|
||||
@ -3405,7 +3508,9 @@ jlong Java_org_rocksdb_DBOptions_getDBOptionsFromProps(
|
||||
*/
|
||||
void Java_org_rocksdb_DBOptions_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::DBOptions*>(handle);
|
||||
auto* dbo = reinterpret_cast<rocksdb::DBOptions*>(handle);
|
||||
assert(dbo != nullptr);
|
||||
delete dbo;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3505,17 +3610,6 @@ jboolean Java_org_rocksdb_DBOptions_paranoidChecks(
|
||||
return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->paranoid_checks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DBOptions
|
||||
* Method: setOldRateLimiter
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_DBOptions_setOldRateLimiter(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jlong jrate_limiter_handle) {
|
||||
reinterpret_cast<rocksdb::DBOptions*>(jhandle)->rate_limiter.reset(
|
||||
reinterpret_cast<rocksdb::RateLimiter*>(jrate_limiter_handle));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DBOptions
|
||||
* Method: setRateLimiter
|
||||
@ -3626,7 +3720,7 @@ void Java_org_rocksdb_DBOptions_createStatistics(
|
||||
*/
|
||||
jlong Java_org_rocksdb_DBOptions_statisticsPtr(
|
||||
JNIEnv* env, jobject jobj, jlong jOptHandle) {
|
||||
auto st = reinterpret_cast<rocksdb::DBOptions*>(jOptHandle)->
|
||||
auto* st = reinterpret_cast<rocksdb::DBOptions*>(jOptHandle)->
|
||||
statistics.get();
|
||||
return reinterpret_cast<jlong>(st);
|
||||
}
|
||||
@ -3659,7 +3753,12 @@ jboolean Java_org_rocksdb_DBOptions_useFsync(
|
||||
*/
|
||||
void Java_org_rocksdb_DBOptions_setDbLogDir(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jstring jdb_log_dir) {
|
||||
const char* log_dir = env->GetStringUTFChars(jdb_log_dir, 0);
|
||||
const char* log_dir = env->GetStringUTFChars(jdb_log_dir, nullptr);
|
||||
if(log_dir == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
|
||||
reinterpret_cast<rocksdb::DBOptions*>(jhandle)->db_log_dir.assign(log_dir);
|
||||
env->ReleaseStringUTFChars(jdb_log_dir, log_dir);
|
||||
}
|
||||
@ -4307,19 +4406,17 @@ jlong Java_org_rocksdb_DBOptions_writeThreadSlowYieldUsec(
|
||||
}
|
||||
|
||||
void Java_org_rocksdb_DBOptions_setDelayedWriteRate(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jlong delay_write_rate){
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jlong delay_write_rate) {
|
||||
reinterpret_cast<rocksdb::DBOptions*>(jhandle)->delayed_write_rate =
|
||||
static_cast<int64_t>(delay_write_rate);
|
||||
}
|
||||
|
||||
reinterpret_cast<rocksdb::DBOptions*>(jhandle)->
|
||||
delayed_write_rate = static_cast<int64_t>(delay_write_rate);
|
||||
jlong Java_org_rocksdb_DBOptions_delayedWriteRate(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->
|
||||
delayed_write_rate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
jlong Java_org_rocksdb_DBOptions_delayedWriteRate(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle){
|
||||
|
||||
return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->
|
||||
delayed_write_rate;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::WriteOptions
|
||||
|
||||
@ -4330,7 +4427,7 @@ void Java_org_rocksdb_DBOptions_setDelayedWriteRate(
|
||||
*/
|
||||
jlong Java_org_rocksdb_WriteOptions_newWriteOptions(
|
||||
JNIEnv* env, jclass jcls) {
|
||||
rocksdb::WriteOptions* op = new rocksdb::WriteOptions();
|
||||
auto* op = new rocksdb::WriteOptions();
|
||||
return reinterpret_cast<jlong>(op);
|
||||
}
|
||||
|
||||
@ -4341,7 +4438,8 @@ jlong Java_org_rocksdb_WriteOptions_newWriteOptions(
|
||||
*/
|
||||
void Java_org_rocksdb_WriteOptions_disposeInternal(
|
||||
JNIEnv* env, jobject jwrite_options, jlong jhandle) {
|
||||
auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle);
|
||||
auto* write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle);
|
||||
assert(write_options != nullptr);
|
||||
delete write_options;
|
||||
}
|
||||
|
||||
@ -4395,8 +4493,8 @@ jboolean Java_org_rocksdb_WriteOptions_disableWAL(
|
||||
*/
|
||||
jlong Java_org_rocksdb_ReadOptions_newReadOptions(
|
||||
JNIEnv* env, jclass jcls) {
|
||||
auto read_opt = new rocksdb::ReadOptions();
|
||||
return reinterpret_cast<jlong>(read_opt);
|
||||
auto* read_options = new rocksdb::ReadOptions();
|
||||
return reinterpret_cast<jlong>(read_options);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4406,7 +4504,9 @@ jlong Java_org_rocksdb_ReadOptions_newReadOptions(
|
||||
*/
|
||||
void Java_org_rocksdb_ReadOptions_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
delete reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
|
||||
auto* read_options = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
|
||||
assert(read_options != nullptr);
|
||||
delete read_options;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4613,7 +4713,7 @@ void Java_org_rocksdb_ReadOptions_setReadTier(
|
||||
*/
|
||||
jlong Java_org_rocksdb_ComparatorOptions_newComparatorOptions(
|
||||
JNIEnv* env, jclass jcls) {
|
||||
auto comparator_opt = new rocksdb::ComparatorJniCallbackOptions();
|
||||
auto* comparator_opt = new rocksdb::ComparatorJniCallbackOptions();
|
||||
return reinterpret_cast<jlong>(comparator_opt);
|
||||
}
|
||||
|
||||
@ -4646,7 +4746,10 @@ void Java_org_rocksdb_ComparatorOptions_setUseAdaptiveMutex(
|
||||
*/
|
||||
void Java_org_rocksdb_ComparatorOptions_disposeInternal(
|
||||
JNIEnv * env, jobject jobj, jlong jhandle) {
|
||||
delete reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle);
|
||||
auto* comparator_opt =
|
||||
reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle);
|
||||
assert(comparator_opt != nullptr);
|
||||
delete comparator_opt;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@ -4659,7 +4762,7 @@ void Java_org_rocksdb_ComparatorOptions_disposeInternal(
|
||||
*/
|
||||
jlong Java_org_rocksdb_FlushOptions_newFlushOptions(
|
||||
JNIEnv* env, jclass jcls) {
|
||||
auto flush_opt = new rocksdb::FlushOptions();
|
||||
auto* flush_opt = new rocksdb::FlushOptions();
|
||||
return reinterpret_cast<jlong>(flush_opt);
|
||||
}
|
||||
|
||||
@ -4692,5 +4795,7 @@ jboolean Java_org_rocksdb_FlushOptions_waitForFlush(
|
||||
*/
|
||||
void Java_org_rocksdb_FlushOptions_disposeInternal(
|
||||
JNIEnv * env, jobject jobj, jlong jhandle) {
|
||||
delete reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
|
||||
auto* flush_opt = reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
|
||||
assert(flush_opt != nullptr);
|
||||
delete flush_opt;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,8 +26,17 @@
|
||||
*/
|
||||
jlong Java_org_rocksdb_AbstractSlice_createNewSliceFromString(
|
||||
JNIEnv * env, jclass jcls, jstring jstr) {
|
||||
const auto* str = env->GetStringUTFChars(jstr, NULL);
|
||||
const auto* str = env->GetStringUTFChars(jstr, nullptr);
|
||||
if(str == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
|
||||
const size_t len = strlen(str);
|
||||
|
||||
// NOTE: buf will be deleted in the
|
||||
// Java_org_rocksdb_Slice_disposeInternalBuf or
|
||||
// or Java_org_rocksdb_DirectSlice_disposeInternalBuf methods
|
||||
char* buf = new char[len + 1];
|
||||
memcpy(buf, str, len);
|
||||
buf[len] = 0;
|
||||
@ -118,13 +127,18 @@ void Java_org_rocksdb_AbstractSlice_disposeInternal(
|
||||
*/
|
||||
jlong Java_org_rocksdb_Slice_createNewSlice0(
|
||||
JNIEnv * env, jclass jcls, jbyteArray data, jint offset) {
|
||||
|
||||
const jsize dataSize = env->GetArrayLength(data);
|
||||
const int len = dataSize - offset;
|
||||
jbyte* ptrData = new jbyte[len];
|
||||
env->GetByteArrayRegion(data, offset, len, ptrData);
|
||||
|
||||
const auto* slice = new rocksdb::Slice((const char*)ptrData, len);
|
||||
// NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf method
|
||||
jbyte* buf = new jbyte[len];
|
||||
env->GetByteArrayRegion(data, offset, len, buf);
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto* slice = new rocksdb::Slice((const char*)buf, len);
|
||||
return reinterpret_cast<jlong>(slice);
|
||||
}
|
||||
|
||||
@ -135,16 +149,17 @@ jlong Java_org_rocksdb_Slice_createNewSlice0(
|
||||
*/
|
||||
jlong Java_org_rocksdb_Slice_createNewSlice1(
|
||||
JNIEnv * env, jclass jcls, jbyteArray data) {
|
||||
|
||||
jbyte* ptrData = env->GetByteArrayElements(data, nullptr);
|
||||
if(ptrData == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
const int len = env->GetArrayLength(data) + 1;
|
||||
|
||||
jboolean isCopy;
|
||||
jbyte* ptrData = env->GetByteArrayElements(data, &isCopy);
|
||||
|
||||
// NOTE: buf will be deleted in the org.rocksdb.Slice#dispose method
|
||||
// NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf method
|
||||
char* buf = new char[len];
|
||||
memcpy(buf, ptrData, len - 1);
|
||||
buf[len-1]='\0';
|
||||
buf[len-1] = '\0';
|
||||
|
||||
const auto* slice =
|
||||
new rocksdb::Slice(buf, len - 1);
|
||||
@ -162,22 +177,61 @@ jlong Java_org_rocksdb_Slice_createNewSlice1(
|
||||
jbyteArray Java_org_rocksdb_Slice_data0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
|
||||
const int len = static_cast<int>(slice->size());
|
||||
const jsize len = static_cast<jsize>(slice->size());
|
||||
const jbyteArray data = env->NewByteArray(len);
|
||||
if(data == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
env->SetByteArrayRegion(data, 0, len,
|
||||
reinterpret_cast<const jbyte*>(slice->data()));
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Slice
|
||||
* Method: clear0
|
||||
* Signature: (JZJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_Slice_clear0(
|
||||
JNIEnv * env, jobject jobj, jlong handle, jboolean shouldRelease,
|
||||
jlong internalBufferOffset) {
|
||||
auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
|
||||
if(shouldRelease == JNI_TRUE) {
|
||||
const char* buf = slice->data_ - internalBufferOffset;
|
||||
delete [] buf;
|
||||
}
|
||||
slice->clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Slice
|
||||
* Method: removePrefix0
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
void Java_org_rocksdb_Slice_removePrefix0(
|
||||
JNIEnv * env, jobject jobj, jlong handle, jint length) {
|
||||
auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
|
||||
slice->remove_prefix(length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Slice
|
||||
* Method: disposeInternalBuf
|
||||
* Signature: (J)V
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_Slice_disposeInternalBuf(
|
||||
JNIEnv * env, jobject jobj, jlong handle) {
|
||||
JNIEnv * env, jobject jobj, jlong handle, jlong internalBufferOffset) {
|
||||
const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
|
||||
delete [] slice->data_;
|
||||
const char* buf = slice->data_ - internalBufferOffset;
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
@ -191,8 +245,19 @@ void Java_org_rocksdb_Slice_disposeInternalBuf(
|
||||
*/
|
||||
jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0(
|
||||
JNIEnv* env, jclass jcls, jobject data, jint length) {
|
||||
assert(data != nullptr);
|
||||
void* data_addr = env->GetDirectBufferAddress(data);
|
||||
if(data_addr == nullptr) {
|
||||
// error: memory region is undefined, given object is not a direct
|
||||
// java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
|
||||
rocksdb::IllegalArgumentExceptionJni::ThrowNew(env,
|
||||
rocksdb::Status::InvalidArgument(
|
||||
"Could not access DirectBuffer"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto* ptrData =
|
||||
reinterpret_cast<char*>(env->GetDirectBufferAddress(data));
|
||||
reinterpret_cast<char*>(data_addr);
|
||||
const auto* slice = new rocksdb::Slice(ptrData, length);
|
||||
return reinterpret_cast<jlong>(slice);
|
||||
}
|
||||
@ -204,8 +269,17 @@ jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0(
|
||||
*/
|
||||
jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1(
|
||||
JNIEnv* env, jclass jcls, jobject data) {
|
||||
const auto* ptrData =
|
||||
reinterpret_cast<char*>(env->GetDirectBufferAddress(data));
|
||||
void* data_addr = env->GetDirectBufferAddress(data);
|
||||
if(data_addr == nullptr) {
|
||||
// error: memory region is undefined, given object is not a direct
|
||||
// java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
|
||||
rocksdb::IllegalArgumentExceptionJni::ThrowNew(env,
|
||||
rocksdb::Status::InvalidArgument(
|
||||
"Could not access DirectBuffer"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto* ptrData = reinterpret_cast<char*>(data_addr);
|
||||
const auto* slice = new rocksdb::Slice(ptrData);
|
||||
return reinterpret_cast<jlong>(slice);
|
||||
}
|
||||
@ -236,12 +310,16 @@ jbyte Java_org_rocksdb_DirectSlice_get0(
|
||||
/*
|
||||
* Class: org_rocksdb_DirectSlice
|
||||
* Method: clear0
|
||||
* Signature: (J)V
|
||||
* Signature: (JZJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_DirectSlice_clear0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
JNIEnv* env, jobject jobj, jlong handle,
|
||||
jboolean shouldRelease, jlong internalBufferOffset) {
|
||||
auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
|
||||
delete [] slice->data_;
|
||||
if(shouldRelease == JNI_TRUE) {
|
||||
const char* buf = slice->data_ - internalBufferOffset;
|
||||
delete [] buf;
|
||||
}
|
||||
slice->clear();
|
||||
}
|
||||
|
||||
@ -256,4 +334,16 @@ void Java_org_rocksdb_DirectSlice_removePrefix0(
|
||||
slice->remove_prefix(length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DirectSlice
|
||||
* Method: disposeInternalBuf
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_DirectSlice_disposeInternalBuf(
|
||||
JNIEnv* env, jobject jobj, jlong handle, jlong internalBufferOffset) {
|
||||
const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
|
||||
const char* buf = slice->data_ - internalBufferOffset;
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -26,9 +26,14 @@
|
||||
jlong Java_org_rocksdb_TtlDB_open(JNIEnv* env,
|
||||
jclass jcls, jlong joptions_handle, jstring jdb_path,
|
||||
jint jttl, jboolean jread_only) {
|
||||
const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
|
||||
if(db_path == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto* opt = reinterpret_cast<rocksdb::Options*>(joptions_handle);
|
||||
rocksdb::DBWithTTL* db = nullptr;
|
||||
const char* db_path = env->GetStringUTFChars(jdb_path, 0);
|
||||
rocksdb::Status s = rocksdb::DBWithTTL::Open(*opt, db_path, &db,
|
||||
jttl, jread_only);
|
||||
env->ReleaseStringUTFChars(jdb_path, db_path);
|
||||
@ -53,49 +58,69 @@ jlongArray
|
||||
JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path,
|
||||
jobjectArray jcolumn_names, jlongArray jcolumn_options,
|
||||
jintArray jttls, jboolean jread_only) {
|
||||
auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
|
||||
const char* db_path = env->GetStringUTFChars(jdb_path, NULL);
|
||||
const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
|
||||
if(db_path == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
|
||||
const jsize len_cols = env->GetArrayLength(jcolumn_names);
|
||||
jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr);
|
||||
if(jco == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
env->ReleaseStringUTFChars(jdb_path, db_path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
|
||||
jboolean has_exception = JNI_FALSE;
|
||||
rocksdb::JniUtil::byteStrings<std::string>(
|
||||
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);
|
||||
|
||||
jsize len_cols = env->GetArrayLength(jcolumn_names);
|
||||
jlong* jco = env->GetLongArrayElements(jcolumn_options, NULL);
|
||||
for(int i = 0; i < len_cols; i++) {
|
||||
jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
|
||||
jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
|
||||
jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, NULL);
|
||||
const int jcf_name_len = env->GetArrayLength(jcn_ba);
|
||||
|
||||
//TODO(AR) do I need to make a copy of jco[i] ?
|
||||
|
||||
std::string cf_name (reinterpret_cast<char *>(jcf_name), jcf_name_len);
|
||||
rocksdb::ColumnFamilyOptions* cf_options =
|
||||
reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[i]);
|
||||
column_families.push_back(
|
||||
rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
|
||||
|
||||
env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
|
||||
env->DeleteLocalRef(jcn);
|
||||
}
|
||||
env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
|
||||
|
||||
std::vector<rocksdb::ColumnFamilyHandle*> handles;
|
||||
rocksdb::DBWithTTL* db = nullptr;
|
||||
if(has_exception == JNI_TRUE) {
|
||||
// exception occured
|
||||
env->ReleaseStringUTFChars(jdb_path, db_path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<int32_t> ttl_values;
|
||||
jint* jttlv = env->GetIntArrayElements(jttls, NULL);
|
||||
jsize len_ttls = env->GetArrayLength(jttls);
|
||||
for(int i = 0; i < len_ttls; i++) {
|
||||
jint* jttlv = env->GetIntArrayElements(jttls, nullptr);
|
||||
if(jttlv == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
env->ReleaseStringUTFChars(jdb_path, db_path);
|
||||
return nullptr;
|
||||
}
|
||||
const jsize len_ttls = env->GetArrayLength(jttls);
|
||||
for(jsize i = 0; i < len_ttls; i++) {
|
||||
ttl_values.push_back(jttlv[i]);
|
||||
}
|
||||
env->ReleaseIntArrayElements(jttls, jttlv, JNI_ABORT);
|
||||
|
||||
auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
|
||||
std::vector<rocksdb::ColumnFamilyHandle*> handles;
|
||||
rocksdb::DBWithTTL* db = nullptr;
|
||||
rocksdb::Status s = rocksdb::DBWithTTL::Open(*opt, db_path, column_families,
|
||||
&handles, &db, ttl_values, jread_only);
|
||||
|
||||
// we have now finished with db_path
|
||||
env->ReleaseStringUTFChars(jdb_path, db_path);
|
||||
|
||||
// check if open operation was successful
|
||||
if (s.ok()) {
|
||||
jsize resultsLen = 1 + len_cols; //db handle + column family handles
|
||||
const jsize resultsLen = 1 + len_cols; //db handle + column family handles
|
||||
std::unique_ptr<jlong[]> results =
|
||||
std::unique_ptr<jlong[]>(new jlong[resultsLen]);
|
||||
results[0] = reinterpret_cast<jlong>(db);
|
||||
@ -104,7 +129,18 @@ jlongArray
|
||||
}
|
||||
|
||||
jlongArray jresults = env->NewLongArray(resultsLen);
|
||||
if(jresults == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(jresults);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return jresults;
|
||||
} else {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
@ -120,18 +156,23 @@ jlongArray
|
||||
jlong Java_org_rocksdb_TtlDB_createColumnFamilyWithTtl(
|
||||
JNIEnv* env, jobject jobj, jlong jdb_handle,
|
||||
jbyteArray jcolumn_name, jlong jcolumn_options, jint jttl) {
|
||||
rocksdb::ColumnFamilyHandle* handle;
|
||||
auto* db_handle = reinterpret_cast<rocksdb::DBWithTTL*>(jdb_handle);
|
||||
|
||||
jbyte* cfname = env->GetByteArrayElements(jcolumn_name, 0);
|
||||
const int len = env->GetArrayLength(jcolumn_name);
|
||||
jbyte* cfname = env->GetByteArrayElements(jcolumn_name, nullptr);
|
||||
if(cfname == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return 0;
|
||||
}
|
||||
const jsize len = env->GetArrayLength(jcolumn_name);
|
||||
|
||||
auto* cfOptions =
|
||||
reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcolumn_options);
|
||||
|
||||
auto* db_handle = reinterpret_cast<rocksdb::DBWithTTL*>(jdb_handle);
|
||||
rocksdb::ColumnFamilyHandle* handle;
|
||||
rocksdb::Status s = db_handle->CreateColumnFamilyWithTtl(
|
||||
*cfOptions, std::string(reinterpret_cast<char *>(cfname),
|
||||
len), &handle, jttl);
|
||||
|
||||
env->ReleaseByteArrayElements(jcolumn_name, cfname, 0);
|
||||
|
||||
if (s.ok()) {
|
||||
|
@ -30,8 +30,7 @@
|
||||
*/
|
||||
jlong Java_org_rocksdb_WriteBatch_newWriteBatch(
|
||||
JNIEnv* env, jclass jcls, jint jreserved_bytes) {
|
||||
rocksdb::WriteBatch* wb = new rocksdb::WriteBatch(
|
||||
static_cast<size_t>(jreserved_bytes));
|
||||
auto* wb = new rocksdb::WriteBatch(static_cast<size_t>(jreserved_bytes));
|
||||
return reinterpret_cast<jlong>(wb);
|
||||
}
|
||||
|
||||
@ -244,7 +243,9 @@ void Java_org_rocksdb_WriteBatch_iterate(
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::WriteBatch*>(handle);
|
||||
auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(handle);
|
||||
assert(wb != nullptr);
|
||||
delete wb;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -254,9 +255,8 @@ void Java_org_rocksdb_WriteBatch_disposeInternal(
|
||||
*/
|
||||
jlong Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0(
|
||||
JNIEnv* env, jobject jobj) {
|
||||
const rocksdb::WriteBatchHandlerJniCallback* h =
|
||||
new rocksdb::WriteBatchHandlerJniCallback(env, jobj);
|
||||
return reinterpret_cast<jlong>(h);
|
||||
auto* wbjnic = new rocksdb::WriteBatchHandlerJniCallback(env, jobj);
|
||||
return reinterpret_cast<jlong>(wbjnic);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -266,5 +266,8 @@ jlong Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0(
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_00024Handler_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::WriteBatchHandlerJniCallback*>(handle);
|
||||
auto* wbjnic =
|
||||
reinterpret_cast<rocksdb::WriteBatchHandlerJniCallback*>(handle);
|
||||
assert(wbjnic != nullptr);
|
||||
delete wbjnic;
|
||||
}
|
||||
|
@ -101,8 +101,18 @@ jbyteArray Java_org_rocksdb_WriteBatchTest_getContents(
|
||||
delete mem->Unref();
|
||||
|
||||
jbyteArray jstate = env->NewByteArray(static_cast<jsize>(state.size()));
|
||||
if(jstate == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
env->SetByteArrayRegion(jstate, 0, static_cast<jsize>(state.size()),
|
||||
reinterpret_cast<const jbyte*>(state.c_str()));
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(jstate);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return jstate;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
*/
|
||||
jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__(
|
||||
JNIEnv* env, jclass jcls) {
|
||||
rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex();
|
||||
auto* wbwi = new rocksdb::WriteBatchWithIndex();
|
||||
return reinterpret_cast<jlong>(wbwi);
|
||||
}
|
||||
|
||||
@ -30,9 +30,9 @@ jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__(
|
||||
*/
|
||||
jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z(
|
||||
JNIEnv* env, jclass jcls, jboolean joverwrite_key) {
|
||||
rocksdb::WriteBatchWithIndex* wbwi =
|
||||
auto* wbwi =
|
||||
new rocksdb::WriteBatchWithIndex(rocksdb::BytewiseComparator(), 0,
|
||||
static_cast<bool>(joverwrite_key));
|
||||
static_cast<bool>(joverwrite_key));
|
||||
return reinterpret_cast<jlong>(wbwi);
|
||||
}
|
||||
|
||||
@ -44,10 +44,10 @@ jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z(
|
||||
jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ(
|
||||
JNIEnv* env, jclass jcls, jlong jfallback_index_comparator_handle,
|
||||
jint jreserved_bytes, jboolean joverwrite_key) {
|
||||
rocksdb::WriteBatchWithIndex* wbwi =
|
||||
auto* wbwi =
|
||||
new rocksdb::WriteBatchWithIndex(
|
||||
reinterpret_cast<rocksdb::Comparator*>(jfallback_index_comparator_handle),
|
||||
static_cast<size_t>(jreserved_bytes), static_cast<bool>(joverwrite_key));
|
||||
reinterpret_cast<rocksdb::Comparator*>(jfallback_index_comparator_handle),
|
||||
static_cast<size_t>(jreserved_bytes), static_cast<bool>(joverwrite_key));
|
||||
return reinterpret_cast<jlong>(wbwi);
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ void Java_org_rocksdb_WriteBatchWithIndex_rollbackToSavePoint0(
|
||||
jlong Java_org_rocksdb_WriteBatchWithIndex_iterator0(
|
||||
JNIEnv* env, jobject jobj, jlong jwbwi_handle) {
|
||||
auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
|
||||
rocksdb::WBWIIterator* wbwi_iterator = wbwi->NewIterator();
|
||||
auto* wbwi_iterator = wbwi->NewIterator();
|
||||
return reinterpret_cast<jlong>(wbwi_iterator);
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ jlong Java_org_rocksdb_WriteBatchWithIndex_iterator1(
|
||||
JNIEnv* env, jobject jobj, jlong jwbwi_handle, jlong jcf_handle) {
|
||||
auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
|
||||
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
|
||||
rocksdb::WBWIIterator* wbwi_iterator = wbwi->NewIterator(cf_handle);
|
||||
auto* wbwi_iterator = wbwi->NewIterator(cf_handle);
|
||||
return reinterpret_cast<jlong>(wbwi_iterator);
|
||||
}
|
||||
|
||||
@ -362,6 +362,7 @@ jbyteArray Java_org_rocksdb_WriteBatchWithIndex_getFromBatchAndDB__JJJ_3BIJ(
|
||||
void Java_org_rocksdb_WriteBatchWithIndex_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(handle);
|
||||
assert(wbwi != nullptr);
|
||||
delete wbwi;
|
||||
}
|
||||
|
||||
@ -375,6 +376,7 @@ void Java_org_rocksdb_WriteBatchWithIndex_disposeInternal(
|
||||
void Java_org_rocksdb_WBWIRocksIterator_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
|
||||
assert(it != nullptr);
|
||||
delete it;
|
||||
}
|
||||
|
||||
@ -437,7 +439,12 @@ void Java_org_rocksdb_WBWIRocksIterator_seek0(
|
||||
JNIEnv* env, jobject jobj, jlong handle, jbyteArray jtarget,
|
||||
jint jtarget_len) {
|
||||
auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(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);
|
||||
|
||||
@ -497,26 +504,41 @@ jlongArray Java_org_rocksdb_WBWIRocksIterator_entry1(
|
||||
results[0] = 0x0;
|
||||
}
|
||||
|
||||
//TODO(AR) do we leak buf and value_buf?
|
||||
// key_slice and value_slice will be freed by org.rocksdb.DirectSlice#close
|
||||
|
||||
//set the pointer to the key slice
|
||||
char* buf = new char[we.key.size()];
|
||||
memcpy(buf, we.key.data(), we.key.size());
|
||||
auto* key_slice = new rocksdb::Slice(buf, we.key.size());
|
||||
auto* key_slice = new rocksdb::Slice(we.key.data(), we.key.size());
|
||||
results[1] = reinterpret_cast<jlong>(key_slice);
|
||||
|
||||
//set the pointer to the value slice
|
||||
if (we.type == rocksdb::kDeleteRecord || we.type == rocksdb::kLogDataRecord) {
|
||||
if (we.type == rocksdb::kDeleteRecord
|
||||
|| we.type == rocksdb::kLogDataRecord) {
|
||||
// set native handle of value slice to null if no value available
|
||||
results[2] = 0;
|
||||
} else {
|
||||
char* value_buf = new char[we.value.size()];
|
||||
memcpy(value_buf, we.value.data(), we.value.size());
|
||||
auto* value_slice = new rocksdb::Slice(value_buf, we.value.size());
|
||||
auto* value_slice = new rocksdb::Slice(we.value.data(), we.value.size());
|
||||
results[2] = reinterpret_cast<jlong>(value_slice);
|
||||
}
|
||||
|
||||
jlongArray jresults = env->NewLongArray(3);
|
||||
if(jresults == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
if(results[2] != 0) {
|
||||
auto* value_slice = reinterpret_cast<rocksdb::Slice*>(results[2]);
|
||||
delete value_slice;
|
||||
}
|
||||
delete key_slice;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
env->SetLongArrayRegion(jresults, 0, 3, results);
|
||||
if(env->ExceptionCheck()) {
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
env->DeleteLocalRef(jresults);
|
||||
if(results[2] != 0) {
|
||||
auto* value_slice = reinterpret_cast<rocksdb::Slice*>(results[2]);
|
||||
delete value_slice;
|
||||
}
|
||||
delete key_slice;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return jresults;
|
||||
}
|
||||
|
@ -16,69 +16,202 @@ WriteBatchHandlerJniCallback::WriteBatchHandlerJniCallback(
|
||||
|
||||
// Note: we want to access the Java WriteBatchHandler instance
|
||||
// across multiple method calls, so we create a global ref
|
||||
assert(jWriteBatchHandler != nullptr);
|
||||
m_jWriteBatchHandler = env->NewGlobalRef(jWriteBatchHandler);
|
||||
if(m_jWriteBatchHandler == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return;
|
||||
}
|
||||
|
||||
m_jPutMethodId = WriteBatchHandlerJni::getPutMethodId(env);
|
||||
if(m_jPutMethodId == nullptr) {
|
||||
// exception thrown
|
||||
return;
|
||||
}
|
||||
|
||||
m_jMergeMethodId = WriteBatchHandlerJni::getMergeMethodId(env);
|
||||
if(m_jMergeMethodId == nullptr) {
|
||||
// exception thrown
|
||||
return;
|
||||
}
|
||||
|
||||
m_jDeleteMethodId = WriteBatchHandlerJni::getDeleteMethodId(env);
|
||||
if(m_jDeleteMethodId == nullptr) {
|
||||
// exception thrown
|
||||
return;
|
||||
}
|
||||
|
||||
m_jLogDataMethodId = WriteBatchHandlerJni::getLogDataMethodId(env);
|
||||
if(m_jLogDataMethodId == nullptr) {
|
||||
// exception thrown
|
||||
return;
|
||||
}
|
||||
|
||||
m_jContinueMethodId = WriteBatchHandlerJni::getContinueMethodId(env);
|
||||
if(m_jContinueMethodId == nullptr) {
|
||||
// exception thrown
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBatchHandlerJniCallback::Put(const Slice& key, const Slice& value) {
|
||||
const jbyteArray j_key = sliceToJArray(key);
|
||||
if(j_key == nullptr) {
|
||||
// exception thrown
|
||||
if(m_env->ExceptionCheck()) {
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const jbyteArray j_value = sliceToJArray(value);
|
||||
if(j_value == nullptr) {
|
||||
// exception thrown
|
||||
if(m_env->ExceptionCheck()) {
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->CallVoidMethod(
|
||||
m_jWriteBatchHandler,
|
||||
m_jPutMethodId,
|
||||
j_key,
|
||||
j_value);
|
||||
if(m_env->ExceptionCheck()) {
|
||||
// exception thrown
|
||||
m_env->ExceptionDescribe();
|
||||
if(j_value != nullptr) {
|
||||
m_env->DeleteLocalRef(j_value);
|
||||
}
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->DeleteLocalRef(j_value);
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
if(j_value != nullptr) {
|
||||
m_env->DeleteLocalRef(j_value);
|
||||
}
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBatchHandlerJniCallback::Merge(const Slice& key, const Slice& value) {
|
||||
const jbyteArray j_key = sliceToJArray(key);
|
||||
if(j_key == nullptr) {
|
||||
// exception thrown
|
||||
if(m_env->ExceptionCheck()) {
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const jbyteArray j_value = sliceToJArray(value);
|
||||
if(j_value == nullptr) {
|
||||
// exception thrown
|
||||
if(m_env->ExceptionCheck()) {
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->CallVoidMethod(
|
||||
m_jWriteBatchHandler,
|
||||
m_jMergeMethodId,
|
||||
j_key,
|
||||
j_value);
|
||||
if(m_env->ExceptionCheck()) {
|
||||
// exception thrown
|
||||
m_env->ExceptionDescribe();
|
||||
if(j_value != nullptr) {
|
||||
m_env->DeleteLocalRef(j_value);
|
||||
}
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->DeleteLocalRef(j_value);
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
if(j_value != nullptr) {
|
||||
m_env->DeleteLocalRef(j_value);
|
||||
}
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBatchHandlerJniCallback::Delete(const Slice& key) {
|
||||
const jbyteArray j_key = sliceToJArray(key);
|
||||
if(j_key == nullptr) {
|
||||
// exception thrown
|
||||
if(m_env->ExceptionCheck()) {
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->CallVoidMethod(
|
||||
m_jWriteBatchHandler,
|
||||
m_jDeleteMethodId,
|
||||
j_key);
|
||||
if(m_env->ExceptionCheck()) {
|
||||
// exception thrown
|
||||
m_env->ExceptionDescribe();
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
if(j_key != nullptr) {
|
||||
m_env->DeleteLocalRef(j_key);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBatchHandlerJniCallback::LogData(const Slice& blob) {
|
||||
const jbyteArray j_blob = sliceToJArray(blob);
|
||||
if(j_blob == nullptr) {
|
||||
// exception thrown
|
||||
if(m_env->ExceptionCheck()) {
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->CallVoidMethod(
|
||||
m_jWriteBatchHandler,
|
||||
m_jLogDataMethodId,
|
||||
j_blob);
|
||||
if(m_env->ExceptionCheck()) {
|
||||
// exception thrown
|
||||
m_env->ExceptionDescribe();
|
||||
if(j_blob != nullptr) {
|
||||
m_env->DeleteLocalRef(j_blob);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_env->DeleteLocalRef(j_blob);
|
||||
if(j_blob != nullptr) {
|
||||
m_env->DeleteLocalRef(j_blob);
|
||||
}
|
||||
}
|
||||
|
||||
bool WriteBatchHandlerJniCallback::Continue() {
|
||||
jboolean jContinue = m_env->CallBooleanMethod(
|
||||
m_jWriteBatchHandler,
|
||||
m_jContinueMethodId);
|
||||
if(m_env->ExceptionCheck()) {
|
||||
// exception thrown
|
||||
m_env->ExceptionDescribe();
|
||||
}
|
||||
|
||||
return static_cast<bool>(jContinue == JNI_TRUE);
|
||||
}
|
||||
@ -89,16 +222,36 @@ bool WriteBatchHandlerJniCallback::Continue() {
|
||||
* When calling this function
|
||||
* you must remember to call env->DeleteLocalRef
|
||||
* on the result after you have finished with it
|
||||
*
|
||||
* @param s A Slice to convery to a Java byte array
|
||||
*
|
||||
* @return A reference to a Java byte array, or a nullptr if an
|
||||
* exception occurs
|
||||
*/
|
||||
jbyteArray WriteBatchHandlerJniCallback::sliceToJArray(const Slice& s) {
|
||||
jbyteArray ja = m_env->NewByteArray(static_cast<jsize>(s.size()));
|
||||
if(ja == nullptr) {
|
||||
// exception thrown: OutOfMemoryError
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_env->SetByteArrayRegion(
|
||||
ja, 0, static_cast<jsize>(s.size()),
|
||||
reinterpret_cast<const jbyte*>(s.data()));
|
||||
if(m_env->ExceptionCheck()) {
|
||||
if(ja != nullptr) {
|
||||
m_env->DeleteLocalRef(ja);
|
||||
}
|
||||
// exception thrown: ArrayIndexOutOfBoundsException
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ja;
|
||||
}
|
||||
|
||||
WriteBatchHandlerJniCallback::~WriteBatchHandlerJniCallback() {
|
||||
m_env->DeleteGlobalRef(m_jWriteBatchHandler);
|
||||
if(m_jWriteBatchHandler != nullptr) {
|
||||
m_env->DeleteGlobalRef(m_jWriteBatchHandler);
|
||||
}
|
||||
}
|
||||
} // namespace rocksdb
|
||||
|
@ -13,13 +13,14 @@ public class RocksDBColumnFamilySample {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws RocksDBException {
|
||||
public static void main(final String[] args) throws RocksDBException {
|
||||
if (args.length < 1) {
|
||||
System.out.println(
|
||||
"usage: RocksDBColumnFamilySample db_path");
|
||||
return;
|
||||
System.exit(-1);
|
||||
}
|
||||
String db_path = args[0];
|
||||
|
||||
final String db_path = args[0];
|
||||
|
||||
System.out.println("RocksDBColumnFamilySample");
|
||||
try(final Options options = new Options().setCreateIfMissing(true);
|
||||
@ -54,8 +55,6 @@ public class RocksDBColumnFamilySample {
|
||||
// put and get from non-default column family
|
||||
db.put(columnFamilyHandles.get(0), new WriteOptions(),
|
||||
"key".getBytes(), "value".getBytes());
|
||||
String value = new String(db.get(columnFamilyHandles.get(0),
|
||||
"key".getBytes()));
|
||||
|
||||
// atomic write
|
||||
try (final WriteBatch wb = new WriteBatch()) {
|
||||
|
@ -12,31 +12,31 @@ import java.util.ArrayList;
|
||||
import org.rocksdb.*;
|
||||
import org.rocksdb.util.SizeUnit;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class RocksDBSample {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(final String[] args) {
|
||||
if (args.length < 1) {
|
||||
System.out.println("usage: RocksDBSample db_path");
|
||||
return;
|
||||
System.exit(-1);
|
||||
}
|
||||
String db_path = args[0];
|
||||
String db_path_not_found = db_path + "_not_found";
|
||||
|
||||
final String db_path = args[0];
|
||||
final String db_path_not_found = db_path + "_not_found";
|
||||
|
||||
System.out.println("RocksDBSample");
|
||||
try (final Options options = new Options();
|
||||
final Filter bloomFilter = new BloomFilter(10);
|
||||
final ReadOptions readOptions = new ReadOptions()
|
||||
.setFillCache(false)) {
|
||||
.setFillCache(false);
|
||||
final RateLimiter rateLimiter = new RateLimiter(10000000,10000, 10)) {
|
||||
|
||||
try (final RocksDB db = RocksDB.open(options, db_path_not_found)) {
|
||||
assert (false);
|
||||
} catch (RocksDBException e) {
|
||||
System.out.format("caught the expected exception -- %s\n", e);
|
||||
} catch (final RocksDBException e) {
|
||||
System.out.format("Caught the expected exception -- %s\n", e);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -47,11 +47,11 @@ public class RocksDBSample {
|
||||
.setMaxBackgroundCompactions(10)
|
||||
.setCompressionType(CompressionType.SNAPPY_COMPRESSION)
|
||||
.setCompactionStyle(CompactionStyle.UNIVERSAL);
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assert (false);
|
||||
}
|
||||
|
||||
Statistics stats = options.statisticsPtr();
|
||||
final Statistics stats = options.statisticsPtr();
|
||||
|
||||
assert (options.createIfMissing() == true);
|
||||
assert (options.writeBufferSize() == 8 * SizeUnit.KB);
|
||||
@ -85,9 +85,7 @@ public class RocksDBSample {
|
||||
options.setAllowMmapReads(true);
|
||||
assert (options.tableFactoryName().equals("PlainTable"));
|
||||
|
||||
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000,
|
||||
10000, 10));
|
||||
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000));
|
||||
options.setRateLimiter(rateLimiter);
|
||||
|
||||
final BlockBasedTableConfig table_options = new BlockBasedTableConfig();
|
||||
table_options.setBlockCacheSize(64 * SizeUnit.KB)
|
||||
@ -114,12 +112,14 @@ public class RocksDBSample {
|
||||
|
||||
try (final RocksDB db = RocksDB.open(options, db_path)) {
|
||||
db.put("hello".getBytes(), "world".getBytes());
|
||||
byte[] value = db.get("hello".getBytes());
|
||||
|
||||
final byte[] value = db.get("hello".getBytes());
|
||||
assert ("world".equals(new String(value)));
|
||||
String str = db.getProperty("rocksdb.stats");
|
||||
|
||||
final String str = db.getProperty("rocksdb.stats");
|
||||
assert (str != null && !str.equals(""));
|
||||
} catch (RocksDBException e) {
|
||||
System.out.format("[ERROR] caught the unexpceted exception -- %s\n", e);
|
||||
} catch (final RocksDBException e) {
|
||||
System.out.format("[ERROR] caught the unexpected exception -- %s\n", e);
|
||||
assert (false);
|
||||
}
|
||||
|
||||
@ -174,8 +174,8 @@ public class RocksDBSample {
|
||||
value = db.get(readOptions, "world".getBytes());
|
||||
assert (value == null);
|
||||
|
||||
byte[] testKey = "asdf".getBytes();
|
||||
byte[] testValue =
|
||||
final byte[] testKey = "asdf".getBytes();
|
||||
final byte[] testValue =
|
||||
"asdfghjkl;'?><MNBVCXZQWERTYUIOP{+_)(*&^%$#@".getBytes();
|
||||
db.put(testKey, testValue);
|
||||
byte[] testResult = db.get(testKey);
|
||||
@ -187,8 +187,8 @@ public class RocksDBSample {
|
||||
assert (Arrays.equals(testValue, testResult));
|
||||
assert (new String(testValue).equals(new String(testResult)));
|
||||
|
||||
byte[] insufficientArray = new byte[10];
|
||||
byte[] enoughArray = new byte[50];
|
||||
final byte[] insufficientArray = new byte[10];
|
||||
final byte[] enoughArray = new byte[50];
|
||||
int len;
|
||||
len = db.get(testKey, insufficientArray);
|
||||
assert (len > insufficientArray.length);
|
||||
@ -220,21 +220,21 @@ public class RocksDBSample {
|
||||
}
|
||||
|
||||
try {
|
||||
for (TickerType statsType : TickerType.values()) {
|
||||
for (final TickerType statsType : TickerType.values()) {
|
||||
stats.getTickerCount(statsType);
|
||||
}
|
||||
System.out.println("getTickerCount() passed.");
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println("Failed in call to getTickerCount()");
|
||||
assert (false); //Should never reach here.
|
||||
}
|
||||
|
||||
try {
|
||||
for (HistogramType histogramType : HistogramType.values()) {
|
||||
for (final HistogramType histogramType : HistogramType.values()) {
|
||||
HistogramData data = stats.getHistogramData(histogramType);
|
||||
}
|
||||
System.out.println("getHistogramData() passed.");
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println("Failed in call to getHistogramData()");
|
||||
assert (false); //Should never reach here.
|
||||
}
|
||||
@ -283,16 +283,16 @@ public class RocksDBSample {
|
||||
|
||||
Map<byte[], byte[]> values = db.multiGet(keys);
|
||||
assert (values.size() == keys.size());
|
||||
for (byte[] value1 : values.values()) {
|
||||
for (final byte[] value1 : values.values()) {
|
||||
assert (value1 != null);
|
||||
}
|
||||
|
||||
values = db.multiGet(new ReadOptions(), keys);
|
||||
assert (values.size() == keys.size());
|
||||
for (byte[] value1 : values.values()) {
|
||||
for (final byte[] value1 : values.values()) {
|
||||
assert (value1 != null);
|
||||
}
|
||||
} catch (RocksDBException e) {
|
||||
} catch (final RocksDBException e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,20 @@ public abstract class AbstractSlice<T> extends RocksMutableObject {
|
||||
*/
|
||||
protected abstract T data0(long handle);
|
||||
|
||||
/**
|
||||
* Drops the specified {@code n}
|
||||
* number of bytes from the start
|
||||
* of the backing slice
|
||||
*
|
||||
* @param n The number of bytes to drop
|
||||
*/
|
||||
public abstract void removePrefix(final int n);
|
||||
|
||||
/**
|
||||
* Clears the backing slice
|
||||
*/
|
||||
public abstract void clear();
|
||||
|
||||
/**
|
||||
* Return the length (in bytes) of the data.
|
||||
*
|
||||
|
@ -143,7 +143,7 @@ public class ColumnFamilyOptions extends RocksObject
|
||||
@Override
|
||||
public ColumnFamilyOptions setMergeOperator(
|
||||
final MergeOperator mergeOperator) {
|
||||
setMergeOperator(nativeHandle_, mergeOperator.newMergeOperatorHandle());
|
||||
setMergeOperator(nativeHandle_, mergeOperator.nativeHandle_);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -134,15 +134,6 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
|
||||
return paranoidChecks(nativeHandle_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBOptions setRateLimiterConfig(
|
||||
final RateLimiterConfig config) {
|
||||
assert(isOwningHandle());
|
||||
rateLimiterConfig_ = config;
|
||||
setOldRateLimiter(nativeHandle_, config.newRateLimiterHandle());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBOptions setRateLimiter(final RateLimiter rateLimiter) {
|
||||
assert(isOwningHandle());
|
||||
@ -650,9 +641,6 @@ public long delayedWriteRate(){
|
||||
private native void setParanoidChecks(
|
||||
long handle, boolean paranoidChecks);
|
||||
private native boolean paranoidChecks(long handle);
|
||||
@Deprecated
|
||||
private native void setOldRateLimiter(long handle,
|
||||
long rateLimiterHandle);
|
||||
private native void setRateLimiter(long handle,
|
||||
long rateLimiterHandle);
|
||||
private native void setLogger(long handle,
|
||||
@ -750,6 +738,5 @@ public long delayedWriteRate(){
|
||||
private native long delayedWriteRate(long handle);
|
||||
|
||||
int numShardBits_;
|
||||
RateLimiterConfig rateLimiterConfig_;
|
||||
RateLimiter rateLimiter_;
|
||||
}
|
||||
|
@ -118,18 +118,6 @@ public interface DBOptionsInterface {
|
||||
*/
|
||||
boolean paranoidChecks();
|
||||
|
||||
/**
|
||||
* Use to control write rate of flush and compaction. Flush has higher
|
||||
* priority than compaction. Rate limiting is disabled if nullptr.
|
||||
* Default: nullptr
|
||||
*
|
||||
* @param config rate limiter config.
|
||||
* @return the instance of the current Object.
|
||||
* @deprecated See: {@link #setRateLimiter(RateLimiter)}.
|
||||
*/
|
||||
@Deprecated
|
||||
Object setRateLimiterConfig(RateLimiterConfig config);
|
||||
|
||||
/**
|
||||
* Use to control write rate of flush and compaction. Flush has higher
|
||||
* priority than compaction. Rate limiting is disabled if nullptr.
|
||||
|
@ -18,6 +18,13 @@ import java.nio.ByteBuffer;
|
||||
public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
public final static DirectSlice NONE = new DirectSlice();
|
||||
|
||||
/**
|
||||
* Indicates whether we have to free the memory pointed to by the Slice
|
||||
*/
|
||||
private final boolean internalBuffer;
|
||||
private volatile boolean cleared = false;
|
||||
private volatile long internalBufferOffset = 0;
|
||||
|
||||
/**
|
||||
* Called from JNI to construct a new Java DirectSlice
|
||||
* without an underlying C++ object set
|
||||
@ -32,6 +39,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
*/
|
||||
DirectSlice() {
|
||||
super();
|
||||
this.internalBuffer = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,6 +51,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
*/
|
||||
public DirectSlice(final String str) {
|
||||
super(createNewSliceFromString(str));
|
||||
this.internalBuffer = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,6 +64,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
*/
|
||||
public DirectSlice(final ByteBuffer data, final int length) {
|
||||
super(createNewDirectSlice0(ensureDirect(data), length));
|
||||
this.internalBuffer = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,12 +76,13 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
*/
|
||||
public DirectSlice(final ByteBuffer data) {
|
||||
super(createNewDirectSlice1(ensureDirect(data)));
|
||||
this.internalBuffer = false;
|
||||
}
|
||||
|
||||
private static ByteBuffer ensureDirect(final ByteBuffer data) {
|
||||
// TODO(AR) consider throwing a checked exception, as if it's not direct
|
||||
// this can SIGSEGV
|
||||
assert(data.isDirect());
|
||||
if(!data.isDirect()) {
|
||||
throw new IllegalArgumentException("The ByteBuffer must be direct");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -83,26 +94,29 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
*
|
||||
* @return the requested byte
|
||||
*/
|
||||
public byte get(int offset) {
|
||||
public byte get(final int offset) {
|
||||
return get0(getNativeHandle(), offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the backing slice
|
||||
*/
|
||||
@Override
|
||||
public void clear() {
|
||||
clear0(getNativeHandle());
|
||||
clear0(getNativeHandle(), !cleared && internalBuffer, internalBufferOffset);
|
||||
cleared = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the specified {@code n}
|
||||
* number of bytes from the start
|
||||
* of the backing slice
|
||||
*
|
||||
* @param n The number of bytes to drop
|
||||
*/
|
||||
@Override
|
||||
public void removePrefix(final int n) {
|
||||
removePrefix0(getNativeHandle(), n);
|
||||
this.internalBufferOffset += n;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeInternal() {
|
||||
final long nativeHandle = getNativeHandle();
|
||||
if(!cleared && internalBuffer) {
|
||||
disposeInternalBuf(nativeHandle, internalBufferOffset);
|
||||
}
|
||||
disposeInternal(nativeHandle);
|
||||
}
|
||||
|
||||
private native static long createNewDirectSlice0(final ByteBuffer data,
|
||||
@ -110,6 +124,9 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||
private native static long createNewDirectSlice1(final ByteBuffer data);
|
||||
@Override protected final native ByteBuffer data0(long handle);
|
||||
private native byte get0(long handle, int offset);
|
||||
private native void clear0(long handle);
|
||||
private native void clear0(long handle, boolean internalBuffer,
|
||||
long internalBufferOffset);
|
||||
private native void removePrefix0(long handle, int length);
|
||||
private native void disposeInternalBuf(final long handle,
|
||||
long internalBufferOffset);
|
||||
}
|
||||
|
@ -134,15 +134,15 @@ public class EnvOptions extends RocksObject {
|
||||
return writableFileMaxBufferSize(nativeHandle_);
|
||||
}
|
||||
|
||||
public EnvOptions setRateLimiterConfig(final RateLimiterConfig rateLimiterConfig) {
|
||||
this.rateLimiterConfig = rateLimiterConfig;
|
||||
setRateLimiter(nativeHandle_, rateLimiterConfig.newRateLimiterHandle());
|
||||
public EnvOptions setRateLimiter(final RateLimiter rateLimiter) {
|
||||
this.rateLimiter = rateLimiter;
|
||||
setRateLimiter(nativeHandle_, rateLimiter.nativeHandle_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RateLimiterConfig rateLimiterConfig() {
|
||||
public RateLimiter rateLimiter() {
|
||||
assert(isOwningHandle());
|
||||
return rateLimiterConfig;
|
||||
return rateLimiter;
|
||||
}
|
||||
|
||||
private native static long newEnvOptions();
|
||||
@ -203,5 +203,5 @@ public class EnvOptions extends RocksObject {
|
||||
|
||||
private native void setRateLimiter(final long handle, final long rateLimiterHandle);
|
||||
|
||||
private RateLimiterConfig rateLimiterConfig;
|
||||
private RateLimiter rateLimiter;
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* Config for rate limiter, which is used to control write rate of flush and
|
||||
* compaction.
|
||||
*
|
||||
* @see RateLimiterConfig
|
||||
* @deprecated obsolete. See: {@link org.rocksdb.RateLimiter}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class GenericRateLimiterConfig extends RateLimiterConfig {
|
||||
private static final long DEFAULT_REFILL_PERIOD_MICROS = (100 * 1000);
|
||||
private static final int DEFAULT_FAIRNESS = 10;
|
||||
|
||||
/**
|
||||
* GenericRateLimiterConfig constructor
|
||||
*
|
||||
* @param rateBytesPerSecond this is the only parameter you want to set
|
||||
* most of the time. It controls the total write rate of compaction
|
||||
* and flush in bytes per second. Currently, RocksDB does not enforce
|
||||
* rate limit for anything other than flush and compaction, e.g. write to WAL.
|
||||
* @param refillPeriodMicros this controls how often tokens are refilled. For example,
|
||||
* when rate_bytes_per_sec is set to 10MB/s and refill_period_us is set to
|
||||
* 100ms, then 1MB is refilled every 100ms internally. Larger value can lead to
|
||||
* burstier writes while smaller value introduces more CPU overhead.
|
||||
* The default should work for most cases.
|
||||
* @param fairness RateLimiter accepts high-pri requests and low-pri requests.
|
||||
* A low-pri request is usually blocked in favor of hi-pri request. Currently,
|
||||
* RocksDB assigns low-pri to request from compaction and high-pri to request
|
||||
* from flush. Low-pri requests can get blocked if flush requests come in
|
||||
* continuously. This fairness parameter grants low-pri requests permission by
|
||||
* fairness chance even though high-pri requests exist to avoid starvation.
|
||||
* You should be good by leaving it at default 10.
|
||||
*/
|
||||
public GenericRateLimiterConfig(final long rateBytesPerSecond,
|
||||
final long refillPeriodMicros, final int fairness) {
|
||||
rateBytesPerSecond_ = rateBytesPerSecond;
|
||||
refillPeriodMicros_ = refillPeriodMicros;
|
||||
fairness_ = fairness;
|
||||
}
|
||||
|
||||
/**
|
||||
* GenericRateLimiterConfig constructor
|
||||
*
|
||||
* @param rateBytesPerSecond this is the only parameter you want to set
|
||||
* most of the time. It controls the total write rate of compaction
|
||||
* and flush in bytes per second. Currently, RocksDB does not enforce
|
||||
* rate limit for anything other than flush and compaction, e.g. write to WAL.
|
||||
*/
|
||||
public GenericRateLimiterConfig(final long rateBytesPerSecond) {
|
||||
this(rateBytesPerSecond, DEFAULT_REFILL_PERIOD_MICROS, DEFAULT_FAIRNESS);
|
||||
}
|
||||
|
||||
@Override protected long newRateLimiterHandle() {
|
||||
return newRateLimiterHandle(rateBytesPerSecond_, refillPeriodMicros_,
|
||||
fairness_);
|
||||
}
|
||||
|
||||
private native long newRateLimiterHandle(long rateBytesPerSecond,
|
||||
long refillPeriodMicros, int fairness);
|
||||
private final long rateBytesPerSecond_;
|
||||
private final long refillPeriodMicros_;
|
||||
private final int fairness_;
|
||||
}
|
@ -10,6 +10,8 @@ package org.rocksdb;
|
||||
* two merge operands held under the same key in order to obtain a single
|
||||
* value.
|
||||
*/
|
||||
public interface MergeOperator {
|
||||
long newMergeOperatorHandle();
|
||||
public abstract class MergeOperator extends RocksObject {
|
||||
protected MergeOperator(final long nativeHandle) {
|
||||
super(nativeHandle);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ public class MutableColumnFamilyOptions {
|
||||
* For int[] values, each int should be separated by a comma, e.g.
|
||||
*
|
||||
* key1=value1;intArrayKey1=1,2,3
|
||||
*
|
||||
* @param str The string representation of the mutable column family options
|
||||
*
|
||||
* @return A builder for the mutable column family options
|
||||
*/
|
||||
public static MutableColumnFamilyOptionsBuilder parse(final String str) {
|
||||
Objects.requireNonNull(str);
|
||||
|
@ -188,7 +188,7 @@ public class Options extends RocksObject
|
||||
|
||||
@Override
|
||||
public Options setMergeOperator(final MergeOperator mergeOperator) {
|
||||
setMergeOperator(nativeHandle_, mergeOperator.newMergeOperatorHandle());
|
||||
setMergeOperator(nativeHandle_, mergeOperator.nativeHandle_);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -683,13 +683,6 @@ public class Options extends RocksObject
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options setRateLimiterConfig(final RateLimiterConfig config) {
|
||||
rateLimiterConfig_ = config;
|
||||
setOldRateLimiter(nativeHandle_, config.newRateLimiterHandle());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options setRateLimiter(final RateLimiter rateLimiter) {
|
||||
assert(isOwningHandle());
|
||||
@ -1202,9 +1195,6 @@ public class Options extends RocksObject
|
||||
private native void setParanoidChecks(
|
||||
long handle, boolean paranoidChecks);
|
||||
private native boolean paranoidChecks(long handle);
|
||||
@Deprecated
|
||||
private native void setOldRateLimiter(long handle,
|
||||
long rateLimiterHandle);
|
||||
private native void setRateLimiter(long handle,
|
||||
long rateLimiterHandle);
|
||||
private native void setLogger(long handle,
|
||||
@ -1436,7 +1426,6 @@ public class Options extends RocksObject
|
||||
Env env_;
|
||||
MemTableConfig memTableConfig_;
|
||||
TableFormatConfig tableFormatConfig_;
|
||||
RateLimiterConfig rateLimiterConfig_;
|
||||
RateLimiter rateLimiter_;
|
||||
AbstractComparator<? extends AbstractSlice<?>> comparator_;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* Config for rate limiter, which is used to control write rate of flush and
|
||||
* compaction.
|
||||
*
|
||||
* @deprecated obsolete. See: {@link org.rocksdb.RateLimiter}.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class RateLimiterConfig {
|
||||
/**
|
||||
* This function should only be called by
|
||||
* {@link org.rocksdb.DBOptions#setRateLimiter(long, long)}, which will
|
||||
* create a c++ shared-pointer to the c++ {@code RateLimiter} that is associated
|
||||
* with a Java RateLimiterConfig.
|
||||
*
|
||||
* @see org.rocksdb.DBOptions#setRateLimiter(long, long)
|
||||
*
|
||||
* @return native handle address to rate limiter instance.
|
||||
*/
|
||||
abstract protected long newRateLimiterHandle();
|
||||
}
|
@ -520,11 +520,11 @@ public class RocksDB extends RocksObject {
|
||||
* to make this lighter weight is to avoid doing any IOs.
|
||||
*
|
||||
* @param key byte array of a key to search for
|
||||
* @param value StringBuffer instance which is a out parameter if a value is
|
||||
* @param value StringBuilder instance which is a out parameter if a value is
|
||||
* found in block-cache.
|
||||
* @return boolean value indicating if key does not exist or might exist.
|
||||
*/
|
||||
public boolean keyMayExist(final byte[] key, final StringBuffer value) {
|
||||
public boolean keyMayExist(final byte[] key, final StringBuilder value) {
|
||||
return keyMayExist(nativeHandle_, key, 0, key.length, value);
|
||||
}
|
||||
|
||||
@ -537,12 +537,12 @@ public class RocksDB extends RocksObject {
|
||||
*
|
||||
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
|
||||
* @param key byte array of a key to search for
|
||||
* @param value StringBuffer instance which is a out parameter if a value is
|
||||
* @param value StringBuilder instance which is a out parameter if a value is
|
||||
* found in block-cache.
|
||||
* @return boolean value indicating if key does not exist or might exist.
|
||||
*/
|
||||
public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle,
|
||||
final byte[] key, final StringBuffer value) {
|
||||
final byte[] key, final StringBuilder value) {
|
||||
return keyMayExist(nativeHandle_, key, 0, key.length,
|
||||
columnFamilyHandle.nativeHandle_, value);
|
||||
}
|
||||
@ -556,12 +556,12 @@ public class RocksDB extends RocksObject {
|
||||
*
|
||||
* @param readOptions {@link ReadOptions} instance
|
||||
* @param key byte array of a key to search for
|
||||
* @param value StringBuffer instance which is a out parameter if a value is
|
||||
* @param value StringBuilder instance which is a out parameter if a value is
|
||||
* found in block-cache.
|
||||
* @return boolean value indicating if key does not exist or might exist.
|
||||
*/
|
||||
public boolean keyMayExist(final ReadOptions readOptions,
|
||||
final byte[] key, final StringBuffer value) {
|
||||
final byte[] key, final StringBuilder value) {
|
||||
return keyMayExist(nativeHandle_, readOptions.nativeHandle_,
|
||||
key, 0, key.length, value);
|
||||
}
|
||||
@ -576,13 +576,13 @@ public class RocksDB extends RocksObject {
|
||||
* @param readOptions {@link ReadOptions} instance
|
||||
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
|
||||
* @param key byte array of a key to search for
|
||||
* @param value StringBuffer instance which is a out parameter if a value is
|
||||
* @param value StringBuilder instance which is a out parameter if a value is
|
||||
* found in block-cache.
|
||||
* @return boolean value indicating if key does not exist or might exist.
|
||||
*/
|
||||
public boolean keyMayExist(final ReadOptions readOptions,
|
||||
final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
|
||||
final StringBuffer value) {
|
||||
final StringBuilder value) {
|
||||
return keyMayExist(nativeHandle_, readOptions.nativeHandle_,
|
||||
key, 0, key.length, columnFamilyHandle.nativeHandle_,
|
||||
value);
|
||||
@ -685,6 +685,9 @@ public class RocksDB extends RocksObject {
|
||||
columnFamilyHandle.nativeHandle_);
|
||||
}
|
||||
|
||||
// TODO(AR) we should improve the #get() API, returning -1 (RocksDB.NOT_FOUND) is not very nice
|
||||
// when we could communicate better status into, also the C++ code show that -2 could be returned
|
||||
|
||||
/**
|
||||
* Get the value associated with the specified key within column family*
|
||||
* @param key the key to retrieve the value.
|
||||
@ -1917,6 +1920,8 @@ public class RocksDB extends RocksObject {
|
||||
* This function will wait until all currently running background processes
|
||||
* finish. After it returns, no background process will be run until
|
||||
* {@link #continueBackgroundWork()} is called
|
||||
*
|
||||
* @throws RocksDBException If an error occurs when pausing background work
|
||||
*/
|
||||
public void pauseBackgroundWork() throws RocksDBException {
|
||||
pauseBackgroundWork(nativeHandle_);
|
||||
@ -1925,6 +1930,8 @@ public class RocksDB extends RocksObject {
|
||||
/**
|
||||
* Resumes backround work which was suspended by
|
||||
* previously calling {@link #pauseBackgroundWork()}
|
||||
*
|
||||
* @throws RocksDBException If an error occurs when resuming background work
|
||||
*/
|
||||
public void continueBackgroundWork() throws RocksDBException {
|
||||
continueBackgroundWork(nativeHandle_);
|
||||
@ -2182,17 +2189,17 @@ public class RocksDB extends RocksObject {
|
||||
long wbwiHandle) throws RocksDBException;
|
||||
protected native boolean keyMayExist(final long handle, final byte[] key,
|
||||
final int keyOffset, final int keyLength,
|
||||
final StringBuffer stringBuffer);
|
||||
final StringBuilder stringBuilder);
|
||||
protected native boolean keyMayExist(final long handle, final byte[] key,
|
||||
final int keyOffset, final int keyLength, final long cfHandle,
|
||||
final StringBuffer stringBuffer);
|
||||
final StringBuilder stringBuilder);
|
||||
protected native boolean keyMayExist(final long handle,
|
||||
final long optionsHandle, final byte[] key, final int keyOffset,
|
||||
final int keyLength, final StringBuffer stringBuffer);
|
||||
final int keyLength, final StringBuilder stringBuilder);
|
||||
protected native boolean keyMayExist(final long handle,
|
||||
final long optionsHandle, final byte[] key, final int keyOffset,
|
||||
final int keyLength, final long cfHandle,
|
||||
final StringBuffer stringBuffer);
|
||||
final StringBuilder stringBuilder);
|
||||
protected native void merge(long handle, byte[] key, int keyOffset,
|
||||
int keyLength, byte[] value, int valueOffset, int valueLength)
|
||||
throws RocksDBException;
|
||||
|
@ -30,6 +30,24 @@ public abstract class RocksMutableObject extends AbstractNativeReference {
|
||||
this.owningHandle_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the existing handle, and changes the handle to the new handle
|
||||
*
|
||||
* @param newNativeHandle The C++ pointer to the new native object
|
||||
* @param owningNativeHandle true if we own the new native object
|
||||
*/
|
||||
public synchronized void resetNativeHandle(final long newNativeHandle,
|
||||
final boolean owningNativeHandle) {
|
||||
close();
|
||||
setNativeHandle(newNativeHandle, owningNativeHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the handle (C++ pointer) of the underlying C++ native object
|
||||
*
|
||||
* @param nativeHandle The C++ pointer to the native object
|
||||
* @param owningNativeHandle true if we own the native object
|
||||
*/
|
||||
public synchronized void setNativeHandle(final long nativeHandle,
|
||||
final boolean owningNativeHandle) {
|
||||
this.nativeHandle_ = nativeHandle;
|
||||
|
@ -14,6 +14,13 @@ package org.rocksdb;
|
||||
* values consider using {@link org.rocksdb.DirectSlice}</p>
|
||||
*/
|
||||
public class Slice extends AbstractSlice<byte[]> {
|
||||
|
||||
/**
|
||||
* Indicates whether we have to free the memory pointed to by the Slice
|
||||
*/
|
||||
private volatile boolean cleared;
|
||||
private volatile long internalBufferOffset = 0;
|
||||
|
||||
/**
|
||||
* <p>Called from JNI to construct a new Java Slice
|
||||
* without an underlying C++ object set
|
||||
@ -27,6 +34,7 @@ public class Slice extends AbstractSlice<byte[]> {
|
||||
* Slice objects through this, they are not creating underlying C++ Slice
|
||||
* objects, and so there is nothing to free (dispose) from Java.</p>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private Slice() {
|
||||
super();
|
||||
}
|
||||
@ -62,6 +70,18 @@ public class Slice extends AbstractSlice<byte[]> {
|
||||
super(createNewSlice1(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
clear0(getNativeHandle(), !cleared, internalBufferOffset);
|
||||
cleared = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePrefix(final int n) {
|
||||
removePrefix0(getNativeHandle(), n);
|
||||
this.internalBufferOffset += n;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Deletes underlying C++ slice pointer
|
||||
* and any buffered data.</p>
|
||||
@ -74,7 +94,9 @@ public class Slice extends AbstractSlice<byte[]> {
|
||||
@Override
|
||||
protected void disposeInternal() {
|
||||
final long nativeHandle = getNativeHandle();
|
||||
disposeInternalBuf(nativeHandle);
|
||||
if(!cleared) {
|
||||
disposeInternalBuf(nativeHandle, internalBufferOffset);
|
||||
}
|
||||
super.disposeInternal(nativeHandle);
|
||||
}
|
||||
|
||||
@ -82,5 +104,9 @@ public class Slice extends AbstractSlice<byte[]> {
|
||||
private native static long createNewSlice0(final byte[] data,
|
||||
final int length);
|
||||
private native static long createNewSlice1(final byte[] data);
|
||||
private native void disposeInternalBuf(final long handle);
|
||||
private native void clear0(long handle, boolean internalBuffer,
|
||||
long internalBufferOffset);
|
||||
private native void removePrefix0(long handle, int length);
|
||||
private native void disposeInternalBuf(final long handle,
|
||||
long internalBufferOffset);
|
||||
}
|
||||
|
@ -9,9 +9,11 @@ package org.rocksdb;
|
||||
* StringAppendOperator is a merge operator that concatenates
|
||||
* two strings.
|
||||
*/
|
||||
public class StringAppendOperator implements MergeOperator {
|
||||
@Override public long newMergeOperatorHandle() {
|
||||
return newMergeOperatorHandleImpl();
|
||||
public class StringAppendOperator extends MergeOperator {
|
||||
public StringAppendOperator() {
|
||||
super(newSharedStringAppendOperator());
|
||||
}
|
||||
private native long newMergeOperatorHandleImpl();
|
||||
|
||||
private native static long newSharedStringAppendOperator();
|
||||
@Override protected final native void disposeInternal(final long handle);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public class TransactionLogIterator extends RocksObject {
|
||||
* by a TransactionLogIterator containing a sequence
|
||||
* number and a {@link WriteBatch} instance.</p>
|
||||
*/
|
||||
public final class BatchResult {
|
||||
public static final class BatchResult {
|
||||
/**
|
||||
* <p>Constructor of BatchResult class.</p>
|
||||
*
|
||||
|
@ -29,12 +29,11 @@ public class WBWIRocksIterator
|
||||
*/
|
||||
public WriteEntry entry() {
|
||||
assert(isOwningHandle());
|
||||
assert(entry != null);
|
||||
final long ptrs[] = entry1(nativeHandle_);
|
||||
|
||||
entry.type = WriteType.fromId((byte)ptrs[0]);
|
||||
entry.key.setNativeHandle(ptrs[1], true);
|
||||
entry.value.setNativeHandle(ptrs[2], ptrs[2] != 0);
|
||||
entry.key.resetNativeHandle(ptrs[1], ptrs[1] != 0);
|
||||
entry.value.resetNativeHandle(ptrs[2], ptrs[2] != 0);
|
||||
|
||||
return entry;
|
||||
}
|
||||
@ -75,6 +74,12 @@ public class WBWIRocksIterator
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
entry.close();
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an entry returned by
|
||||
* {@link org.rocksdb.WBWIRocksIterator#entry()}
|
||||
@ -84,7 +89,7 @@ public class WBWIRocksIterator
|
||||
* or {@link org.rocksdb.WBWIRocksIterator.WriteType#LOG}
|
||||
* will not have a value.
|
||||
*/
|
||||
public static class WriteEntry {
|
||||
public static class WriteEntry implements AutoCloseable {
|
||||
WriteType type = null;
|
||||
final DirectSlice key;
|
||||
final DirectSlice value;
|
||||
@ -101,7 +106,8 @@ public class WBWIRocksIterator
|
||||
value = new DirectSlice();
|
||||
}
|
||||
|
||||
public WriteEntry(WriteType type, DirectSlice key, DirectSlice value) {
|
||||
public WriteEntry(final WriteType type, final DirectSlice key,
|
||||
final DirectSlice value) {
|
||||
this.type = type;
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
@ -154,7 +160,7 @@ public class WBWIRocksIterator
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(final Object other) {
|
||||
if(other == null) {
|
||||
return false;
|
||||
} else if (this == other) {
|
||||
@ -168,5 +174,11 @@ public class WBWIRocksIterator
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
value.close();
|
||||
key.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +144,9 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
|
||||
* @param options The database options to use
|
||||
* @param key The key to read the value for
|
||||
*
|
||||
* @return a byte array storing the value associated with the input key if
|
||||
* any. null if it does not find the specified key.
|
||||
*
|
||||
* @throws RocksDBException if the batch does not have enough data to resolve
|
||||
* Merge operations, MergeInProgress status may be returned.
|
||||
*/
|
||||
@ -160,6 +163,9 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
|
||||
* @param options The database options to use
|
||||
* @param key The key to read the value for
|
||||
*
|
||||
* @return a byte array storing the value associated with the input key if
|
||||
* any. null if it does not find the specified key.
|
||||
*
|
||||
* @throws RocksDBException if the batch does not have enough data to resolve
|
||||
* Merge operations, MergeInProgress status may be returned.
|
||||
*/
|
||||
@ -181,10 +187,14 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
|
||||
* (the keys in this batch do not yet belong to any snapshot and will be
|
||||
* fetched regardless).
|
||||
*
|
||||
* @param db The Rocks database
|
||||
* @param columnFamilyHandle The column family to retrieve the value from
|
||||
* @param options The read options to use
|
||||
* @param key The key to read the value for
|
||||
*
|
||||
* @return a byte array storing the value associated with the input key if
|
||||
* any. null if it does not find the specified key.
|
||||
*
|
||||
* @throws RocksDBException if the value for the key cannot be read
|
||||
*/
|
||||
public byte[] getFromBatchAndDB(final RocksDB db, final ColumnFamilyHandle columnFamilyHandle,
|
||||
@ -207,9 +217,13 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
|
||||
* (the keys in this batch do not yet belong to any snapshot and will be
|
||||
* fetched regardless).
|
||||
*
|
||||
* @param db The Rocks database
|
||||
* @param options The read options to use
|
||||
* @param key The key to read the value for
|
||||
*
|
||||
* @return a byte array storing the value associated with the input key if
|
||||
* any. null if it does not find the specified key.
|
||||
*
|
||||
* @throws RocksDBException if the value for the key cannot be read
|
||||
*/
|
||||
public byte[] getFromBatchAndDB(final RocksDB db, final ReadOptions options,
|
||||
|
@ -203,8 +203,9 @@ public class ColumnFamilyTest {
|
||||
|
||||
@Test
|
||||
public void writeBatch() throws RocksDBException {
|
||||
try (final ColumnFamilyOptions defaultCfOptions = new ColumnFamilyOptions()
|
||||
.setMergeOperator(new StringAppendOperator())) {
|
||||
try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
|
||||
final ColumnFamilyOptions defaultCfOptions = new ColumnFamilyOptions()
|
||||
.setMergeOperator(stringAppendOperator)) {
|
||||
final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
|
||||
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
|
||||
defaultCfOptions),
|
||||
|
@ -388,25 +388,11 @@ public class DBOptionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rateLimiterConfig() {
|
||||
try(final DBOptions options = new DBOptions();
|
||||
final DBOptions anotherOptions = new DBOptions()) {
|
||||
final RateLimiterConfig rateLimiterConfig =
|
||||
new GenericRateLimiterConfig(1000, 100 * 1000, 1);
|
||||
options.setRateLimiterConfig(rateLimiterConfig);
|
||||
// Test with parameter initialization
|
||||
|
||||
anotherOptions.setRateLimiterConfig(
|
||||
new GenericRateLimiterConfig(1000));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rateLimiter() {
|
||||
try(final DBOptions options = new DBOptions();
|
||||
final DBOptions anotherOptions = new DBOptions()) {
|
||||
final RateLimiter rateLimiter = new RateLimiter(1000, 100 * 1000, 1);
|
||||
final DBOptions anotherOptions = new DBOptions();
|
||||
final RateLimiter rateLimiter = new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
options.setRateLimiter(rateLimiter);
|
||||
// Test with parameter initialization
|
||||
anotherOptions.setRateLimiter(
|
||||
|
@ -54,7 +54,7 @@ public class DirectSliceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void directSliceInitWithoutDirectAllocation() {
|
||||
final byte[] data = "Some text".getBytes();
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
@ -63,7 +63,7 @@ public class DirectSliceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void directSlicePrefixInitWithoutDirectAllocation() {
|
||||
final byte[] data = "Some text".getBytes();
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
@ -71,4 +71,23 @@ public class DirectSliceTest {
|
||||
//no-op
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void directSliceClear() {
|
||||
try(final DirectSlice directSlice = new DirectSlice("abc")) {
|
||||
assertThat(directSlice.toString()).isEqualTo("abc");
|
||||
directSlice.clear();
|
||||
assertThat(directSlice.toString()).isEmpty();
|
||||
directSlice.clear(); // make sure we don't double-free
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void directSliceRemovePrefix() {
|
||||
try(final DirectSlice directSlice = new DirectSlice("abc")) {
|
||||
assertThat(directSlice.toString()).isEqualTo("abc");
|
||||
directSlice.removePrefix(1);
|
||||
assertThat(directSlice.toString()).isEqualTo("bc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,16 +118,16 @@ public class EnvOptionsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rateLimiterConfig() {
|
||||
try (final EnvOptions envOptions = new EnvOptions()) {
|
||||
final RateLimiterConfig rateLimiterConfig1 =
|
||||
new GenericRateLimiterConfig(1000, 100 * 1000, 1);
|
||||
envOptions.setRateLimiterConfig(rateLimiterConfig1);
|
||||
assertThat(envOptions.rateLimiterConfig()).isEqualTo(rateLimiterConfig1);
|
||||
public void rateLimiter() {
|
||||
try (final EnvOptions envOptions = new EnvOptions();
|
||||
final RateLimiter rateLimiter1 = new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
envOptions.setRateLimiter(rateLimiter1);
|
||||
assertThat(envOptions.rateLimiter()).isEqualTo(rateLimiter1);
|
||||
|
||||
final RateLimiterConfig rateLimiterConfig2 = new GenericRateLimiterConfig(1000);
|
||||
envOptions.setRateLimiterConfig(rateLimiterConfig2);
|
||||
assertThat(envOptions.rateLimiterConfig()).isEqualTo(rateLimiterConfig2);
|
||||
try(final RateLimiter rateLimiter2 = new RateLimiter(1000)) {
|
||||
envOptions.setRateLimiter(rateLimiter2);
|
||||
assertThat(envOptions.rateLimiter()).isEqualTo(rateLimiter2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,21 +43,21 @@ public class KeyMayExistTest {
|
||||
isEqualTo(2);
|
||||
db.put("key".getBytes(), "value".getBytes());
|
||||
// Test without column family
|
||||
StringBuffer retValue = new StringBuffer();
|
||||
StringBuilder retValue = new StringBuilder();
|
||||
boolean exists = db.keyMayExist("key".getBytes(), retValue);
|
||||
assertThat(exists).isTrue();
|
||||
assertThat(retValue.toString()).isEqualTo("value");
|
||||
|
||||
// Test without column family but with readOptions
|
||||
try (final ReadOptions readOptions = new ReadOptions()) {
|
||||
retValue = new StringBuffer();
|
||||
retValue = new StringBuilder();
|
||||
exists = db.keyMayExist(readOptions, "key".getBytes(), retValue);
|
||||
assertThat(exists).isTrue();
|
||||
assertThat(retValue.toString()).isEqualTo("value");
|
||||
}
|
||||
|
||||
// Test with column family
|
||||
retValue = new StringBuffer();
|
||||
retValue = new StringBuilder();
|
||||
exists = db.keyMayExist(columnFamilyHandleList.get(0), "key".getBytes(),
|
||||
retValue);
|
||||
assertThat(exists).isTrue();
|
||||
@ -65,7 +65,7 @@ public class KeyMayExistTest {
|
||||
|
||||
// Test with column family and readOptions
|
||||
try (final ReadOptions readOptions = new ReadOptions()) {
|
||||
retValue = new StringBuffer();
|
||||
retValue = new StringBuilder();
|
||||
exists = db.keyMayExist(readOptions,
|
||||
columnFamilyHandleList.get(0), "key".getBytes(),
|
||||
retValue);
|
||||
|
@ -89,11 +89,10 @@ public class MergeTest {
|
||||
@Test
|
||||
public void operatorOption()
|
||||
throws InterruptedException, RocksDBException {
|
||||
final StringAppendOperator stringAppendOperator =
|
||||
new StringAppendOperator();
|
||||
try (final Options opt = new Options()
|
||||
.setCreateIfMissing(true)
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
|
||||
final Options opt = new Options()
|
||||
.setCreateIfMissing(true)
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
// Writing aa under key
|
||||
@ -112,10 +111,9 @@ public class MergeTest {
|
||||
@Test
|
||||
public void cFOperatorOption()
|
||||
throws InterruptedException, RocksDBException {
|
||||
final StringAppendOperator stringAppendOperator =
|
||||
new StringAppendOperator();
|
||||
try (final ColumnFamilyOptions cfOpt1 = new ColumnFamilyOptions()
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
|
||||
final ColumnFamilyOptions cfOpt1 = new ColumnFamilyOptions()
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final ColumnFamilyOptions cfOpt2 = new ColumnFamilyOptions()
|
||||
.setMergeOperator(stringAppendOperator)
|
||||
) {
|
||||
@ -175,42 +173,43 @@ public class MergeTest {
|
||||
@Test
|
||||
public void operatorGcBehaviour()
|
||||
throws RocksDBException {
|
||||
final StringAppendOperator stringAppendOperator
|
||||
= new StringAppendOperator();
|
||||
try (final Options opt = new Options()
|
||||
.setCreateIfMissing(true)
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
// test reuse
|
||||
try (final Options opt = new Options()
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
// test param init
|
||||
try (final Options opt = new Options()
|
||||
.setMergeOperator(new StringAppendOperator());
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
// test replace one with another merge operator instance
|
||||
try (final Options opt = new Options()
|
||||
.setMergeOperator(stringAppendOperator)) {
|
||||
final StringAppendOperator newStringAppendOperator
|
||||
= new StringAppendOperator();
|
||||
opt.setMergeOperator(newStringAppendOperator);
|
||||
try (final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
try (final StringAppendOperator stringAppendOperator = new StringAppendOperator()) {
|
||||
try (final Options opt = new Options()
|
||||
.setCreateIfMissing(true)
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
|
||||
// test reuse
|
||||
try (final Options opt = new Options()
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
// test param init
|
||||
try (final StringAppendOperator stringAppendOperator2 = new StringAppendOperator();
|
||||
final Options opt = new Options()
|
||||
.setMergeOperator(stringAppendOperator2);
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
// test replace one with another merge operator instance
|
||||
try (final Options opt = new Options()
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final StringAppendOperator newStringAppendOperator = new StringAppendOperator()) {
|
||||
opt.setMergeOperator(newStringAppendOperator);
|
||||
try (final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())) {
|
||||
//no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,16 +697,15 @@ public class OptionsTest {
|
||||
|
||||
@Test
|
||||
public void compressionPerLevel() {
|
||||
try (final ColumnFamilyOptions columnFamilyOptions =
|
||||
new ColumnFamilyOptions()) {
|
||||
assertThat(columnFamilyOptions.compressionPerLevel()).isEmpty();
|
||||
try (final Options options = new Options()) {
|
||||
assertThat(options.compressionPerLevel()).isEmpty();
|
||||
List<CompressionType> compressionTypeList =
|
||||
new ArrayList<>();
|
||||
for (int i = 0; i < columnFamilyOptions.numLevels(); i++) {
|
||||
for (int i = 0; i < options.numLevels(); i++) {
|
||||
compressionTypeList.add(CompressionType.NO_COMPRESSION);
|
||||
}
|
||||
columnFamilyOptions.setCompressionPerLevel(compressionTypeList);
|
||||
compressionTypeList = columnFamilyOptions.compressionPerLevel();
|
||||
options.setCompressionPerLevel(compressionTypeList);
|
||||
compressionTypeList = options.compressionPerLevel();
|
||||
for (final CompressionType compressionType : compressionTypeList) {
|
||||
assertThat(compressionType).isEqualTo(
|
||||
CompressionType.NO_COMPRESSION);
|
||||
@ -716,19 +715,18 @@ public class OptionsTest {
|
||||
|
||||
@Test
|
||||
public void differentCompressionsPerLevel() {
|
||||
try (final ColumnFamilyOptions columnFamilyOptions =
|
||||
new ColumnFamilyOptions()) {
|
||||
columnFamilyOptions.setNumLevels(3);
|
||||
try (final Options options = new Options()) {
|
||||
options.setNumLevels(3);
|
||||
|
||||
assertThat(columnFamilyOptions.compressionPerLevel()).isEmpty();
|
||||
assertThat(options.compressionPerLevel()).isEmpty();
|
||||
List<CompressionType> compressionTypeList = new ArrayList<>();
|
||||
|
||||
compressionTypeList.add(CompressionType.BZLIB2_COMPRESSION);
|
||||
compressionTypeList.add(CompressionType.SNAPPY_COMPRESSION);
|
||||
compressionTypeList.add(CompressionType.LZ4_COMPRESSION);
|
||||
|
||||
columnFamilyOptions.setCompressionPerLevel(compressionTypeList);
|
||||
compressionTypeList = columnFamilyOptions.compressionPerLevel();
|
||||
options.setCompressionPerLevel(compressionTypeList);
|
||||
compressionTypeList = options.compressionPerLevel();
|
||||
|
||||
assertThat(compressionTypeList.size()).isEqualTo(3);
|
||||
assertThat(compressionTypeList).
|
||||
@ -767,26 +765,12 @@ public class OptionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rateLimiterConfig() {
|
||||
try (final Options options = new Options();
|
||||
final Options anotherOptions = new Options()) {
|
||||
final RateLimiterConfig rateLimiterConfig =
|
||||
new GenericRateLimiterConfig(1000, 100 * 1000, 1);
|
||||
options.setRateLimiterConfig(rateLimiterConfig);
|
||||
// Test with parameter initialization
|
||||
|
||||
anotherOptions.setRateLimiterConfig(
|
||||
new GenericRateLimiterConfig(1000));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rateLimiter() {
|
||||
try (final Options options = new Options();
|
||||
final Options anotherOptions = new Options()) {
|
||||
final RateLimiter rateLimiter =
|
||||
new RateLimiter(1000, 100 * 1000, 1);
|
||||
final Options anotherOptions = new Options();
|
||||
final RateLimiter rateLimiter =
|
||||
new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
options.setRateLimiter(rateLimiter);
|
||||
// Test with parameter initialization
|
||||
anotherOptions.setRateLimiter(
|
||||
@ -810,7 +794,6 @@ public class OptionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldTestMemTableFactoryName()
|
||||
throws RocksDBException {
|
||||
|
49
java/src/test/java/org/rocksdb/RateLimiterTest.java
Normal file
49
java/src/test/java/org/rocksdb/RateLimiterTest.java
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
package org.rocksdb;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class RateLimiterTest {
|
||||
|
||||
@ClassRule
|
||||
public static final RocksMemoryResource rocksMemoryResource =
|
||||
new RocksMemoryResource();
|
||||
|
||||
@Test
|
||||
public void setBytesPerSecond() {
|
||||
try(final RateLimiter rateLimiter =
|
||||
new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
rateLimiter.setBytesPerSecond(2000);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSingleBurstBytes() {
|
||||
try(final RateLimiter rateLimiter =
|
||||
new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
assertThat(rateLimiter.getSingleBurstBytes()).isEqualTo(100);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTotalBytesThrough() {
|
||||
try(final RateLimiter rateLimiter =
|
||||
new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
assertThat(rateLimiter.getTotalBytesThrough()).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTotalRequests() {
|
||||
try(final RateLimiter rateLimiter =
|
||||
new RateLimiter(1000, 100 * 1000, 1)) {
|
||||
assertThat(rateLimiter.getTotalRequests()).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
}
|
@ -73,8 +73,10 @@ public class RocksDBTest {
|
||||
|
||||
@Test
|
||||
public void write() throws RocksDBException {
|
||||
try (final Options options = new Options().setMergeOperator(
|
||||
new StringAppendOperator()).setCreateIfMissing(true);
|
||||
try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
|
||||
final Options options = new Options()
|
||||
.setMergeOperator(stringAppendOperator)
|
||||
.setCreateIfMissing(true);
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath());
|
||||
final WriteOptions opts = new WriteOptions()) {
|
||||
@ -182,9 +184,10 @@ public class RocksDBTest {
|
||||
|
||||
@Test
|
||||
public void merge() throws RocksDBException {
|
||||
try (final Options opt = new Options()
|
||||
.setCreateIfMissing(true)
|
||||
.setMergeOperator(new StringAppendOperator());
|
||||
try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
|
||||
final Options opt = new Options()
|
||||
.setCreateIfMissing(true)
|
||||
.setMergeOperator(stringAppendOperator);
|
||||
final WriteOptions wOpt = new WriteOptions();
|
||||
final RocksDB db = RocksDB.open(opt,
|
||||
dbFolder.getRoot().getAbsolutePath())
|
||||
|
@ -32,6 +32,25 @@ public class SliceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sliceClear() {
|
||||
try (final Slice slice = new Slice("abc")) {
|
||||
assertThat(slice.toString()).isEqualTo("abc");
|
||||
slice.clear();
|
||||
assertThat(slice.toString()).isEmpty();
|
||||
slice.clear(); // make sure we don't double-free
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sliceRemovePrefix() {
|
||||
try (final Slice slice = new Slice("abc")) {
|
||||
assertThat(slice.toString()).isEqualTo("abc");
|
||||
slice.removePrefix(1);
|
||||
assertThat(slice.toString()).isEqualTo("bc");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sliceEquals() {
|
||||
try (final Slice slice = new Slice("abc");
|
||||
|
@ -192,16 +192,16 @@ public class WriteBatchWithIndexTest {
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(zeroByteValue.length);
|
||||
buffer.put(zeroByteValue);
|
||||
|
||||
WBWIRocksIterator.WriteEntry[] expected = {
|
||||
final WBWIRocksIterator.WriteEntry expected =
|
||||
new WBWIRocksIterator.WriteEntry(WBWIRocksIterator.WriteType.PUT,
|
||||
new DirectSlice(buffer, zeroByteValue.length),
|
||||
new DirectSlice(buffer, zeroByteValue.length))
|
||||
};
|
||||
new DirectSlice(buffer, zeroByteValue.length));
|
||||
|
||||
try (final WBWIRocksIterator it = wbwi.newIterator()) {
|
||||
it.seekToFirst();
|
||||
assertThat(it.entry().equals(expected[0])).isTrue();
|
||||
assertThat(it.entry().hashCode() == expected[0].hashCode()).isTrue();
|
||||
final WBWIRocksIterator.WriteEntry actual = it.entry();
|
||||
assertThat(actual.equals(expected)).isTrue();
|
||||
assertThat(it.entry().hashCode() == expected.hashCode()).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,12 +31,12 @@ public class RocksJunitRunner {
|
||||
*
|
||||
* @param system JUnitSystem
|
||||
*/
|
||||
public RocksJunitListener(JUnitSystem system) {
|
||||
public RocksJunitListener(final JUnitSystem system) {
|
||||
super(system);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStarted(Description description) {
|
||||
public void testStarted(final Description description) {
|
||||
System.out.format("Run: %s testing now -> %s \n",
|
||||
description.getClassName(),
|
||||
description.getMethodName());
|
||||
@ -48,21 +48,23 @@ public class RocksJunitRunner {
|
||||
*
|
||||
* @param args Test classes as String names
|
||||
*/
|
||||
public static void main(String[] args){
|
||||
JUnitCore runner = new JUnitCore();
|
||||
public static void main(final String[] args){
|
||||
final JUnitCore runner = new JUnitCore();
|
||||
final JUnitSystem system = new RealSystem();
|
||||
runner.addListener(new RocksJunitListener(system));
|
||||
try {
|
||||
List<Class<?>> classes = new ArrayList<>();
|
||||
for (String arg : args) {
|
||||
final List<Class<?>> classes = new ArrayList<>();
|
||||
for (final String arg : args) {
|
||||
classes.add(Class.forName(arg));
|
||||
}
|
||||
final Result result = runner.run(classes.toArray(new Class[1]));
|
||||
final Class[] clazzes = classes.toArray(new Class[classes.size()]);
|
||||
final Result result = runner.run(clazzes);
|
||||
if(!result.wasSuccessful()) {
|
||||
System.exit(-1);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
} catch (final ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user