Improve the speed and synchronization around the construction of Java/JNI objects

main
Adam Retter 9 years ago
parent 2a04268be3
commit 18eb563058
  1. 23
      java/rocksjni/backupablejni.cc
  2. 14
      java/rocksjni/backupenginejni.cc
  3. 12
      java/rocksjni/comparator.cc
  4. 12
      java/rocksjni/filter.cc
  5. 12
      java/rocksjni/loggerjnicallback.cc
  6. 69
      java/rocksjni/options.cc
  7. 8
      java/rocksjni/portal.h
  8. 13
      java/rocksjni/remove_emptyvalue_compactionfilterjni.cc
  9. 16
      java/rocksjni/restorejni.cc
  10. 281
      java/rocksjni/rocksjni.cc
  11. 48
      java/rocksjni/slice.cc
  12. 146
      java/rocksjni/ttl.cc
  13. 15
      java/rocksjni/write_batch.cc
  14. 24
      java/rocksjni/write_batch_with_index.cc
  15. 12
      java/src/main/java/org/rocksdb/AbstractCompactionFilter.java
  16. 17
      java/src/main/java/org/rocksdb/AbstractComparator.java
  17. 23
      java/src/main/java/org/rocksdb/AbstractRocksIterator.java
  18. 42
      java/src/main/java/org/rocksdb/AbstractSlice.java
  19. 33
      java/src/main/java/org/rocksdb/AbstractWriteBatch.java
  20. 36
      java/src/main/java/org/rocksdb/BackupEngine.java
  21. 29
      java/src/main/java/org/rocksdb/BackupableDB.java
  22. 53
      java/src/main/java/org/rocksdb/BackupableDBOptions.java
  23. 16
      java/src/main/java/org/rocksdb/BloomFilter.java
  24. 18
      java/src/main/java/org/rocksdb/Checkpoint.java
  25. 17
      java/src/main/java/org/rocksdb/ColumnFamilyHandle.java
  26. 45
      java/src/main/java/org/rocksdb/ColumnFamilyOptions.java
  27. 12
      java/src/main/java/org/rocksdb/Comparator.java
  28. 16
      java/src/main/java/org/rocksdb/ComparatorOptions.java
  29. 149
      java/src/main/java/org/rocksdb/DBOptions.java
  30. 12
      java/src/main/java/org/rocksdb/DirectComparator.java
  31. 32
      java/src/main/java/org/rocksdb/DirectSlice.java
  32. 4
      java/src/main/java/org/rocksdb/Env.java
  33. 12
      java/src/main/java/org/rocksdb/Filter.java
  34. 15
      java/src/main/java/org/rocksdb/FlushOptions.java
  35. 17
      java/src/main/java/org/rocksdb/Logger.java
  36. 77
      java/src/main/java/org/rocksdb/NativeReference.java
  37. 173
      java/src/main/java/org/rocksdb/Options.java
  38. 27
      java/src/main/java/org/rocksdb/ReadOptions.java
  39. 5
      java/src/main/java/org/rocksdb/RemoveEmptyValueCompactionFilter.java
  40. 29
      java/src/main/java/org/rocksdb/RestoreBackupableDB.java
  41. 16
      java/src/main/java/org/rocksdb/RestoreOptions.java
  42. 113
      java/src/main/java/org/rocksdb/RocksDB.java
  43. 6
      java/src/main/java/org/rocksdb/RocksEnv.java
  44. 6
      java/src/main/java/org/rocksdb/RocksIterator.java
  45. 10
      java/src/main/java/org/rocksdb/RocksMemEnv.java
  46. 33
      java/src/main/java/org/rocksdb/RocksMutableObject.java
  47. 101
      java/src/main/java/org/rocksdb/RocksObject.java
  48. 17
      java/src/main/java/org/rocksdb/Slice.java
  49. 8
      java/src/main/java/org/rocksdb/Snapshot.java
  50. 9
      java/src/main/java/org/rocksdb/TransactionLogIterator.java
  51. 56
      java/src/main/java/org/rocksdb/TtlDB.java
  52. 10
      java/src/main/java/org/rocksdb/WBWIRocksIterator.java
  53. 25
      java/src/main/java/org/rocksdb/WriteBatch.java
  54. 20
      java/src/main/java/org/rocksdb/WriteBatchWithIndex.java
  55. 11
      java/src/main/java/org/rocksdb/WriteOptions.java
  56. 4
      java/src/test/java/org/rocksdb/WriteBatchWithIndexTest.java

@ -21,17 +21,17 @@
/* /*
* Class: org_rocksdb_BackupableDB * Class: org_rocksdb_BackupableDB
* Method: open * Method: open
* Signature: (JJ)V * Signature: (JJ)J
*/ */
void Java_org_rocksdb_BackupableDB_open( jlong Java_org_rocksdb_BackupableDB_open(
JNIEnv* env, jobject jbdb, jlong jdb_handle, jlong jopt_handle) { JNIEnv* env, jclass jcls, jlong jdb_handle, jlong jopt_handle) {
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto opt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jopt_handle); auto* opt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jopt_handle);
auto bdb = new rocksdb::BackupableDB(db, *opt); auto bdb = new rocksdb::BackupableDB(db, *opt);
// as BackupableDB extends RocksDB on the java side, we can reuse // as BackupableDB extends RocksDB on the java side, we can reuse
// the RocksDB portal here. // the RocksDB portal here.
rocksdb::RocksDBJni::setHandle(env, jbdb, bdb); return reinterpret_cast<jlong>(bdb);
} }
/* /*
@ -135,14 +135,14 @@ void Java_org_rocksdb_BackupableDB_garbageCollect(JNIEnv* env,
/* /*
* Class: org_rocksdb_BackupableDBOptions * Class: org_rocksdb_BackupableDBOptions
* Method: newBackupableDBOptions * Method: newBackupableDBOptions
* Signature: (Ljava/lang/String;)V * Signature: (Ljava/lang/String;)J
*/ */
void Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions( jlong Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions(
JNIEnv* env, jobject jobj, jstring jpath) { JNIEnv* env, jclass jcls, jstring jpath) {
const char* cpath = env->GetStringUTFChars(jpath, 0); const char* cpath = env->GetStringUTFChars(jpath, NULL);
auto bopt = new rocksdb::BackupableDBOptions(cpath); auto bopt = new rocksdb::BackupableDBOptions(cpath);
env->ReleaseStringUTFChars(jpath, cpath); env->ReleaseStringUTFChars(jpath, cpath);
rocksdb::BackupableDBOptionsJni::setHandle(env, jobj, bopt); return reinterpret_cast<jlong>(bopt);
} }
/* /*
@ -320,5 +320,4 @@ void Java_org_rocksdb_BackupableDBOptions_disposeInternal(
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle); auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
assert(bopt); assert(bopt);
delete bopt; delete bopt;
rocksdb::BackupableDBOptionsJni::setHandle(env, jopt, nullptr);
} }

@ -16,10 +16,10 @@
/* /*
* Class: org_rocksdb_BackupEngine * Class: org_rocksdb_BackupEngine
* Method: open * Method: open
* Signature: (JJ)V * Signature: (JJ)J
*/ */
void Java_org_rocksdb_BackupEngine_open( jlong Java_org_rocksdb_BackupEngine_open(
JNIEnv* env, jobject jbe, jlong env_handle, JNIEnv* env, jclass jcls, jlong env_handle,
jlong backupable_db_options_handle) { jlong backupable_db_options_handle) {
auto* rocks_env = reinterpret_cast<rocksdb::Env*>(env_handle); auto* rocks_env = reinterpret_cast<rocksdb::Env*>(env_handle);
auto* backupable_db_options = auto* backupable_db_options =
@ -30,11 +30,11 @@ void Java_org_rocksdb_BackupEngine_open(
*backupable_db_options, &backup_engine); *backupable_db_options, &backup_engine);
if (status.ok()) { if (status.ok()) {
rocksdb::BackupEngineJni::setHandle(env, jbe, backup_engine); return reinterpret_cast<jlong>(backup_engine);
return; } else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
return 0;
} }
rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
} }
/* /*

@ -36,15 +36,15 @@ void Java_org_rocksdb_AbstractComparator_disposeInternal(
/* /*
* Class: org_rocksdb_Comparator * Class: org_rocksdb_Comparator
* Method: createNewComparator0 * Method: createNewComparator0
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_Comparator_createNewComparator0( jlong Java_org_rocksdb_Comparator_createNewComparator0(
JNIEnv* env, jobject jobj, jlong copt_handle) { JNIEnv* env, jobject jobj, jlong copt_handle) {
const rocksdb::ComparatorJniCallbackOptions* copt = const rocksdb::ComparatorJniCallbackOptions* copt =
reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(copt_handle); reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(copt_handle);
const rocksdb::ComparatorJniCallback* c = const rocksdb::ComparatorJniCallback* c =
new rocksdb::ComparatorJniCallback(env, jobj, copt); new rocksdb::ComparatorJniCallback(env, jobj, copt);
rocksdb::AbstractComparatorJni::setHandle(env, jobj, c); return reinterpret_cast<jlong>(c);
} }
// </editor-fold> // </editor-fold>
@ -53,14 +53,14 @@ void Java_org_rocksdb_Comparator_createNewComparator0(
/* /*
* Class: org_rocksdb_DirectComparator * Class: org_rocksdb_DirectComparator
* Method: createNewDirectComparator0 * Method: createNewDirectComparator0
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_DirectComparator_createNewDirectComparator0( jlong Java_org_rocksdb_DirectComparator_createNewDirectComparator0(
JNIEnv* env, jobject jobj, jlong copt_handle) { JNIEnv* env, jobject jobj, jlong copt_handle) {
const rocksdb::ComparatorJniCallbackOptions* copt = const rocksdb::ComparatorJniCallbackOptions* copt =
reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(copt_handle); reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(copt_handle);
const rocksdb::DirectComparatorJniCallback* c = const rocksdb::DirectComparatorJniCallback* c =
new rocksdb::DirectComparatorJniCallback(env, jobj, copt); new rocksdb::DirectComparatorJniCallback(env, jobj, copt);
rocksdb::AbstractComparatorJni::setHandle(env, jobj, c); return reinterpret_cast<jlong>(c);
} }
// </editor-fold> // </editor-fold>

@ -19,17 +19,17 @@
/* /*
* Class: org_rocksdb_BloomFilter * Class: org_rocksdb_BloomFilter
* Method: createBloomFilter * Method: createBloomFilter
* Signature: (IZ)V * Signature: (IZ)J
*/ */
void Java_org_rocksdb_BloomFilter_createNewBloomFilter( jlong Java_org_rocksdb_BloomFilter_createNewBloomFilter(
JNIEnv* env, jobject jobj, jint bits_per_key, JNIEnv* env, jclass jcls, jint bits_per_key,
jboolean use_block_base_builder) { jboolean use_block_base_builder) {
rocksdb::FilterPolicy* fp = const_cast<rocksdb::FilterPolicy *>( auto* fp = const_cast<rocksdb::FilterPolicy *>(
rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder)); rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder));
std::shared_ptr<rocksdb::FilterPolicy> *pFilterPolicy = auto* pFilterPolicy =
new std::shared_ptr<rocksdb::FilterPolicy>; new std::shared_ptr<rocksdb::FilterPolicy>;
*pFilterPolicy = std::shared_ptr<rocksdb::FilterPolicy>(fp); *pFilterPolicy = std::shared_ptr<rocksdb::FilterPolicy>(fp);
rocksdb::FilterJni::setHandle(env, jobj, pFilterPolicy); return reinterpret_cast<jlong>(pFilterPolicy);
} }
/* /*

@ -125,9 +125,9 @@ LoggerJniCallback::~LoggerJniCallback() {
/* /*
* Class: org_rocksdb_Logger * Class: org_rocksdb_Logger
* Method: createNewLoggerOptions * Method: createNewLoggerOptions
* Signature: (J)V * Signature: (J)J
*/ */
void Java_org_rocksdb_Logger_createNewLoggerOptions( jlong Java_org_rocksdb_Logger_createNewLoggerOptions(
JNIEnv* env, jobject jobj, jlong joptions) { JNIEnv* env, jobject jobj, jlong joptions) {
rocksdb::LoggerJniCallback* c = rocksdb::LoggerJniCallback* c =
new rocksdb::LoggerJniCallback(env, jobj); new rocksdb::LoggerJniCallback(env, jobj);
@ -137,15 +137,15 @@ void Java_org_rocksdb_Logger_createNewLoggerOptions(
std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback =
new std::shared_ptr<rocksdb::LoggerJniCallback>; new std::shared_ptr<rocksdb::LoggerJniCallback>;
*pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c); *pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c);
rocksdb::LoggerJni::setHandle(env, jobj, pLoggerJniCallback); return reinterpret_cast<jlong>(pLoggerJniCallback);
} }
/* /*
* Class: org_rocksdb_Logger * Class: org_rocksdb_Logger
* Method: createNewLoggerDbOptions * Method: createNewLoggerDbOptions
* Signature: (J)V * Signature: (J)J
*/ */
void Java_org_rocksdb_Logger_createNewLoggerDbOptions( jlong Java_org_rocksdb_Logger_createNewLoggerDbOptions(
JNIEnv* env, jobject jobj, jlong jdb_options) { JNIEnv* env, jobject jobj, jlong jdb_options) {
rocksdb::LoggerJniCallback* c = rocksdb::LoggerJniCallback* c =
new rocksdb::LoggerJniCallback(env, jobj); new rocksdb::LoggerJniCallback(env, jobj);
@ -155,7 +155,7 @@ void Java_org_rocksdb_Logger_createNewLoggerDbOptions(
std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback =
new std::shared_ptr<rocksdb::LoggerJniCallback>; new std::shared_ptr<rocksdb::LoggerJniCallback>;
*pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c); *pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c);
rocksdb::LoggerJni::setHandle(env, jobj, pLoggerJniCallback); return reinterpret_cast<jlong>(pLoggerJniCallback);
} }
/* /*

@ -36,25 +36,25 @@
/* /*
* Class: org_rocksdb_Options * Class: org_rocksdb_Options
* Method: newOptions * Method: newOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_Options_newOptions__(JNIEnv* env, jobject jobj) { jlong Java_org_rocksdb_Options_newOptions__(JNIEnv* env, jclass jcls) {
rocksdb::Options* op = new rocksdb::Options(); rocksdb::Options* op = new rocksdb::Options();
rocksdb::OptionsJni::setHandle(env, jobj, op); return reinterpret_cast<jlong>(op);
} }
/* /*
* Class: org_rocksdb_Options * Class: org_rocksdb_Options
* Method: newOptions * Method: newOptions
* Signature: (JJ)V * Signature: (JJ)J
*/ */
void Java_org_rocksdb_Options_newOptions__JJ(JNIEnv* env, jobject jobj, jlong Java_org_rocksdb_Options_newOptions__JJ(JNIEnv* env, jclass jcls,
jlong jdboptions, jlong jcfoptions) { jlong jdboptions, jlong jcfoptions) {
auto dbOpt = reinterpret_cast<const rocksdb::DBOptions*>(jdboptions); auto* dbOpt = reinterpret_cast<const rocksdb::DBOptions*>(jdboptions);
auto cfOpt = reinterpret_cast<const rocksdb::ColumnFamilyOptions*>( auto* cfOpt = reinterpret_cast<const rocksdb::ColumnFamilyOptions*>(
jcfoptions); jcfoptions);
rocksdb::Options* op = new rocksdb::Options(*dbOpt, *cfOpt); rocksdb::Options* op = new rocksdb::Options(*dbOpt, *cfOpt);
rocksdb::OptionsJni::setHandle(env, jobj, op); return reinterpret_cast<jlong>(op);
} }
/* /*
@ -1932,12 +1932,12 @@ void Java_org_rocksdb_Options_prepareForBulkLoad(
/* /*
* Class: org_rocksdb_ColumnFamilyOptions * Class: org_rocksdb_ColumnFamilyOptions
* Method: newColumnFamilyOptions * Method: newColumnFamilyOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions( jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
rocksdb::ColumnFamilyOptions* op = new rocksdb::ColumnFamilyOptions(); rocksdb::ColumnFamilyOptions* op = new rocksdb::ColumnFamilyOptions();
rocksdb::ColumnFamilyOptionsJni::setHandle(env, jobj, op); return reinterpret_cast<jlong>(op);
} }
/* /*
@ -3072,12 +3072,12 @@ void Java_org_rocksdb_ColumnFamilyOptions_setOptimizeFiltersForHits(
/* /*
* Class: org_rocksdb_DBOptions * Class: org_rocksdb_DBOptions
* Method: newDBOptions * Method: newDBOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env, jlong Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env,
jobject jobj) { jclass jcls) {
rocksdb::DBOptions* dbop = new rocksdb::DBOptions(); rocksdb::DBOptions* dbop = new rocksdb::DBOptions();
rocksdb::DBOptionsJni::setHandle(env, jobj, dbop); return reinterpret_cast<jlong>(dbop);
} }
/* /*
@ -3872,12 +3872,12 @@ jlong Java_org_rocksdb_DBOptions_bytesPerSync(
/* /*
* Class: org_rocksdb_WriteOptions * Class: org_rocksdb_WriteOptions
* Method: newWriteOptions * Method: newWriteOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_WriteOptions_newWriteOptions( jlong Java_org_rocksdb_WriteOptions_newWriteOptions(
JNIEnv* env, jobject jwrite_options) { JNIEnv* env, jclass jcls) {
rocksdb::WriteOptions* op = new rocksdb::WriteOptions(); rocksdb::WriteOptions* op = new rocksdb::WriteOptions();
rocksdb::WriteOptionsJni::setHandle(env, jwrite_options, op); return reinterpret_cast<jlong>(op);
} }
/* /*
@ -3889,8 +3889,6 @@ void Java_org_rocksdb_WriteOptions_disposeInternal(
JNIEnv* env, jobject jwrite_options, jlong jhandle) { JNIEnv* env, jobject jwrite_options, jlong jhandle) {
auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle); auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle);
delete write_options; delete write_options;
rocksdb::WriteOptionsJni::setHandle(env, jwrite_options, nullptr);
} }
/* /*
@ -3939,12 +3937,12 @@ jboolean Java_org_rocksdb_WriteOptions_disableWAL(
/* /*
* Class: org_rocksdb_ReadOptions * Class: org_rocksdb_ReadOptions
* Method: newReadOptions * Method: newReadOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_ReadOptions_newReadOptions( jlong Java_org_rocksdb_ReadOptions_newReadOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
auto read_opt = new rocksdb::ReadOptions(); auto read_opt = new rocksdb::ReadOptions();
rocksdb::ReadOptionsJni::setHandle(env, jobj, read_opt); return reinterpret_cast<jlong>(read_opt);
} }
/* /*
@ -3955,7 +3953,6 @@ void Java_org_rocksdb_ReadOptions_newReadOptions(
void Java_org_rocksdb_ReadOptions_disposeInternal( void Java_org_rocksdb_ReadOptions_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) { JNIEnv* env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::ReadOptions*>(jhandle); delete reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
rocksdb::ReadOptionsJni::setHandle(env, jobj, nullptr);
} }
/* /*
@ -4052,12 +4049,12 @@ jlong Java_org_rocksdb_ReadOptions_snapshot(
/* /*
* Class: org_rocksdb_ComparatorOptions * Class: org_rocksdb_ComparatorOptions
* Method: newComparatorOptions * Method: newComparatorOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_ComparatorOptions_newComparatorOptions( jlong Java_org_rocksdb_ComparatorOptions_newComparatorOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
auto comparator_opt = new rocksdb::ComparatorJniCallbackOptions(); auto comparator_opt = new rocksdb::ComparatorJniCallbackOptions();
rocksdb::ComparatorOptionsJni::setHandle(env, jobj, comparator_opt); return reinterpret_cast<jlong>(comparator_opt);
} }
/* /*
@ -4090,7 +4087,6 @@ void Java_org_rocksdb_ComparatorOptions_setUseAdaptiveMutex(
void Java_org_rocksdb_ComparatorOptions_disposeInternal( void Java_org_rocksdb_ComparatorOptions_disposeInternal(
JNIEnv * env, jobject jobj, jlong jhandle) { JNIEnv * env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle); delete reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle);
rocksdb::ComparatorOptionsJni::setHandle(env, jobj, nullptr);
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -4099,12 +4095,12 @@ void Java_org_rocksdb_ComparatorOptions_disposeInternal(
/* /*
* Class: org_rocksdb_FlushOptions * Class: org_rocksdb_FlushOptions
* Method: newFlushOptions * Method: newFlushOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_FlushOptions_newFlushOptions( jlong Java_org_rocksdb_FlushOptions_newFlushOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
auto flush_opt = new rocksdb::FlushOptions(); auto flush_opt = new rocksdb::FlushOptions();
rocksdb::FlushOptionsJni::setHandle(env, jobj, flush_opt); return reinterpret_cast<jlong>(flush_opt);
} }
/* /*
@ -4137,5 +4133,4 @@ jboolean Java_org_rocksdb_FlushOptions_waitForFlush(
void Java_org_rocksdb_FlushOptions_disposeInternal( void Java_org_rocksdb_FlushOptions_disposeInternal(
JNIEnv * env, jobject jobj, jlong jhandle) { JNIEnv * env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::FlushOptions*>(jhandle); delete reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
rocksdb::FlushOptionsJni::setHandle(env, jobj, nullptr);
} }

@ -64,11 +64,15 @@ template<class PTR, class DERIVED> class RocksDBNativeClass {
return reinterpret_cast<PTR>( return reinterpret_cast<PTR>(
env->GetLongField(jobj, getHandleFieldID(env))); env->GetLongField(jobj, getHandleFieldID(env)));
} }
};
// Native class template for sub-classes of RocksMutableObject
template<class PTR, class DERIVED> class NativeRocksMutableObject : public RocksDBNativeClass<PTR, DERIVED> {
public:
// Pass the pointer to the java side. // Pass the pointer to the java side.
static void setHandle(JNIEnv* env, jobject jdb, PTR ptr) { static void setHandle(JNIEnv* env, jobject jdb, PTR ptr) {
env->SetLongField( env->SetLongField(
jdb, getHandleFieldID(env), jdb, RocksDBNativeClass<PTR, DERIVED>::getHandleFieldID(env),
reinterpret_cast<jlong>(ptr)); reinterpret_cast<jlong>(ptr));
} }
}; };
@ -407,7 +411,7 @@ class AbstractComparatorJni : public RocksDBNativeClass<
}; };
// The portal class for org.rocksdb.AbstractSlice // The portal class for org.rocksdb.AbstractSlice
class AbstractSliceJni : public RocksDBNativeClass< class AbstractSliceJni : public NativeRocksMutableObject<
const rocksdb::Slice*, AbstractSliceJni> { const rocksdb::Slice*, AbstractSliceJni> {
public: public:
static jclass getJClass(JNIEnv* env) { static jclass getJClass(JNIEnv* env) {

@ -12,16 +12,13 @@
/* /*
* Class: org_rocksdb_RemoveEmptyValueCompactionFilter * Class: org_rocksdb_RemoveEmptyValueCompactionFilter
* Method: createNewRemoveEmptyValueCompactionFilter0 * Method: createNewRemoveEmptyValueCompactionFilter0
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_RemoveEmptyValueCompactionFilter_createNewRemoveEmptyValueCompactionFilter0( jlong Java_org_rocksdb_RemoveEmptyValueCompactionFilter_createNewRemoveEmptyValueCompactionFilter0(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
const rocksdb::RemoveEmptyValueCompactionFilter* compaction_filter = auto* compaction_filter =
new rocksdb::RemoveEmptyValueCompactionFilter(); new rocksdb::RemoveEmptyValueCompactionFilter();
// set the native handle to our native compaction filter // set the native handle to our native compaction filter
static jclass jclazz = return reinterpret_cast<jlong>(compaction_filter);
env->FindClass("org/rocksdb/RemoveEmptyValueCompactionFilter");
static jfieldID fid = env->GetFieldID(jclazz, "nativeHandle_", "J");
env->SetLongField(jobj, fid, reinterpret_cast<jlong>(compaction_filter));
} }

@ -22,17 +22,17 @@
* Signature: (Z)J * Signature: (Z)J
*/ */
jlong Java_org_rocksdb_RestoreOptions_newRestoreOptions(JNIEnv* env, jlong Java_org_rocksdb_RestoreOptions_newRestoreOptions(JNIEnv* env,
jobject jobj, jboolean keep_log_files) { 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); return reinterpret_cast<jlong>(ropt);
} }
/* /*
* Class: org_rocksdb_RestoreOptions * Class: org_rocksdb_RestoreOptions
* Method: dispose * Method: disposeInternal
* Signature: (J)V * Signature: (J)V
*/ */
void Java_org_rocksdb_RestoreOptions_dispose(JNIEnv* env, jobject jobj, void Java_org_rocksdb_RestoreOptions_disposeInternal(JNIEnv* env, jobject jobj,
jlong jhandle) { jlong jhandle) {
auto ropt = reinterpret_cast<rocksdb::RestoreOptions*>(jhandle); auto ropt = reinterpret_cast<rocksdb::RestoreOptions*>(jhandle);
assert(ropt); assert(ropt);
@ -45,8 +45,8 @@ void Java_org_rocksdb_RestoreOptions_dispose(JNIEnv* env, jobject jobj,
* Signature: (J)J * Signature: (J)J
*/ */
jlong Java_org_rocksdb_RestoreBackupableDB_newRestoreBackupableDB(JNIEnv* env, jlong Java_org_rocksdb_RestoreBackupableDB_newRestoreBackupableDB(JNIEnv* env,
jobject jobj, jlong jopt_handle) { jclass jcls, jlong jopt_handle) {
auto opt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jopt_handle); auto* opt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jopt_handle);
auto rdb = new rocksdb::RestoreBackupableDB(rocksdb::Env::Default(), *opt); auto rdb = new rocksdb::RestoreBackupableDB(rocksdb::Env::Default(), *opt);
return reinterpret_cast<jlong>(rdb); return reinterpret_cast<jlong>(rdb);
} }
@ -185,11 +185,11 @@ void Java_org_rocksdb_RestoreBackupableDB_garbageCollect(
/* /*
* Class: org_rocksdb_RestoreBackupableDB * Class: org_rocksdb_RestoreBackupableDB
* Method: dispose * Method: disposeInternal
* Signature: (J)V * Signature: (J)V
*/ */
void Java_org_rocksdb_RestoreBackupableDB_dispose(JNIEnv* env, jobject jobj, void Java_org_rocksdb_RestoreBackupableDB_disposeInternal(JNIEnv* env,
jlong jhandle) { jobject jobj, jlong jhandle) {
auto ropt = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle); auto ropt = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
assert(ropt); assert(ropt);
delete ropt; delete ropt;

@ -26,217 +26,142 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// rocksdb::DB::Open // rocksdb::DB::Open
jlong rocksdb_open_helper(JNIEnv* env, jlong jopt_handle, jstring jdb_path,
/* std::function<rocksdb::Status(
* Class: org_rocksdb_RocksDB const rocksdb::Options&, const std::string&, rocksdb::DB**)> open_fn
* Method: open ) {
* Signature: (JLjava/lang/String;)V auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
*/
void Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) {
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
rocksdb::DB* db = nullptr; rocksdb::DB* db = nullptr;
const char* db_path = env->GetStringUTFChars(jdb_path, 0); const char* db_path = env->GetStringUTFChars(jdb_path, NULL);
rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, &db); rocksdb::Status s = open_fn(*opt, db_path, &db);
env->ReleaseStringUTFChars(jdb_path, db_path); env->ReleaseStringUTFChars(jdb_path, db_path);
if (s.ok()) { if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db); return reinterpret_cast<jlong>(db);
return; } else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
} }
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: openROnly * Method: open
* Signature: (JLjava/lang/String;)V * Signature: (JLjava/lang/String;)J
*/ */
void Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2( jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) { JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path) {
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); return rocksdb_open_helper(env, jopt_handle, jdb_path,
rocksdb::DB* db = nullptr; (rocksdb::Status(*)
const char* db_path = env->GetStringUTFChars(jdb_path, 0); (const rocksdb::Options&, const std::string&, rocksdb::DB**)
rocksdb::Status s = rocksdb::DB::OpenForReadOnly(*opt, )&rocksdb::DB::Open
db_path, &db); );
env->ReleaseStringUTFChars(jdb_path, db_path);
if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db);
return;
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: openROnly * Method: openROnly
* Signature: (JLjava/lang/String;Ljava/util/List;I)Ljava/util/List; * Signature: (JLjava/lang/String;)J
*/ */
jobject jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2(
Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2Ljava_util_List_2I( JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path) {
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, return rocksdb_open_helper(env, jopt_handle, jdb_path, [](
jobject jcfdesc_list, jint jcfdesc_count) { const rocksdb::Options& options,
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); const std::string& db_path, rocksdb::DB** db) {
rocksdb::DB* db = nullptr; return rocksdb::DB::OpenForReadOnly(options, db_path, db);
const char* db_path = env->GetStringUTFChars(jdb_path, 0); });
}
std::vector<jbyte*> cfnames_to_free;
std::vector<jbyteArray> jcfnames_for_free; jlongArray rocksdb_open_helper(JNIEnv* env, jlong jopt_handle,
jstring jdb_path, jobjectArray jcolumn_names, jlongArray jcolumn_options,
std::function<rocksdb::Status(
const rocksdb::DBOptions&, const std::string&,
const std::vector<rocksdb::ColumnFamilyDescriptor>&,
std::vector<rocksdb::ColumnFamilyHandle*>*,
rocksdb::DB**)> open_fn
) {
auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
const char* db_path = env->GetStringUTFChars(jdb_path, NULL);
std::vector<rocksdb::ColumnFamilyDescriptor> column_families; std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
std::vector<rocksdb::ColumnFamilyHandle* > handles;
// get iterator for ColumnFamilyDescriptors
jobject iteratorObj = env->CallObjectMethod(
jcfdesc_list, rocksdb::ListJni::getIteratorMethod(env));
// iterate over ColumnFamilyDescriptors jsize len_cols = env->GetArrayLength(jcolumn_names);
while (env->CallBooleanMethod( jlong* jco = env->GetLongArrayElements(jcolumn_options, NULL);
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { for(int i = 0; i < len_cols; i++) {
// get ColumnFamilyDescriptor jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
jobject jcf_descriptor = env->CallObjectMethod(iteratorObj, jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
rocksdb::ListJni::getNextMethod(env)); jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, NULL);
// get ColumnFamilyName const int jcf_name_len = env->GetArrayLength(jcn_ba);
jbyteArray cf_name_in_byte_array = static_cast<jbyteArray>(
env->CallObjectMethod(jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyNameMethod(
env)));
// get CF Options
jobject jcf_opt_obj = env->CallObjectMethod(jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyOptionsMethod(
env));
rocksdb::ColumnFamilyOptions* cfOptions =
rocksdb::ColumnFamilyOptionsJni::getHandle(env, jcf_opt_obj);
jbyte* cfname = env->GetByteArrayElements(cf_name_in_byte_array, 0);
const int len = env->GetArrayLength(cf_name_in_byte_array);
// free allocated cfnames after call to open
cfnames_to_free.push_back(cfname);
jcfnames_for_free.push_back(cf_name_in_byte_array);
column_families.push_back(rocksdb::ColumnFamilyDescriptor(
std::string(reinterpret_cast<char *>(cfname), len), *cfOptions));
}
rocksdb::Status s = rocksdb::DB::OpenForReadOnly(*opt, //TODO(AR) do I need to make a copy of jco[i] ?
db_path, column_families, &handles, &db);
env->ReleaseStringUTFChars(jdb_path, db_path); std::string cf_name (reinterpret_cast<char *>(jcf_name), jcf_name_len);
// free jbyte allocations rocksdb::ColumnFamilyOptions* cf_options =
for (std::vector<jbyte*>::size_type i = 0; reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[i]);
i != cfnames_to_free.size(); i++) { column_families.push_back(
// free cfnames rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
env->ReleaseByteArrayElements(jcfnames_for_free[i], cfnames_to_free[i], 0);
env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
env->DeleteLocalRef(jcn);
} }
env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
std::vector<rocksdb::ColumnFamilyHandle*> handles;
rocksdb::DB* db = nullptr;
rocksdb::Status s = open_fn(*opt, db_path, column_families,
&handles, &db);
// check if open operation was successful // check if open operation was successful
if (s.ok()) { if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db); jsize resultsLen = 1 + len_cols; //db handle + column family handles
jclass jListClazz = env->FindClass("java/util/ArrayList"); jlong results[resultsLen];
jmethodID midList = rocksdb::ListJni::getArrayListConstructorMethodId( results[0] = reinterpret_cast<jlong>(db);
env, jListClazz); for(int i = 1; i <= len_cols; i++) {
jobject jcfhandle_list = env->NewObject(jListClazz, results[i] = reinterpret_cast<jlong>(handles[i - 1]);
midList, handles.size());
// insert in java list
for (std::vector<rocksdb::ColumnFamilyHandle*>::size_type i = 0;
i != handles.size(); i++) {
// jlong must be converted to Long due to collections restrictions
jclass jLongClazz = env->FindClass("java/lang/Long");
jmethodID midLong = env->GetMethodID(jLongClazz, "<init>", "(J)V");
jobject obj = env->NewObject(jLongClazz, midLong,
reinterpret_cast<jlong>(handles[i]));
env->CallBooleanMethod(jcfhandle_list,
rocksdb::ListJni::getListAddMethodId(env), obj);
} }
return jcfhandle_list; jlongArray jresults = env->NewLongArray(resultsLen);
env->SetLongArrayRegion(jresults, 0, resultsLen, results);
return jresults;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return NULL;
} }
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return nullptr;
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: open * Method: openROnly
* Signature: (JLjava/lang/String;Ljava/util/List;I)Ljava/util/List; * Signature: (JLjava/lang/String;[[B[J)[J
*/ */
jobject Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2Ljava_util_List_2I( jlongArray Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3J(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path,
jobject jcfdesc_list, jint jcfdesc_count) { jobjectArray jcolumn_names, jlongArray jcolumn_options) {
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); return rocksdb_open_helper(env, jopt_handle, jdb_path, jcolumn_names,
rocksdb::DB* db = nullptr; jcolumn_options, [](
const char* db_path = env->GetStringUTFChars(jdb_path, 0); const rocksdb::DBOptions& options, const std::string& db_path,
const std::vector<rocksdb::ColumnFamilyDescriptor>& column_families,
std::vector<jbyte*> cfnames_to_free; std::vector<rocksdb::ColumnFamilyHandle*>* handles, rocksdb::DB** db) {
std::vector<jbyteArray> jcfnames_for_free; return rocksdb::DB::OpenForReadOnly(options, db_path, column_families,
handles, db);
std::vector<rocksdb::ColumnFamilyDescriptor> column_families; });
std::vector<rocksdb::ColumnFamilyHandle* > handles; }
// get iterator for ColumnFamilyDescriptors
jobject iteratorObj = env->CallObjectMethod(
jcfdesc_list, rocksdb::ListJni::getIteratorMethod(env));
// iterate over ColumnFamilyDescriptors
while (env->CallBooleanMethod(
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
// get ColumnFamilyDescriptor
jobject jcf_descriptor = env->CallObjectMethod(iteratorObj,
rocksdb::ListJni::getNextMethod(env));
// get ColumnFamilyName
jbyteArray cf_name_in_byte_array = static_cast<jbyteArray>(
env->CallObjectMethod(jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyNameMethod(
env)));
// get CF Options
jobject jcf_opt_obj = env->CallObjectMethod(jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyOptionsMethod(
env));
rocksdb::ColumnFamilyOptions* cfOptions =
rocksdb::ColumnFamilyOptionsJni::getHandle(env, jcf_opt_obj);
jbyte* cfname = env->GetByteArrayElements(cf_name_in_byte_array, 0);
const int len = env->GetArrayLength(cf_name_in_byte_array);
// free allocated cfnames after call to open
cfnames_to_free.push_back(cfname);
jcfnames_for_free.push_back(cf_name_in_byte_array);
column_families.push_back(rocksdb::ColumnFamilyDescriptor(
std::string(reinterpret_cast<char *>(cfname), len), *cfOptions));
}
rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, column_families,
&handles, &db);
env->ReleaseStringUTFChars(jdb_path, db_path);
// free jbyte allocations
for (std::vector<jbyte*>::size_type i = 0;
i != cfnames_to_free.size(); i++) {
// free cfnames
env->ReleaseByteArrayElements(jcfnames_for_free[i], cfnames_to_free[i], 0);
}
// check if open operation was successful
if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db);
jclass jListClazz = env->FindClass("java/util/ArrayList");
jmethodID midList = rocksdb::ListJni::getArrayListConstructorMethodId(
env, jListClazz);
jobject jcfhandle_list = env->NewObject(jListClazz,
midList, handles.size());
// insert in java list
for (std::vector<rocksdb::ColumnFamilyHandle*>::size_type i = 0;
i != handles.size(); i++) {
// jlong must be converted to Long due to collections restrictions
jclass jLongClazz = env->FindClass("java/lang/Long");
jmethodID midLong = env->GetMethodID(jLongClazz, "<init>", "(J)V");
jobject obj = env->NewObject(jLongClazz, midLong,
reinterpret_cast<jlong>(handles[i]));
env->CallBooleanMethod(jcfhandle_list,
rocksdb::ListJni::getListAddMethodId(env), obj);
}
return jcfhandle_list; /*
} * Class: org_rocksdb_RocksDB
rocksdb::RocksDBExceptionJni::ThrowNew(env, s); * Method: open
return nullptr; * Signature: (JLjava/lang/String;[[B[J)[J
*/
jlongArray Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J(
JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path,
jobjectArray jcolumn_names, jlongArray jcolumn_options) {
return rocksdb_open_helper(env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
(rocksdb::Status(*)
(const rocksdb::DBOptions&, const std::string&,
const std::vector<rocksdb::ColumnFamilyDescriptor>&,
std::vector<rocksdb::ColumnFamilyHandle*>*, rocksdb::DB**)
)&rocksdb::DB::Open
);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

@ -22,12 +22,11 @@
/* /*
* Class: org_rocksdb_AbstractSlice * Class: org_rocksdb_AbstractSlice
* Method: createNewSliceFromString * Method: createNewSliceFromString
* Signature: (Ljava/lang/String;)V * Signature: (Ljava/lang/String;)J
*/ */
void Java_org_rocksdb_AbstractSlice_createNewSliceFromString( jlong Java_org_rocksdb_AbstractSlice_createNewSliceFromString(
JNIEnv* env, jobject jobj, jstring jstr) { JNIEnv * env, jclass jcls, jstring jstr) {
const auto* str = env->GetStringUTFChars(jstr, NULL);
const auto* str = env->GetStringUTFChars(jstr, 0);
const size_t len = strlen(str); const size_t len = strlen(str);
char* buf = new char[len + 1]; char* buf = new char[len + 1];
memcpy(buf, str, len); memcpy(buf, str, len);
@ -35,7 +34,7 @@ void Java_org_rocksdb_AbstractSlice_createNewSliceFromString(
env->ReleaseStringUTFChars(jstr, str); env->ReleaseStringUTFChars(jstr, str);
const auto* slice = new rocksdb::Slice(buf); const auto* slice = new rocksdb::Slice(buf);
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); return reinterpret_cast<jlong>(slice);
} }
/* /*
@ -115,10 +114,10 @@ void Java_org_rocksdb_AbstractSlice_disposeInternal(
/* /*
* Class: org_rocksdb_Slice * Class: org_rocksdb_Slice
* Method: createNewSlice0 * Method: createNewSlice0
* Signature: ([BI)V * Signature: ([BI)J
*/ */
void Java_org_rocksdb_Slice_createNewSlice0( jlong Java_org_rocksdb_Slice_createNewSlice0(
JNIEnv * env, jobject jobj, jbyteArray data, jint offset) { JNIEnv * env, jclass jcls, jbyteArray data, jint offset) {
const jsize dataSize = env->GetArrayLength(data); const jsize dataSize = env->GetArrayLength(data);
const int len = dataSize - offset; const int len = dataSize - offset;
@ -126,32 +125,33 @@ void Java_org_rocksdb_Slice_createNewSlice0(
env->GetByteArrayRegion(data, offset, len, ptrData); env->GetByteArrayRegion(data, offset, len, ptrData);
const auto* slice = new rocksdb::Slice((const char*)ptrData, len); const auto* slice = new rocksdb::Slice((const char*)ptrData, len);
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); return reinterpret_cast<jlong>(slice);
} }
/* /*
* Class: org_rocksdb_Slice * Class: org_rocksdb_Slice
* Method: createNewSlice1 * Method: createNewSlice1
* Signature: ([B)V * Signature: ([B)J
*/ */
void Java_org_rocksdb_Slice_createNewSlice1( jlong Java_org_rocksdb_Slice_createNewSlice1(
JNIEnv * env, jobject jobj, jbyteArray data) { JNIEnv * env, jclass jcls, jbyteArray data) {
const int len = env->GetArrayLength(data) + 1; const int len = env->GetArrayLength(data) + 1;
jboolean isCopy; jboolean isCopy;
jbyte* ptrData = env->GetByteArrayElements(data, &isCopy); jbyte* ptrData = env->GetByteArrayElements(data, &isCopy);
char* buf = new char[len];
// NOTE: buf will be deleted in the org.rocksdb.Slice#dispose method
char* buf = new char[len];
memcpy(buf, ptrData, len - 1); memcpy(buf, ptrData, len - 1);
buf[len-1]='\0'; buf[len-1]='\0';
const auto* slice = const auto* slice =
new rocksdb::Slice(buf, len - 1); new rocksdb::Slice(buf, len - 1);
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice);
env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT); env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT);
// NOTE: buf will be deleted in the org.rocksdb.Slice#dispose method
return reinterpret_cast<jlong>(slice);
} }
/* /*
@ -187,27 +187,27 @@ void Java_org_rocksdb_Slice_disposeInternalBuf(
/* /*
* Class: org_rocksdb_DirectSlice * Class: org_rocksdb_DirectSlice
* Method: createNewDirectSlice0 * Method: createNewDirectSlice0
* Signature: (Ljava/nio/ByteBuffer;I)V * Signature: (Ljava/nio/ByteBuffer;I)J
*/ */
void Java_org_rocksdb_DirectSlice_createNewDirectSlice0( jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0(
JNIEnv* env, jobject jobj, jobject data, jint length) { JNIEnv* env, jclass jcls, jobject data, jint length) {
const auto* ptrData = const auto* ptrData =
reinterpret_cast<char*>(env->GetDirectBufferAddress(data)); reinterpret_cast<char*>(env->GetDirectBufferAddress(data));
const auto* slice = new rocksdb::Slice(ptrData, length); const auto* slice = new rocksdb::Slice(ptrData, length);
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); return reinterpret_cast<jlong>(slice);
} }
/* /*
* Class: org_rocksdb_DirectSlice * Class: org_rocksdb_DirectSlice
* Method: createNewDirectSlice1 * Method: createNewDirectSlice1
* Signature: (Ljava/nio/ByteBuffer;)V * Signature: (Ljava/nio/ByteBuffer;)J
*/ */
void Java_org_rocksdb_DirectSlice_createNewDirectSlice1( jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1(
JNIEnv* env, jobject jobj, jobject data) { JNIEnv* env, jclass jcls, jobject data) {
const auto* ptrData = const auto* ptrData =
reinterpret_cast<char*>(env->GetDirectBufferAddress(data)); reinterpret_cast<char*>(env->GetDirectBufferAddress(data));
const auto* slice = new rocksdb::Slice(ptrData); const auto* slice = new rocksdb::Slice(ptrData);
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); return reinterpret_cast<jlong>(slice);
} }
/* /*

@ -20,10 +20,10 @@
/* /*
* Class: org_rocksdb_TtlDB * Class: org_rocksdb_TtlDB
* Method: open * Method: open
* Signature: (JLjava/lang/String;IZ)V * Signature: (JLjava/lang/String;IZ)J
*/ */
void Java_org_rocksdb_TtlDB_open(JNIEnv* env, jlong Java_org_rocksdb_TtlDB_open(JNIEnv* env,
jobject jttldb, jlong joptions_handle, jstring jdb_path, jclass jcls, jlong joptions_handle, jstring jdb_path,
jint jttl, jboolean jread_only) { jint jttl, jboolean jread_only) {
auto* opt = reinterpret_cast<rocksdb::Options*>(joptions_handle); auto* opt = reinterpret_cast<rocksdb::Options*>(joptions_handle);
rocksdb::DBWithTTL* db = nullptr; rocksdb::DBWithTTL* db = nullptr;
@ -35,113 +35,79 @@ void Java_org_rocksdb_TtlDB_open(JNIEnv* env,
// as TTLDB extends RocksDB on the java side, we can reuse // as TTLDB extends RocksDB on the java side, we can reuse
// the RocksDB portal here. // the RocksDB portal here.
if (s.ok()) { if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jttldb, db); return reinterpret_cast<jlong>(db);
return; } else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
} }
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
} }
/* /*
* Class: org_rocksdb_TtlDB * Class: org_rocksdb_TtlDB
* Method: openCF * Method: openCF
* Signature: (JLjava/lang/String;Ljava/util/List; * Signature: (JLjava/lang/String;[[B[J[IZ)[J
* ILjava/util/List;Z)Ljava/util/List;
*/ */
jobject jlongArray
Java_org_rocksdb_TtlDB_openCF( Java_org_rocksdb_TtlDB_openCF(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path,
jobject jcfdesc_list, jint jcfdesc_count, jobject jttl_list, jobjectArray jcolumn_names, jlongArray jcolumn_options,
jboolean jread_only) { jintArray jttls, jboolean jread_only) {
auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
rocksdb::DBWithTTL* db = nullptr; const char* db_path = env->GetStringUTFChars(jdb_path, NULL);
const char* db_path = env->GetStringUTFChars(jdb_path, 0);
std::vector<jbyte*> cfnames_to_free;
std::vector<jbyteArray> jcfnames_for_free;
std::vector<rocksdb::ColumnFamilyDescriptor> column_families; std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
std::vector<int32_t> ttl_values;
std::vector<rocksdb::ColumnFamilyHandle* > handles; jsize len_cols = env->GetArrayLength(jcolumn_names);
// get iterator for ColumnFamilyDescriptors jlong* jco = env->GetLongArrayElements(jcolumn_options, NULL);
jobject iteratorObj = env->CallObjectMethod( for(int i = 0; i < len_cols; i++) {
jcfdesc_list, rocksdb::ListJni::getIteratorMethod(env)); jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
// iterate over ColumnFamilyDescriptors jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, NULL);
while (env->CallBooleanMethod( const int jcf_name_len = env->GetArrayLength(jcn_ba);
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
// get ColumnFamilyDescriptor //TODO(AR) do I need to make a copy of jco[i] ?
jobject jcf_descriptor = env->CallObjectMethod(iteratorObj,
rocksdb::ListJni::getNextMethod(env)); std::string cf_name (reinterpret_cast<char *>(jcf_name), jcf_name_len);
// get ColumnFamilyName rocksdb::ColumnFamilyOptions* cf_options =
jbyteArray byteArray = static_cast<jbyteArray>(env->CallObjectMethod( reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[i]);
jcf_descriptor, column_families.push_back(
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyNameMethod( rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
env)));
// get CF Options env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
jobject jcf_opt_obj = env->CallObjectMethod(jcf_descriptor, env->DeleteLocalRef(jcn);
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyOptionsMethod(
env));
rocksdb::ColumnFamilyOptions* cfOptions =
rocksdb::ColumnFamilyOptionsJni::getHandle(env, jcf_opt_obj);
jbyte* cfname = env->GetByteArrayElements(byteArray, 0);
const int len = env->GetArrayLength(byteArray);
// free allocated cfnames after call to open
cfnames_to_free.push_back(cfname);
jcfnames_for_free.push_back(byteArray);
column_families.push_back(rocksdb::ColumnFamilyDescriptor(
std::string(reinterpret_cast<char *>(cfname), len), *cfOptions));
} }
// get iterator for TTL values env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
iteratorObj = env->CallObjectMethod(
jttl_list, rocksdb::ListJni::getIteratorMethod(env)); std::vector<rocksdb::ColumnFamilyHandle*> handles;
// iterate over TTL values rocksdb::DBWithTTL* db = nullptr;
while (env->CallBooleanMethod(
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { std::vector<int32_t> ttl_values;
// get TTL object jint* jttlv = env->GetIntArrayElements(jttls, NULL);
jobject jttl_object = env->CallObjectMethod(iteratorObj, jsize len_ttls = env->GetArrayLength(jttls);
rocksdb::ListJni::getNextMethod(env)); for(int i = 0; i < len_ttls; i++) {
// get Integer value ttl_values.push_back(jttlv[i]);
jclass jIntClazz = env->FindClass("java/lang/Integer");
jmethodID getVal = env->GetMethodID(jIntClazz, "intValue", "()I");
ttl_values.push_back(env->CallIntMethod(jttl_object, getVal));
} }
env->ReleaseIntArrayElements(jttls, jttlv, JNI_ABORT);
rocksdb::Status s = rocksdb::DBWithTTL::Open(*opt, db_path, column_families, rocksdb::Status s = rocksdb::DBWithTTL::Open(*opt, db_path, column_families,
&handles, &db, ttl_values, jread_only); &handles, &db, ttl_values, jread_only);
env->ReleaseStringUTFChars(jdb_path, db_path);
// free jbyte allocations
for (std::vector<jbyte*>::size_type i = 0;
i != cfnames_to_free.size(); i++) {
// free cfnames
env->ReleaseByteArrayElements(jcfnames_for_free[i], cfnames_to_free[i], 0);
}
// check if open operation was successful // check if open operation was successful
if (s.ok()) { if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db); jsize resultsLen = 1 + len_cols; //db handle + column family handles
jclass jListClazz = env->FindClass("java/util/ArrayList"); jlong results[resultsLen];
jmethodID midList = rocksdb::ListJni::getArrayListConstructorMethodId( results[0] = reinterpret_cast<jlong>(db);
env, jListClazz); for(int i = 1; i <= len_cols; i++) {
jobject jcfhandle_list = env->NewObject(jListClazz, results[i] = reinterpret_cast<jlong>(handles[i - 1]);
midList, handles.size());
// insert in java list
for (std::vector<rocksdb::ColumnFamilyHandle*>::size_type i = 0;
i != handles.size(); i++) {
// jlong must be converted to Long due to collections restrictions
jclass jLongClazz = env->FindClass("java/lang/Long");
jmethodID midLong = env->GetMethodID(jLongClazz, "<init>", "(J)V");
jobject obj = env->NewObject(jLongClazz, midLong,
reinterpret_cast<jlong>(handles[i]));
env->CallBooleanMethod(jcfhandle_list,
rocksdb::ListJni::getListAddMethodId(env), obj);
} }
return jcfhandle_list; jlongArray jresults = env->NewLongArray(resultsLen);
env->SetLongArrayRegion(jresults, 0, resultsLen, results);
return jresults;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return NULL;
} }
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return nullptr;
} }
/* /*

@ -27,14 +27,13 @@
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: newWriteBatch * Method: newWriteBatch
* Signature: (I)V * Signature: (I)J
*/ */
void Java_org_rocksdb_WriteBatch_newWriteBatch( jlong Java_org_rocksdb_WriteBatch_newWriteBatch(
JNIEnv* env, jobject jobj, jint jreserved_bytes) { JNIEnv* env, jclass jcls, jint jreserved_bytes) {
rocksdb::WriteBatch* wb = new rocksdb::WriteBatch( rocksdb::WriteBatch* wb = new rocksdb::WriteBatch(
static_cast<size_t>(jreserved_bytes)); static_cast<size_t>(jreserved_bytes));
return reinterpret_cast<jlong>(wb);
rocksdb::WriteBatchJni::setHandle(env, jobj, wb);
} }
/* /*
@ -218,13 +217,13 @@ void Java_org_rocksdb_WriteBatch_disposeInternal(
/* /*
* Class: org_rocksdb_WriteBatch_Handler * Class: org_rocksdb_WriteBatch_Handler
* Method: createNewHandler0 * Method: createNewHandler0
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0( jlong Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0(
JNIEnv* env, jobject jobj) { JNIEnv* env, jobject jobj) {
const rocksdb::WriteBatchHandlerJniCallback* h = const rocksdb::WriteBatchHandlerJniCallback* h =
new rocksdb::WriteBatchHandlerJniCallback(env, jobj); new rocksdb::WriteBatchHandlerJniCallback(env, jobj);
rocksdb::WriteBatchHandlerJni::setHandle(env, jobj, h); return reinterpret_cast<jlong>(h);
} }
/* /*

@ -15,40 +15,40 @@
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: newWriteBatchWithIndex * Method: newWriteBatchWithIndex
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__( jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex(); rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex();
rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); return reinterpret_cast<jlong>(wbwi);
} }
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: newWriteBatchWithIndex * Method: newWriteBatchWithIndex
* Signature: (Z)V * Signature: (Z)J
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z( jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z(
JNIEnv* env, jobject jobj, jboolean joverwrite_key) { JNIEnv* env, jclass jcls, jboolean joverwrite_key) {
rocksdb::WriteBatchWithIndex* wbwi = rocksdb::WriteBatchWithIndex* wbwi =
new rocksdb::WriteBatchWithIndex(rocksdb::BytewiseComparator(), 0, new rocksdb::WriteBatchWithIndex(rocksdb::BytewiseComparator(), 0,
static_cast<bool>(joverwrite_key)); static_cast<bool>(joverwrite_key));
rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); return reinterpret_cast<jlong>(wbwi);
} }
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: newWriteBatchWithIndex * Method: newWriteBatchWithIndex
* Signature: (JIZ)V * Signature: (JIZ)J
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ( jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ(
JNIEnv* env, jobject jobj, jlong jfallback_index_comparator_handle, JNIEnv* env, jclass jcls, jlong jfallback_index_comparator_handle,
jint jreserved_bytes, jboolean joverwrite_key) { jint jreserved_bytes, jboolean joverwrite_key) {
rocksdb::WriteBatchWithIndex* wbwi = rocksdb::WriteBatchWithIndex* wbwi =
new rocksdb::WriteBatchWithIndex( new rocksdb::WriteBatchWithIndex(
reinterpret_cast<rocksdb::Comparator*>(jfallback_index_comparator_handle), reinterpret_cast<rocksdb::Comparator*>(jfallback_index_comparator_handle),
static_cast<size_t>(jreserved_bytes), static_cast<bool>(joverwrite_key)); static_cast<size_t>(jreserved_bytes), static_cast<bool>(joverwrite_key));
rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); return reinterpret_cast<jlong>(wbwi);
} }
/* /*

@ -13,6 +13,10 @@ package org.rocksdb;
public abstract class AbstractCompactionFilter<T extends AbstractSlice<?>> public abstract class AbstractCompactionFilter<T extends AbstractSlice<?>>
extends RocksObject { extends RocksObject {
protected AbstractCompactionFilter(final long nativeHandle) {
super(nativeHandle);
}
/** /**
* Deletes underlying C++ comparator pointer. * Deletes underlying C++ comparator pointer.
* *
@ -20,10 +24,6 @@ public abstract class AbstractCompactionFilter<T extends AbstractSlice<?>>
* RocksDB instances referencing the comparator are closed. * RocksDB instances referencing the comparator are closed.
* Otherwise an undefined behavior will occur. * Otherwise an undefined behavior will occur.
*/ */
@Override protected void disposeInternal() { @Override
assert(isInitialized()); protected final native void disposeInternal(final long handle);
disposeInternal(nativeHandle_);
}
private native void disposeInternal(long handle);
} }

@ -14,8 +14,11 @@ package org.rocksdb;
* @see org.rocksdb.Comparator * @see org.rocksdb.Comparator
* @see org.rocksdb.DirectComparator * @see org.rocksdb.DirectComparator
*/ */
public abstract class AbstractComparator<T extends AbstractSlice<?>> public abstract class AbstractComparator<T extends AbstractSlice<?>> extends NativeReference {
extends RocksObject {
protected AbstractComparator() {
super(true);
}
/** /**
* The name of the comparator. Used to check for comparator * The name of the comparator. Used to check for comparator
@ -91,10 +94,12 @@ public abstract class AbstractComparator<T extends AbstractSlice<?>>
* RocksDB instances referencing the comparator are closed. * RocksDB instances referencing the comparator are closed.
* Otherwise an undefined behavior will occur. * Otherwise an undefined behavior will occur.
*/ */
@Override protected void disposeInternal() { @Override
assert(isInitialized()); protected void disposeInternal() {
disposeInternal(nativeHandle_); disposeInternal(getNativeHandle());
} }
private native void disposeInternal(long handle); protected abstract long getNativeHandle();
private native void disposeInternal(final long handle);
} }

@ -25,8 +25,7 @@ public abstract class AbstractRocksIterator<P extends RocksObject>
protected AbstractRocksIterator(final P parent, protected AbstractRocksIterator(final P parent,
final long nativeHandle) { final long nativeHandle) {
super(); super(nativeHandle);
nativeHandle_ = nativeHandle;
// parent must point to a valid RocksDB instance. // parent must point to a valid RocksDB instance.
assert (parent != null); assert (parent != null);
// RocksIterator must hold a reference to the related parent instance // RocksIterator must hold a reference to the related parent instance
@ -37,43 +36,43 @@ public abstract class AbstractRocksIterator<P extends RocksObject>
@Override @Override
public boolean isValid() { public boolean isValid() {
assert (isInitialized()); assert (isOwningHandle());
return isValid0(nativeHandle_); return isValid0(nativeHandle_);
} }
@Override @Override
public void seekToFirst() { public void seekToFirst() {
assert (isInitialized()); assert (isOwningHandle());
seekToFirst0(nativeHandle_); seekToFirst0(nativeHandle_);
} }
@Override @Override
public void seekToLast() { public void seekToLast() {
assert (isInitialized()); assert (isOwningHandle());
seekToLast0(nativeHandle_); seekToLast0(nativeHandle_);
} }
@Override @Override
public void seek(byte[] target) { public void seek(byte[] target) {
assert (isInitialized()); assert (isOwningHandle());
seek0(nativeHandle_, target, target.length); seek0(nativeHandle_, target, target.length);
} }
@Override @Override
public void next() { public void next() {
assert (isInitialized()); assert (isOwningHandle());
next0(nativeHandle_); next0(nativeHandle_);
} }
@Override @Override
public void prev() { public void prev() {
assert (isInitialized()); assert (isOwningHandle());
prev0(nativeHandle_); prev0(nativeHandle_);
} }
@Override @Override
public void status() throws RocksDBException { public void status() throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
status0(nativeHandle_); status0(nativeHandle_);
} }
@ -87,15 +86,11 @@ public abstract class AbstractRocksIterator<P extends RocksObject>
*/ */
@Override @Override
protected void disposeInternal() { protected void disposeInternal() {
synchronized (parent_) { if (parent_.isOwningHandle()) {
assert (isInitialized());
if (parent_.isInitialized()) {
disposeInternal(nativeHandle_); disposeInternal(nativeHandle_);
} }
}
} }
abstract void disposeInternal(long handle);
abstract boolean isValid0(long handle); abstract boolean isValid0(long handle);
abstract void seekToFirst0(long handle); abstract void seekToFirst0(long handle);
abstract void seekToLast0(long handle); abstract void seekToLast0(long handle);

@ -24,7 +24,15 @@ package org.rocksdb;
* C++ BaseComparatorJniCallback subclass, which in turn destroys the * C++ BaseComparatorJniCallback subclass, which in turn destroys the
* Java @see org.rocksdb.AbstractSlice subclass Objects. * Java @see org.rocksdb.AbstractSlice subclass Objects.
*/ */
abstract class AbstractSlice<T> extends RocksObject { abstract class AbstractSlice<T> extends RocksMutableObject {
protected AbstractSlice() {
super();
}
protected AbstractSlice(final long nativeHandle) {
super(nativeHandle);
}
/** /**
* Returns the data of the slice. * Returns the data of the slice.
@ -34,7 +42,7 @@ abstract class AbstractSlice<T> extends RocksObject {
* @see org.rocksdb.AbstractSlice#data0(long) * @see org.rocksdb.AbstractSlice#data0(long)
*/ */
public T data() { public T data() {
assert (isInitialized()); assert (isOwningHandle());
return data0(nativeHandle_); return data0(nativeHandle_);
} }
@ -56,7 +64,7 @@ abstract class AbstractSlice<T> extends RocksObject {
* @return The length in bytes. * @return The length in bytes.
*/ */
public int size() { public int size() {
assert (isInitialized()); assert (isOwningHandle());
return size0(nativeHandle_); return size0(nativeHandle_);
} }
@ -67,7 +75,7 @@ abstract class AbstractSlice<T> extends RocksObject {
* @return true if there is no data, false otherwise. * @return true if there is no data, false otherwise.
*/ */
public boolean empty() { public boolean empty() {
assert (isInitialized()); assert (isOwningHandle());
return empty0(nativeHandle_); return empty0(nativeHandle_);
} }
@ -80,7 +88,7 @@ abstract class AbstractSlice<T> extends RocksObject {
* @return The string representation of the data. * @return The string representation of the data.
*/ */
public String toString(final boolean hex) { public String toString(final boolean hex) {
assert (isInitialized()); assert (isOwningHandle());
return toString0(nativeHandle_, hex); return toString0(nativeHandle_, hex);
} }
@ -101,7 +109,7 @@ abstract class AbstractSlice<T> extends RocksObject {
*/ */
public int compare(final AbstractSlice<?> other) { public int compare(final AbstractSlice<?> other) {
assert (other != null); assert (other != null);
assert (isInitialized()); assert (isOwningHandle());
return compare0(nativeHandle_, other.nativeHandle_); return compare0(nativeHandle_, other.nativeHandle_);
} }
@ -141,13 +149,20 @@ abstract class AbstractSlice<T> extends RocksObject {
*/ */
public boolean startsWith(final AbstractSlice<?> prefix) { public boolean startsWith(final AbstractSlice<?> prefix) {
if (prefix != null) { if (prefix != null) {
assert (isInitialized()); assert (isOwningHandle());
return startsWith0(nativeHandle_, prefix.nativeHandle_); return startsWith0(nativeHandle_, prefix.nativeHandle_);
} else { } else {
return false; return false;
} }
} }
protected native static long createNewSliceFromString(final String str);
private native int size0(long handle);
private native boolean empty0(long handle);
private native String toString0(long handle, boolean hex);
private native int compare0(long handle, long otherHandle);
private native boolean startsWith0(long handle, long otherHandle);
/** /**
* Deletes underlying C++ slice pointer. * Deletes underlying C++ slice pointer.
* Note that this function should be called only after all * Note that this function should be called only after all
@ -155,17 +170,6 @@ abstract class AbstractSlice<T> extends RocksObject {
* Otherwise an undefined behavior will occur. * Otherwise an undefined behavior will occur.
*/ */
@Override @Override
protected void disposeInternal() { protected final native void disposeInternal(final long handle);
assert(isInitialized());
disposeInternal(nativeHandle_);
}
protected native void createNewSliceFromString(String str);
private native int size0(long handle);
private native boolean empty0(long handle);
private native String toString0(long handle, boolean hex);
private native int compare0(long handle, long otherHandle);
private native boolean startsWith0(long handle, long otherHandle);
private native void disposeInternal(long handle);
} }

@ -7,71 +7,64 @@ package org.rocksdb;
public abstract class AbstractWriteBatch extends RocksObject implements WriteBatchInterface { public abstract class AbstractWriteBatch extends RocksObject implements WriteBatchInterface {
protected AbstractWriteBatch(final long nativeHandle) {
super(nativeHandle);
}
@Override @Override
public int count() { public int count() {
assert (isInitialized()); assert (isOwningHandle());
return count0(); return count0();
} }
@Override @Override
public void put(byte[] key, byte[] value) { public void put(byte[] key, byte[] value) {
assert (isInitialized()); assert (isOwningHandle());
put(key, key.length, value, value.length); put(key, key.length, value, value.length);
} }
@Override @Override
public void put(ColumnFamilyHandle columnFamilyHandle, byte[] key, byte[] value) { public void put(ColumnFamilyHandle columnFamilyHandle, byte[] key, byte[] value) {
assert (isInitialized()); assert (isOwningHandle());
put(key, key.length, value, value.length, columnFamilyHandle.nativeHandle_); put(key, key.length, value, value.length, columnFamilyHandle.nativeHandle_);
} }
@Override @Override
public void merge(byte[] key, byte[] value) { public void merge(byte[] key, byte[] value) {
assert (isInitialized()); assert (isOwningHandle());
merge(key, key.length, value, value.length); merge(key, key.length, value, value.length);
} }
@Override @Override
public void merge(ColumnFamilyHandle columnFamilyHandle, byte[] key, byte[] value) { public void merge(ColumnFamilyHandle columnFamilyHandle, byte[] key, byte[] value) {
assert (isInitialized()); assert (isOwningHandle());
merge(key, key.length, value, value.length, columnFamilyHandle.nativeHandle_); merge(key, key.length, value, value.length, columnFamilyHandle.nativeHandle_);
} }
@Override @Override
public void remove(byte[] key) { public void remove(byte[] key) {
assert (isInitialized()); assert (isOwningHandle());
remove(key, key.length); remove(key, key.length);
} }
@Override @Override
public void remove(ColumnFamilyHandle columnFamilyHandle, byte[] key) { public void remove(ColumnFamilyHandle columnFamilyHandle, byte[] key) {
assert (isInitialized()); assert (isOwningHandle());
remove(key, key.length, columnFamilyHandle.nativeHandle_); remove(key, key.length, columnFamilyHandle.nativeHandle_);
} }
@Override @Override
public void putLogData(byte[] blob) { public void putLogData(byte[] blob) {
assert (isInitialized()); assert (isOwningHandle());
putLogData(blob, blob.length); putLogData(blob, blob.length);
} }
@Override @Override
public void clear() { public void clear() {
assert (isInitialized()); assert (isOwningHandle());
clear0(); clear0();
} }
/**
* Delete the c++ side pointer.
*/
@Override
protected void disposeInternal() {
assert (isInitialized());
disposeInternal(nativeHandle_);
}
abstract void disposeInternal(long handle);
abstract int count0(); abstract int count0();
abstract void put(byte[] key, int keyLen, byte[] value, int valueLen); abstract void put(byte[] key, int keyLen, byte[] value, int valueLen);

@ -19,8 +19,8 @@ import java.util.List;
*/ */
public class BackupEngine extends RocksObject implements AutoCloseable { public class BackupEngine extends RocksObject implements AutoCloseable {
protected BackupEngine() { protected BackupEngine(final long nativeHandle) {
super(); super(nativeHandle);
} }
/** /**
@ -33,9 +33,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
*/ */
public static BackupEngine open(final Env env, public static BackupEngine open(final Env env,
final BackupableDBOptions options) throws RocksDBException { final BackupableDBOptions options) throws RocksDBException {
final BackupEngine be = new BackupEngine(); return new BackupEngine(open(env.nativeHandle_, options.nativeHandle_));
be.open(env.nativeHandle_, options.nativeHandle_);
return be;
} }
/** /**
@ -74,7 +72,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
public void createNewBackup( public void createNewBackup(
final RocksDB db, final boolean flushBeforeBackup) final RocksDB db, final boolean flushBeforeBackup)
throws RocksDBException { throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
createNewBackup(nativeHandle_, db.nativeHandle_, flushBeforeBackup); createNewBackup(nativeHandle_, db.nativeHandle_, flushBeforeBackup);
} }
@ -85,7 +83,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @return A list of information about each available backup * @return A list of information about each available backup
*/ */
public List<BackupInfo> getBackupInfo() { public List<BackupInfo> getBackupInfo() {
assert (isInitialized()); assert (isOwningHandle());
return getBackupInfo(nativeHandle_); return getBackupInfo(nativeHandle_);
} }
@ -97,7 +95,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @return array of backup ids as int ids. * @return array of backup ids as int ids.
*/ */
public int[] getCorruptedBackups() { public int[] getCorruptedBackups() {
assert(isInitialized()); assert(isOwningHandle());
return getCorruptedBackups(nativeHandle_); return getCorruptedBackups(nativeHandle_);
} }
@ -110,7 +108,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* native library. * native library.
*/ */
public void garbageCollect() throws RocksDBException { public void garbageCollect() throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
garbageCollect(nativeHandle_); garbageCollect(nativeHandle_);
} }
@ -121,7 +119,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
*/ */
public void purgeOldBackups( public void purgeOldBackups(
final int numBackupsToKeep) throws RocksDBException { final int numBackupsToKeep) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
purgeOldBackups(nativeHandle_, numBackupsToKeep); purgeOldBackups(nativeHandle_, numBackupsToKeep);
} }
@ -131,7 +129,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @param backupId The id of the backup to delete * @param backupId The id of the backup to delete
*/ */
public void deleteBackup(final int backupId) throws RocksDBException { public void deleteBackup(final int backupId) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
deleteBackup(nativeHandle_, backupId); deleteBackup(nativeHandle_, backupId);
} }
@ -158,7 +156,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
public void restoreDbFromBackup( public void restoreDbFromBackup(
final int backupId, final String dbDir, final String walDir, final int backupId, final String dbDir, final String walDir,
final RestoreOptions restoreOptions) throws RocksDBException { final RestoreOptions restoreOptions) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
restoreDbFromBackup(nativeHandle_, backupId, dbDir, walDir, restoreDbFromBackup(nativeHandle_, backupId, dbDir, walDir,
restoreOptions.nativeHandle_); restoreOptions.nativeHandle_);
} }
@ -173,7 +171,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
public void restoreDbFromLatestBackup( public void restoreDbFromLatestBackup(
final String dbDir, final String walDir, final String dbDir, final String walDir,
final RestoreOptions restoreOptions) throws RocksDBException { final RestoreOptions restoreOptions) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
restoreDbFromLatestBackup(nativeHandle_, dbDir, walDir, restoreDbFromLatestBackup(nativeHandle_, dbDir, walDir,
restoreOptions.nativeHandle_); restoreOptions.nativeHandle_);
} }
@ -186,14 +184,8 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
dispose(); dispose();
} }
@Override private native static long open(final long env,
protected void disposeInternal() { final long backupableDbOptions) throws RocksDBException;
assert (isInitialized());
disposeInternal(nativeHandle_);
}
private native void open(final long env, final long backupableDbOptions)
throws RocksDBException;
private native void createNewBackup(final long handle, final long dbHandle, private native void createNewBackup(final long handle, final long dbHandle,
final boolean flushBeforeBackup) throws RocksDBException; final boolean flushBeforeBackup) throws RocksDBException;
@ -218,5 +210,5 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
final String dbDir, final String walDir, final long restoreOptionsHandle) final String dbDir, final String walDir, final long restoreOptionsHandle)
throws RocksDBException; throws RocksDBException;
private native void disposeInternal(final long handle); @Override protected final native void disposeInternal(final long handle);
} }

@ -33,9 +33,8 @@ public class BackupableDB extends RocksDB {
final Options opt, final BackupableDBOptions bopt, final String db_path) final Options opt, final BackupableDBOptions bopt, final String db_path)
throws RocksDBException { throws RocksDBException {
RocksDB db = RocksDB.open(opt, db_path); final RocksDB db = RocksDB.open(opt, db_path);
BackupableDB bdb = new BackupableDB(); final BackupableDB bdb = new BackupableDB(open(db.nativeHandle_, bopt.nativeHandle_));
bdb.open(db.nativeHandle_, bopt.nativeHandle_);
// Prevent the RocksDB object from attempting to delete // Prevent the RocksDB object from attempting to delete
// the underly C++ DB object. // the underly C++ DB object.
@ -56,7 +55,7 @@ public class BackupableDB extends RocksDB {
*/ */
public void createNewBackup(final boolean flushBeforeBackup) public void createNewBackup(final boolean flushBeforeBackup)
throws RocksDBException { throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
createNewBackup(nativeHandle_, flushBeforeBackup); createNewBackup(nativeHandle_, flushBeforeBackup);
} }
@ -70,7 +69,7 @@ public class BackupableDB extends RocksDB {
*/ */
public void purgeOldBackups(final int numBackupsToKeep) public void purgeOldBackups(final int numBackupsToKeep)
throws RocksDBException { throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
purgeOldBackups(nativeHandle_, numBackupsToKeep); purgeOldBackups(nativeHandle_, numBackupsToKeep);
} }
@ -83,7 +82,7 @@ public class BackupableDB extends RocksDB {
* native library. * native library.
*/ */
public void deleteBackup(final int backupId) throws RocksDBException { public void deleteBackup(final int backupId) throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
deleteBackup0(nativeHandle_, backupId); deleteBackup0(nativeHandle_, backupId);
} }
@ -94,7 +93,7 @@ public class BackupableDB extends RocksDB {
* @return List of {@link BackupInfo} instances. * @return List of {@link BackupInfo} instances.
*/ */
public List<BackupInfo> getBackupInfos() { public List<BackupInfo> getBackupInfos() {
assert(isInitialized()); assert(isOwningHandle());
return getBackupInfo(nativeHandle_); return getBackupInfo(nativeHandle_);
} }
@ -106,7 +105,7 @@ public class BackupableDB extends RocksDB {
* @return array of backup ids as int ids. * @return array of backup ids as int ids.
*/ */
public int[] getCorruptedBackups() { public int[] getCorruptedBackups() {
assert(isInitialized()); assert(isOwningHandle());
return getCorruptedBackups(nativeHandle_); return getCorruptedBackups(nativeHandle_);
} }
@ -119,7 +118,7 @@ public class BackupableDB extends RocksDB {
* native library. * native library.
*/ */
public void garbageCollect() throws RocksDBException { public void garbageCollect() throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
garbageCollect(nativeHandle_); garbageCollect(nativeHandle_);
} }
@ -132,19 +131,19 @@ public class BackupableDB extends RocksDB {
* of the c++ {@code rocksdb::BackupableDB} and should be transparent * of the c++ {@code rocksdb::BackupableDB} and should be transparent
* to Java developers.</p> * to Java developers.</p>
*/ */
@Override public synchronized void close() { @Override public void close() {
if (isInitialized()) {
super.close(); super.close();
}
} }
/** /**
* <p>A protected construction that will be used in the static * <p>A protected construction that will be used in the static
* factory method {@link #open(Options, BackupableDBOptions, String)}. * factory method {@link #open(Options, BackupableDBOptions, String)}.
* </p> * </p>
*
* @param nativeHandle The native handle of the C++ BackupableDB object
*/ */
protected BackupableDB() { protected BackupableDB(final long nativeHandle) {
super(); super(nativeHandle);
} }
@Override protected void finalize() throws Throwable { @Override protected void finalize() throws Throwable {
@ -152,7 +151,7 @@ public class BackupableDB extends RocksDB {
super.finalize(); super.finalize();
} }
protected native void open(long rocksDBHandle, long backupDBOptionsHandle); protected native static long open(final long rocksDBHandle, final long backupDBOptionsHandle);
protected native void createNewBackup(long handle, boolean flag) protected native void createNewBackup(long handle, boolean flag)
throws RocksDBException; throws RocksDBException;
protected native void purgeOldBackups(long handle, int numBackupsToKeep) protected native void purgeOldBackups(long handle, int numBackupsToKeep)

@ -6,7 +6,6 @@
package org.rocksdb; package org.rocksdb;
import java.io.File; import java.io.File;
import java.nio.file.Path;
/** /**
* <p>BackupableDBOptions to control the behavior of a backupable database. * <p>BackupableDBOptions to control the behavior of a backupable database.
@ -27,12 +26,16 @@ public class BackupableDBOptions extends RocksObject {
* @throws java.lang.IllegalArgumentException if illegal path is used. * @throws java.lang.IllegalArgumentException if illegal path is used.
*/ */
public BackupableDBOptions(final String path) { public BackupableDBOptions(final String path) {
super(); super(newBackupableDBOptions(ensureWritableFile(path)));
File backupPath = path == null ? null : new File(path); }
private static String ensureWritableFile(final String path) {
final File backupPath = path == null ? null : new File(path);
if (backupPath == null || !backupPath.isDirectory() || !backupPath.canWrite()) { if (backupPath == null || !backupPath.isDirectory() || !backupPath.canWrite()) {
throw new IllegalArgumentException("Illegal path provided."); throw new IllegalArgumentException("Illegal path provided.");
} else {
return path;
} }
newBackupableDBOptions(path);
} }
/** /**
@ -41,7 +44,7 @@ public class BackupableDBOptions extends RocksObject {
* @return the path to the BackupableDB directory. * @return the path to the BackupableDB directory.
*/ */
public String backupDir() { public String backupDir() {
assert(isInitialized()); assert(isOwningHandle());
return backupDir(nativeHandle_); return backupDir(nativeHandle_);
} }
@ -58,7 +61,7 @@ public class BackupableDBOptions extends RocksObject {
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setShareTableFiles(final boolean shareTableFiles) { public BackupableDBOptions setShareTableFiles(final boolean shareTableFiles) {
assert(isInitialized()); assert(isOwningHandle());
setShareTableFiles(nativeHandle_, shareTableFiles); setShareTableFiles(nativeHandle_, shareTableFiles);
return this; return this;
} }
@ -70,7 +73,7 @@ public class BackupableDBOptions extends RocksObject {
* backups. * backups.
*/ */
public boolean shareTableFiles() { public boolean shareTableFiles() {
assert(isInitialized()); assert(isOwningHandle());
return shareTableFiles(nativeHandle_); return shareTableFiles(nativeHandle_);
} }
@ -87,7 +90,7 @@ public class BackupableDBOptions extends RocksObject {
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setSync(final boolean sync) { public BackupableDBOptions setSync(final boolean sync) {
assert(isInitialized()); assert(isOwningHandle());
setSync(nativeHandle_, sync); setSync(nativeHandle_, sync);
return this; return this;
} }
@ -98,7 +101,7 @@ public class BackupableDBOptions extends RocksObject {
* @return boolean value if synchronous backups are configured. * @return boolean value if synchronous backups are configured.
*/ */
public boolean sync() { public boolean sync() {
assert(isInitialized()); assert(isOwningHandle());
return sync(nativeHandle_); return sync(nativeHandle_);
} }
@ -112,7 +115,7 @@ public class BackupableDBOptions extends RocksObject {
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setDestroyOldData(final boolean destroyOldData) { public BackupableDBOptions setDestroyOldData(final boolean destroyOldData) {
assert(isInitialized()); assert(isOwningHandle());
setDestroyOldData(nativeHandle_, destroyOldData); setDestroyOldData(nativeHandle_, destroyOldData);
return this; return this;
} }
@ -123,7 +126,7 @@ public class BackupableDBOptions extends RocksObject {
* @return boolean value indicating if old data will be destroyed. * @return boolean value indicating if old data will be destroyed.
*/ */
public boolean destroyOldData() { public boolean destroyOldData() {
assert(isInitialized()); assert(isOwningHandle());
return destroyOldData(nativeHandle_); return destroyOldData(nativeHandle_);
} }
@ -139,7 +142,7 @@ public class BackupableDBOptions extends RocksObject {
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setBackupLogFiles(final boolean backupLogFiles) { public BackupableDBOptions setBackupLogFiles(final boolean backupLogFiles) {
assert(isInitialized()); assert(isOwningHandle());
setBackupLogFiles(nativeHandle_, backupLogFiles); setBackupLogFiles(nativeHandle_, backupLogFiles);
return this; return this;
} }
@ -150,7 +153,7 @@ public class BackupableDBOptions extends RocksObject {
* @return boolean value indicating if log files will be persisted. * @return boolean value indicating if log files will be persisted.
*/ */
public boolean backupLogFiles() { public boolean backupLogFiles() {
assert(isInitialized()); assert(isOwningHandle());
return backupLogFiles(nativeHandle_); return backupLogFiles(nativeHandle_);
} }
@ -165,7 +168,7 @@ public class BackupableDBOptions extends RocksObject {
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setBackupRateLimit(long backupRateLimit) { public BackupableDBOptions setBackupRateLimit(long backupRateLimit) {
assert(isInitialized()); assert(isOwningHandle());
backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit; backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit;
setBackupRateLimit(nativeHandle_, backupRateLimit); setBackupRateLimit(nativeHandle_, backupRateLimit);
return this; return this;
@ -178,7 +181,7 @@ public class BackupableDBOptions extends RocksObject {
* @return numerical value describing the backup transfer limit in bytes per second. * @return numerical value describing the backup transfer limit in bytes per second.
*/ */
public long backupRateLimit() { public long backupRateLimit() {
assert(isInitialized()); assert(isOwningHandle());
return backupRateLimit(nativeHandle_); return backupRateLimit(nativeHandle_);
} }
@ -193,7 +196,7 @@ public class BackupableDBOptions extends RocksObject {
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setRestoreRateLimit(long restoreRateLimit) { public BackupableDBOptions setRestoreRateLimit(long restoreRateLimit) {
assert(isInitialized()); assert(isOwningHandle());
restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit; restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit;
setRestoreRateLimit(nativeHandle_, restoreRateLimit); setRestoreRateLimit(nativeHandle_, restoreRateLimit);
return this; return this;
@ -206,7 +209,7 @@ public class BackupableDBOptions extends RocksObject {
* @return numerical value describing the restore transfer limit in bytes per second. * @return numerical value describing the restore transfer limit in bytes per second.
*/ */
public long restoreRateLimit() { public long restoreRateLimit() {
assert(isInitialized()); assert(isOwningHandle());
return restoreRateLimit(nativeHandle_); return restoreRateLimit(nativeHandle_);
} }
@ -227,7 +230,7 @@ public class BackupableDBOptions extends RocksObject {
*/ */
public BackupableDBOptions setShareFilesWithChecksum( public BackupableDBOptions setShareFilesWithChecksum(
final boolean shareFilesWithChecksum) { final boolean shareFilesWithChecksum) {
assert(isInitialized()); assert(isOwningHandle());
setShareFilesWithChecksum(nativeHandle_, shareFilesWithChecksum); setShareFilesWithChecksum(nativeHandle_, shareFilesWithChecksum);
return this; return this;
} }
@ -239,19 +242,11 @@ public class BackupableDBOptions extends RocksObject {
* is active. * is active.
*/ */
public boolean shareFilesWithChecksum() { public boolean shareFilesWithChecksum() {
assert(isInitialized()); assert(isOwningHandle());
return shareFilesWithChecksum(nativeHandle_); return shareFilesWithChecksum(nativeHandle_);
} }
/** private native static long newBackupableDBOptions(final String path);
* Release the memory allocated for the current instance
* in the c++ side.
*/
@Override protected void disposeInternal() {
disposeInternal(nativeHandle_);
}
private native void newBackupableDBOptions(String path);
private native String backupDir(long handle); private native String backupDir(long handle);
private native void setShareTableFiles(long handle, boolean flag); private native void setShareTableFiles(long handle, boolean flag);
private native boolean shareTableFiles(long handle); private native boolean shareTableFiles(long handle);
@ -267,5 +262,5 @@ public class BackupableDBOptions extends RocksObject {
private native long restoreRateLimit(long handle); private native long restoreRateLimit(long handle);
private native void setShareFilesWithChecksum(long handle, boolean flag); private native void setShareFilesWithChecksum(long handle, boolean flag);
private native boolean shareFilesWithChecksum(long handle); private native boolean shareFilesWithChecksum(long handle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
} }

@ -22,8 +22,6 @@ public class BloomFilter extends Filter {
private static final int DEFAULT_BITS_PER_KEY = 10; private static final int DEFAULT_BITS_PER_KEY = 10;
private static final boolean DEFAULT_MODE = true; private static final boolean DEFAULT_MODE = true;
private final int bitsPerKey_;
private final boolean useBlockBasedMode_;
/** /**
* BloomFilter constructor * BloomFilter constructor
@ -73,17 +71,9 @@ public class BloomFilter extends Filter {
* @param useBlockBasedMode use block based mode or full filter mode * @param useBlockBasedMode use block based mode or full filter mode
*/ */
public BloomFilter(final int bitsPerKey, final boolean useBlockBasedMode) { public BloomFilter(final int bitsPerKey, final boolean useBlockBasedMode) {
super(); super(createNewBloomFilter(bitsPerKey, useBlockBasedMode));
bitsPerKey_ = bitsPerKey;
useBlockBasedMode_ = useBlockBasedMode;
createNewFilter();
} }
@Override private native static long createNewBloomFilter(final int bitsKeyKey,
protected final void createNewFilter() { final boolean useBlockBasedMode);
createNewBloomFilter(bitsPerKey_, useBlockBasedMode_);
}
private native void createNewBloomFilter(int bitsKeyKey,
boolean useBlockBasedMode);
} }

@ -27,7 +27,7 @@ public class Checkpoint extends RocksObject {
if (db == null) { if (db == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"RocksDB instance shall not be null."); "RocksDB instance shall not be null.");
} else if (!db.isInitialized()) { } else if (!db.isOwningHandle()) {
throw new IllegalStateException( throw new IllegalStateException(
"RocksDB instance must be initialized."); "RocksDB instance must be initialized.");
} }
@ -51,21 +51,15 @@ public class Checkpoint extends RocksObject {
createCheckpoint(nativeHandle_, checkpointPath); createCheckpoint(nativeHandle_, checkpointPath);
} }
@Override private Checkpoint(final RocksDB db) {
protected void disposeInternal() { super(newCheckpoint(db.nativeHandle_));
disposeInternal(nativeHandle_); this.db_ = db;
} }
private Checkpoint(RocksDB db) { private final RocksDB db_;
super();
nativeHandle_ = newCheckpoint(db.nativeHandle_);
db_ = db;
}
private RocksDB db_;
private static native long newCheckpoint(long dbHandle); private static native long newCheckpoint(long dbHandle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native void createCheckpoint(long handle, String checkpointPath) private native void createCheckpoint(long handle, String checkpointPath)
throws RocksDBException; throws RocksDBException;

@ -12,14 +12,13 @@ package org.rocksdb;
public class ColumnFamilyHandle extends RocksObject { public class ColumnFamilyHandle extends RocksObject {
ColumnFamilyHandle(final RocksDB rocksDB, ColumnFamilyHandle(final RocksDB rocksDB,
final long nativeHandle) { final long nativeHandle) {
super(); super(nativeHandle);
nativeHandle_ = nativeHandle;
// rocksDB must point to a valid RocksDB instance; // rocksDB must point to a valid RocksDB instance;
assert(rocksDB != null); assert(rocksDB != null);
// ColumnFamilyHandle must hold a reference to the related RocksDB instance // ColumnFamilyHandle must hold a reference to the related RocksDB instance
// to guarantee that while a GC cycle starts ColumnFamilyHandle instances // to guarantee that while a GC cycle starts ColumnFamilyHandle instances
// are freed prior to RocksDB instances. // are freed prior to RocksDB instances.
rocksDB_ = rocksDB; this.rocksDB_ = rocksDB;
} }
/** /**
@ -30,16 +29,14 @@ public class ColumnFamilyHandle extends RocksObject {
* Therefore {@code disposeInternal()} checks if the RocksDB is initialized * Therefore {@code disposeInternal()} checks if the RocksDB is initialized
* before freeing the native handle.</p> * before freeing the native handle.</p>
*/ */
@Override protected void disposeInternal() { @Override
synchronized (rocksDB_) { protected void disposeInternal() {
assert (isInitialized()); if(rocksDB_.isOwningHandle()) {
if (rocksDB_.isInitialized()) { disposeInternal(nativeHandle_);
disposeInternal(nativeHandle_);
}
} }
} }
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private final RocksDB rocksDB_; private final RocksDB rocksDB_;
} }

@ -29,8 +29,7 @@ public class ColumnFamilyOptions extends RocksObject
* an {@code rocksdb::DBOptions} in the c++ side. * an {@code rocksdb::DBOptions} in the c++ side.
*/ */
public ColumnFamilyOptions() { public ColumnFamilyOptions() {
super(); super(newColumnFamilyOptions());
newColumnFamilyOptions();
} }
/** /**
@ -114,7 +113,7 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setComparator(final BuiltinComparator builtinComparator) { public ColumnFamilyOptions setComparator(final BuiltinComparator builtinComparator) {
assert(isInitialized()); assert(isOwningHandle());
setComparatorHandle(nativeHandle_, builtinComparator.ordinal()); setComparatorHandle(nativeHandle_, builtinComparator.ordinal());
return this; return this;
} }
@ -122,15 +121,15 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setComparator( public ColumnFamilyOptions setComparator(
final AbstractComparator<? extends AbstractSlice<?>> comparator) { final AbstractComparator<? extends AbstractSlice<?>> comparator) {
assert (isInitialized()); assert (isOwningHandle());
setComparatorHandle(nativeHandle_, comparator.nativeHandle_); setComparatorHandle(nativeHandle_, comparator.getNativeHandle());
comparator_ = comparator; comparator_ = comparator;
return this; return this;
} }
@Override @Override
public ColumnFamilyOptions setMergeOperatorName(final String name) { public ColumnFamilyOptions setMergeOperatorName(final String name) {
assert (isInitialized()); assert (isOwningHandle());
if (name == null) { if (name == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Merge operator name must not be null."); "Merge operator name must not be null.");
@ -154,28 +153,28 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setWriteBufferSize(final long writeBufferSize) { public ColumnFamilyOptions setWriteBufferSize(final long writeBufferSize) {
assert(isInitialized()); assert(isOwningHandle());
setWriteBufferSize(nativeHandle_, writeBufferSize); setWriteBufferSize(nativeHandle_, writeBufferSize);
return this; return this;
} }
@Override @Override
public long writeBufferSize() { public long writeBufferSize() {
assert(isInitialized()); assert(isOwningHandle());
return writeBufferSize(nativeHandle_); return writeBufferSize(nativeHandle_);
} }
@Override @Override
public ColumnFamilyOptions setMaxWriteBufferNumber( public ColumnFamilyOptions setMaxWriteBufferNumber(
final int maxWriteBufferNumber) { final int maxWriteBufferNumber) {
assert(isInitialized()); assert(isOwningHandle());
setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber); setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber);
return this; return this;
} }
@Override @Override
public int maxWriteBufferNumber() { public int maxWriteBufferNumber() {
assert(isInitialized()); assert(isOwningHandle());
return maxWriteBufferNumber(nativeHandle_); return maxWriteBufferNumber(nativeHandle_);
} }
@ -193,14 +192,14 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions useFixedLengthPrefixExtractor(final int n) { public ColumnFamilyOptions useFixedLengthPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useFixedLengthPrefixExtractor(nativeHandle_, n); useFixedLengthPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@Override @Override
public ColumnFamilyOptions useCappedPrefixExtractor(final int n) { public ColumnFamilyOptions useCappedPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useCappedPrefixExtractor(nativeHandle_, n); useCappedPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@ -485,7 +484,7 @@ public class ColumnFamilyOptions extends RocksObject
public ColumnFamilyOptions setMaxTableFilesSizeFIFO( public ColumnFamilyOptions setMaxTableFilesSizeFIFO(
final long maxTableFilesSize) { final long maxTableFilesSize) {
assert(maxTableFilesSize > 0); // unsigned native type assert(maxTableFilesSize > 0); // unsigned native type
assert(isInitialized()); assert(isOwningHandle());
setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize); setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize);
return this; return this;
} }
@ -542,7 +541,7 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public String memTableFactoryName() { public String memTableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return memTableFactoryName(nativeHandle_); return memTableFactoryName(nativeHandle_);
} }
@ -556,7 +555,7 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public String tableFactoryName() { public String tableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return tableFactoryName(nativeHandle_); return tableFactoryName(nativeHandle_);
} }
@ -655,15 +654,6 @@ public class ColumnFamilyOptions extends RocksObject
return optimizeFiltersForHits(nativeHandle_); return optimizeFiltersForHits(nativeHandle_);
} }
/**
* Release the memory allocated for the current instance
* in the c++ side.
*/
@Override protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_);
}
/** /**
* <p>Private constructor to be used by * <p>Private constructor to be used by
* {@link #getColumnFamilyOptionsFromProps(java.util.Properties)}</p> * {@link #getColumnFamilyOptionsFromProps(java.util.Properties)}</p>
@ -671,15 +661,14 @@ public class ColumnFamilyOptions extends RocksObject
* @param handle native handle to ColumnFamilyOptions instance. * @param handle native handle to ColumnFamilyOptions instance.
*/ */
private ColumnFamilyOptions(final long handle) { private ColumnFamilyOptions(final long handle) {
super(); super(handle);
nativeHandle_ = handle;
} }
private static native long getColumnFamilyOptionsFromProps( private static native long getColumnFamilyOptionsFromProps(
String optString); String optString);
private native void newColumnFamilyOptions(); private static native long newColumnFamilyOptions();
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native void optimizeForPointLookup(long handle, private native void optimizeForPointLookup(long handle,
long blockCacheSizeMb); long blockCacheSizeMb);

@ -15,10 +15,18 @@ package org.rocksdb;
* using @see org.rocksdb.DirectComparator * using @see org.rocksdb.DirectComparator
*/ */
public abstract class Comparator extends AbstractComparator<Slice> { public abstract class Comparator extends AbstractComparator<Slice> {
private final long nativeHandle_;
public Comparator(final ComparatorOptions copt) { public Comparator(final ComparatorOptions copt) {
super(); super();
createNewComparator0(copt.nativeHandle_); this.nativeHandle_ = createNewComparator0(copt.nativeHandle_);
}
@Override
protected final long getNativeHandle() {
return nativeHandle_;
} }
private native void createNewComparator0(final long comparatorOptionsHandle); private native long createNewComparator0(final long comparatorOptionsHandle);
} }

@ -10,8 +10,7 @@ package org.rocksdb;
*/ */
public class ComparatorOptions extends RocksObject { public class ComparatorOptions extends RocksObject {
public ComparatorOptions() { public ComparatorOptions() {
super(); super(newComparatorOptions());
newComparatorOptions();
} }
/** /**
@ -24,7 +23,7 @@ public class ComparatorOptions extends RocksObject {
* @return true if adaptive mutex is used. * @return true if adaptive mutex is used.
*/ */
public boolean useAdaptiveMutex() { public boolean useAdaptiveMutex() {
assert(isInitialized()); assert(isOwningHandle());
return useAdaptiveMutex(nativeHandle_); return useAdaptiveMutex(nativeHandle_);
} }
@ -39,19 +38,14 @@ public class ComparatorOptions extends RocksObject {
* @return the reference to the current comparator options. * @return the reference to the current comparator options.
*/ */
public ComparatorOptions setUseAdaptiveMutex(final boolean useAdaptiveMutex) { public ComparatorOptions setUseAdaptiveMutex(final boolean useAdaptiveMutex) {
assert (isInitialized()); assert (isOwningHandle());
setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex);
return this; return this;
} }
@Override protected void disposeInternal() { private native static long newComparatorOptions();
assert(isInitialized());
disposeInternal(nativeHandle_);
}
private native void newComparatorOptions();
private native boolean useAdaptiveMutex(final long handle); private native boolean useAdaptiveMutex(final long handle);
private native void setUseAdaptiveMutex(final long handle, private native void setUseAdaptiveMutex(final long handle,
final boolean useAdaptiveMutex); final boolean useAdaptiveMutex);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
} }

@ -26,9 +26,8 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
* an {@code rocksdb::DBOptions} in the c++ side. * an {@code rocksdb::DBOptions} in the c++ side.
*/ */
public DBOptions() { public DBOptions() {
super(); super(newDBOptions());
numShardBits_ = DEFAULT_NUM_SHARD_BITS; numShardBits_ = DEFAULT_NUM_SHARD_BITS;
newDBOptions();
} }
/** /**
@ -75,70 +74,70 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
@Override @Override
public DBOptions setIncreaseParallelism( public DBOptions setIncreaseParallelism(
final int totalThreads) { final int totalThreads) {
assert (isInitialized()); assert(isOwningHandle());
setIncreaseParallelism(nativeHandle_, totalThreads); setIncreaseParallelism(nativeHandle_, totalThreads);
return this; return this;
} }
@Override @Override
public DBOptions setCreateIfMissing(final boolean flag) { public DBOptions setCreateIfMissing(final boolean flag) {
assert(isInitialized()); assert(isOwningHandle());
setCreateIfMissing(nativeHandle_, flag); setCreateIfMissing(nativeHandle_, flag);
return this; return this;
} }
@Override @Override
public boolean createIfMissing() { public boolean createIfMissing() {
assert(isInitialized()); assert(isOwningHandle());
return createIfMissing(nativeHandle_); return createIfMissing(nativeHandle_);
} }
@Override @Override
public DBOptions setCreateMissingColumnFamilies( public DBOptions setCreateMissingColumnFamilies(
final boolean flag) { final boolean flag) {
assert(isInitialized()); assert(isOwningHandle());
setCreateMissingColumnFamilies(nativeHandle_, flag); setCreateMissingColumnFamilies(nativeHandle_, flag);
return this; return this;
} }
@Override @Override
public boolean createMissingColumnFamilies() { public boolean createMissingColumnFamilies() {
assert(isInitialized()); assert(isOwningHandle());
return createMissingColumnFamilies(nativeHandle_); return createMissingColumnFamilies(nativeHandle_);
} }
@Override @Override
public DBOptions setErrorIfExists( public DBOptions setErrorIfExists(
final boolean errorIfExists) { final boolean errorIfExists) {
assert(isInitialized()); assert(isOwningHandle());
setErrorIfExists(nativeHandle_, errorIfExists); setErrorIfExists(nativeHandle_, errorIfExists);
return this; return this;
} }
@Override @Override
public boolean errorIfExists() { public boolean errorIfExists() {
assert(isInitialized()); assert(isOwningHandle());
return errorIfExists(nativeHandle_); return errorIfExists(nativeHandle_);
} }
@Override @Override
public DBOptions setParanoidChecks( public DBOptions setParanoidChecks(
final boolean paranoidChecks) { final boolean paranoidChecks) {
assert(isInitialized()); assert(isOwningHandle());
setParanoidChecks(nativeHandle_, paranoidChecks); setParanoidChecks(nativeHandle_, paranoidChecks);
return this; return this;
} }
@Override @Override
public boolean paranoidChecks() { public boolean paranoidChecks() {
assert(isInitialized()); assert(isOwningHandle());
return paranoidChecks(nativeHandle_); return paranoidChecks(nativeHandle_);
} }
@Override @Override
public DBOptions setRateLimiterConfig( public DBOptions setRateLimiterConfig(
final RateLimiterConfig config) { final RateLimiterConfig config) {
assert(isInitialized()); assert(isOwningHandle());
rateLimiterConfig_ = config; rateLimiterConfig_ = config;
setRateLimiter(nativeHandle_, config.newRateLimiterHandle()); setRateLimiter(nativeHandle_, config.newRateLimiterHandle());
return this; return this;
@ -146,7 +145,7 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
@Override @Override
public DBOptions setLogger(final Logger logger) { public DBOptions setLogger(final Logger logger) {
assert(isInitialized()); assert(isOwningHandle());
setLogger(nativeHandle_, logger.nativeHandle_); setLogger(nativeHandle_, logger.nativeHandle_);
return this; return this;
} }
@ -154,14 +153,14 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
@Override @Override
public DBOptions setInfoLogLevel( public DBOptions setInfoLogLevel(
final InfoLogLevel infoLogLevel) { final InfoLogLevel infoLogLevel) {
assert(isInitialized()); assert(isOwningHandle());
setInfoLogLevel(nativeHandle_, infoLogLevel.getValue()); setInfoLogLevel(nativeHandle_, infoLogLevel.getValue());
return this; return this;
} }
@Override @Override
public InfoLogLevel infoLogLevel() { public InfoLogLevel infoLogLevel() {
assert(isInitialized()); assert(isOwningHandle());
return InfoLogLevel.getInfoLogLevel( return InfoLogLevel.getInfoLogLevel(
infoLogLevel(nativeHandle_)); infoLogLevel(nativeHandle_));
} }
@ -169,41 +168,41 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
@Override @Override
public DBOptions setMaxOpenFiles( public DBOptions setMaxOpenFiles(
final int maxOpenFiles) { final int maxOpenFiles) {
assert(isInitialized()); assert(isOwningHandle());
setMaxOpenFiles(nativeHandle_, maxOpenFiles); setMaxOpenFiles(nativeHandle_, maxOpenFiles);
return this; return this;
} }
@Override @Override
public int maxOpenFiles() { public int maxOpenFiles() {
assert(isInitialized()); assert(isOwningHandle());
return maxOpenFiles(nativeHandle_); return maxOpenFiles(nativeHandle_);
} }
@Override @Override
public DBOptions setMaxTotalWalSize( public DBOptions setMaxTotalWalSize(
final long maxTotalWalSize) { final long maxTotalWalSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxTotalWalSize(nativeHandle_, maxTotalWalSize); setMaxTotalWalSize(nativeHandle_, maxTotalWalSize);
return this; return this;
} }
@Override @Override
public long maxTotalWalSize() { public long maxTotalWalSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxTotalWalSize(nativeHandle_); return maxTotalWalSize(nativeHandle_);
} }
@Override @Override
public DBOptions createStatistics() { public DBOptions createStatistics() {
assert(isInitialized()); assert(isOwningHandle());
createStatistics(nativeHandle_); createStatistics(nativeHandle_);
return this; return this;
} }
@Override @Override
public Statistics statisticsPtr() { public Statistics statisticsPtr() {
assert(isInitialized()); assert(isOwningHandle());
long statsPtr = statisticsPtr(nativeHandle_); long statsPtr = statisticsPtr(nativeHandle_);
if(statsPtr == 0) { if(statsPtr == 0) {
@ -217,287 +216,287 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
@Override @Override
public DBOptions setDisableDataSync( public DBOptions setDisableDataSync(
final boolean disableDataSync) { final boolean disableDataSync) {
assert(isInitialized()); assert(isOwningHandle());
setDisableDataSync(nativeHandle_, disableDataSync); setDisableDataSync(nativeHandle_, disableDataSync);
return this; return this;
} }
@Override @Override
public boolean disableDataSync() { public boolean disableDataSync() {
assert(isInitialized()); assert(isOwningHandle());
return disableDataSync(nativeHandle_); return disableDataSync(nativeHandle_);
} }
@Override @Override
public DBOptions setUseFsync( public DBOptions setUseFsync(
final boolean useFsync) { final boolean useFsync) {
assert(isInitialized()); assert(isOwningHandle());
setUseFsync(nativeHandle_, useFsync); setUseFsync(nativeHandle_, useFsync);
return this; return this;
} }
@Override @Override
public boolean useFsync() { public boolean useFsync() {
assert(isInitialized()); assert(isOwningHandle());
return useFsync(nativeHandle_); return useFsync(nativeHandle_);
} }
@Override @Override
public DBOptions setDbLogDir( public DBOptions setDbLogDir(
final String dbLogDir) { final String dbLogDir) {
assert(isInitialized()); assert(isOwningHandle());
setDbLogDir(nativeHandle_, dbLogDir); setDbLogDir(nativeHandle_, dbLogDir);
return this; return this;
} }
@Override @Override
public String dbLogDir() { public String dbLogDir() {
assert(isInitialized()); assert(isOwningHandle());
return dbLogDir(nativeHandle_); return dbLogDir(nativeHandle_);
} }
@Override @Override
public DBOptions setWalDir( public DBOptions setWalDir(
final String walDir) { final String walDir) {
assert(isInitialized()); assert(isOwningHandle());
setWalDir(nativeHandle_, walDir); setWalDir(nativeHandle_, walDir);
return this; return this;
} }
@Override @Override
public String walDir() { public String walDir() {
assert(isInitialized()); assert(isOwningHandle());
return walDir(nativeHandle_); return walDir(nativeHandle_);
} }
@Override @Override
public DBOptions setDeleteObsoleteFilesPeriodMicros( public DBOptions setDeleteObsoleteFilesPeriodMicros(
final long micros) { final long micros) {
assert(isInitialized()); assert(isOwningHandle());
setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros); setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros);
return this; return this;
} }
@Override @Override
public long deleteObsoleteFilesPeriodMicros() { public long deleteObsoleteFilesPeriodMicros() {
assert(isInitialized()); assert(isOwningHandle());
return deleteObsoleteFilesPeriodMicros(nativeHandle_); return deleteObsoleteFilesPeriodMicros(nativeHandle_);
} }
@Override @Override
public DBOptions setMaxBackgroundCompactions( public DBOptions setMaxBackgroundCompactions(
final int maxBackgroundCompactions) { final int maxBackgroundCompactions) {
assert(isInitialized()); assert(isOwningHandle());
setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions); setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions);
return this; return this;
} }
@Override @Override
public int maxBackgroundCompactions() { public int maxBackgroundCompactions() {
assert(isInitialized()); assert(isOwningHandle());
return maxBackgroundCompactions(nativeHandle_); return maxBackgroundCompactions(nativeHandle_);
} }
@Override @Override
public DBOptions setMaxBackgroundFlushes( public DBOptions setMaxBackgroundFlushes(
final int maxBackgroundFlushes) { final int maxBackgroundFlushes) {
assert(isInitialized()); assert(isOwningHandle());
setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes); setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes);
return this; return this;
} }
@Override @Override
public int maxBackgroundFlushes() { public int maxBackgroundFlushes() {
assert(isInitialized()); assert(isOwningHandle());
return maxBackgroundFlushes(nativeHandle_); return maxBackgroundFlushes(nativeHandle_);
} }
@Override @Override
public DBOptions setMaxLogFileSize( public DBOptions setMaxLogFileSize(
final long maxLogFileSize) { final long maxLogFileSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxLogFileSize(nativeHandle_, maxLogFileSize); setMaxLogFileSize(nativeHandle_, maxLogFileSize);
return this; return this;
} }
@Override @Override
public long maxLogFileSize() { public long maxLogFileSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxLogFileSize(nativeHandle_); return maxLogFileSize(nativeHandle_);
} }
@Override @Override
public DBOptions setLogFileTimeToRoll( public DBOptions setLogFileTimeToRoll(
final long logFileTimeToRoll) { final long logFileTimeToRoll) {
assert(isInitialized()); assert(isOwningHandle());
setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll); setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll);
return this; return this;
} }
@Override @Override
public long logFileTimeToRoll() { public long logFileTimeToRoll() {
assert(isInitialized()); assert(isOwningHandle());
return logFileTimeToRoll(nativeHandle_); return logFileTimeToRoll(nativeHandle_);
} }
@Override @Override
public DBOptions setKeepLogFileNum( public DBOptions setKeepLogFileNum(
final long keepLogFileNum) { final long keepLogFileNum) {
assert(isInitialized()); assert(isOwningHandle());
setKeepLogFileNum(nativeHandle_, keepLogFileNum); setKeepLogFileNum(nativeHandle_, keepLogFileNum);
return this; return this;
} }
@Override @Override
public long keepLogFileNum() { public long keepLogFileNum() {
assert(isInitialized()); assert(isOwningHandle());
return keepLogFileNum(nativeHandle_); return keepLogFileNum(nativeHandle_);
} }
@Override @Override
public DBOptions setMaxManifestFileSize( public DBOptions setMaxManifestFileSize(
final long maxManifestFileSize) { final long maxManifestFileSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxManifestFileSize(nativeHandle_, maxManifestFileSize); setMaxManifestFileSize(nativeHandle_, maxManifestFileSize);
return this; return this;
} }
@Override @Override
public long maxManifestFileSize() { public long maxManifestFileSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxManifestFileSize(nativeHandle_); return maxManifestFileSize(nativeHandle_);
} }
@Override @Override
public DBOptions setTableCacheNumshardbits( public DBOptions setTableCacheNumshardbits(
final int tableCacheNumshardbits) { final int tableCacheNumshardbits) {
assert(isInitialized()); assert(isOwningHandle());
setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits); setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits);
return this; return this;
} }
@Override @Override
public int tableCacheNumshardbits() { public int tableCacheNumshardbits() {
assert(isInitialized()); assert(isOwningHandle());
return tableCacheNumshardbits(nativeHandle_); return tableCacheNumshardbits(nativeHandle_);
} }
@Override @Override
public DBOptions setWalTtlSeconds( public DBOptions setWalTtlSeconds(
final long walTtlSeconds) { final long walTtlSeconds) {
assert(isInitialized()); assert(isOwningHandle());
setWalTtlSeconds(nativeHandle_, walTtlSeconds); setWalTtlSeconds(nativeHandle_, walTtlSeconds);
return this; return this;
} }
@Override @Override
public long walTtlSeconds() { public long walTtlSeconds() {
assert(isInitialized()); assert(isOwningHandle());
return walTtlSeconds(nativeHandle_); return walTtlSeconds(nativeHandle_);
} }
@Override @Override
public DBOptions setWalSizeLimitMB( public DBOptions setWalSizeLimitMB(
final long sizeLimitMB) { final long sizeLimitMB) {
assert(isInitialized()); assert(isOwningHandle());
setWalSizeLimitMB(nativeHandle_, sizeLimitMB); setWalSizeLimitMB(nativeHandle_, sizeLimitMB);
return this; return this;
} }
@Override @Override
public long walSizeLimitMB() { public long walSizeLimitMB() {
assert(isInitialized()); assert(isOwningHandle());
return walSizeLimitMB(nativeHandle_); return walSizeLimitMB(nativeHandle_);
} }
@Override @Override
public DBOptions setManifestPreallocationSize( public DBOptions setManifestPreallocationSize(
final long size) { final long size) {
assert(isInitialized()); assert(isOwningHandle());
setManifestPreallocationSize(nativeHandle_, size); setManifestPreallocationSize(nativeHandle_, size);
return this; return this;
} }
@Override @Override
public long manifestPreallocationSize() { public long manifestPreallocationSize() {
assert(isInitialized()); assert(isOwningHandle());
return manifestPreallocationSize(nativeHandle_); return manifestPreallocationSize(nativeHandle_);
} }
@Override @Override
public DBOptions setAllowOsBuffer( public DBOptions setAllowOsBuffer(
final boolean allowOsBuffer) { final boolean allowOsBuffer) {
assert(isInitialized()); assert(isOwningHandle());
setAllowOsBuffer(nativeHandle_, allowOsBuffer); setAllowOsBuffer(nativeHandle_, allowOsBuffer);
return this; return this;
} }
@Override @Override
public boolean allowOsBuffer() { public boolean allowOsBuffer() {
assert(isInitialized()); assert(isOwningHandle());
return allowOsBuffer(nativeHandle_); return allowOsBuffer(nativeHandle_);
} }
@Override @Override
public DBOptions setAllowMmapReads( public DBOptions setAllowMmapReads(
final boolean allowMmapReads) { final boolean allowMmapReads) {
assert(isInitialized()); assert(isOwningHandle());
setAllowMmapReads(nativeHandle_, allowMmapReads); setAllowMmapReads(nativeHandle_, allowMmapReads);
return this; return this;
} }
@Override @Override
public boolean allowMmapReads() { public boolean allowMmapReads() {
assert(isInitialized()); assert(isOwningHandle());
return allowMmapReads(nativeHandle_); return allowMmapReads(nativeHandle_);
} }
@Override @Override
public DBOptions setAllowMmapWrites( public DBOptions setAllowMmapWrites(
final boolean allowMmapWrites) { final boolean allowMmapWrites) {
assert(isInitialized()); assert(isOwningHandle());
setAllowMmapWrites(nativeHandle_, allowMmapWrites); setAllowMmapWrites(nativeHandle_, allowMmapWrites);
return this; return this;
} }
@Override @Override
public boolean allowMmapWrites() { public boolean allowMmapWrites() {
assert(isInitialized()); assert(isOwningHandle());
return allowMmapWrites(nativeHandle_); return allowMmapWrites(nativeHandle_);
} }
@Override @Override
public DBOptions setIsFdCloseOnExec( public DBOptions setIsFdCloseOnExec(
final boolean isFdCloseOnExec) { final boolean isFdCloseOnExec) {
assert(isInitialized()); assert(isOwningHandle());
setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec); setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec);
return this; return this;
} }
@Override @Override
public boolean isFdCloseOnExec() { public boolean isFdCloseOnExec() {
assert(isInitialized()); assert(isOwningHandle());
return isFdCloseOnExec(nativeHandle_); return isFdCloseOnExec(nativeHandle_);
} }
@Override @Override
public DBOptions setStatsDumpPeriodSec( public DBOptions setStatsDumpPeriodSec(
final int statsDumpPeriodSec) { final int statsDumpPeriodSec) {
assert(isInitialized()); assert(isOwningHandle());
setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec); setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec);
return this; return this;
} }
@Override @Override
public int statsDumpPeriodSec() { public int statsDumpPeriodSec() {
assert(isInitialized()); assert(isOwningHandle());
return statsDumpPeriodSec(nativeHandle_); return statsDumpPeriodSec(nativeHandle_);
} }
@Override @Override
public DBOptions setAdviseRandomOnOpen( public DBOptions setAdviseRandomOnOpen(
final boolean adviseRandomOnOpen) { final boolean adviseRandomOnOpen) {
assert(isInitialized()); assert(isOwningHandle());
setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen); setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen);
return this; return this;
} }
@ -510,21 +509,21 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
@Override @Override
public DBOptions setUseAdaptiveMutex( public DBOptions setUseAdaptiveMutex(
final boolean useAdaptiveMutex) { final boolean useAdaptiveMutex) {
assert(isInitialized()); assert(isOwningHandle());
setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex);
return this; return this;
} }
@Override @Override
public boolean useAdaptiveMutex() { public boolean useAdaptiveMutex() {
assert(isInitialized()); assert(isOwningHandle());
return useAdaptiveMutex(nativeHandle_); return useAdaptiveMutex(nativeHandle_);
} }
@Override @Override
public DBOptions setBytesPerSync( public DBOptions setBytesPerSync(
final long bytesPerSync) { final long bytesPerSync) {
assert(isInitialized()); assert(isOwningHandle());
setBytesPerSync(nativeHandle_, bytesPerSync); setBytesPerSync(nativeHandle_, bytesPerSync);
return this; return this;
} }
@ -534,33 +533,23 @@ public class DBOptions extends RocksObject implements DBOptionsInterface {
return bytesPerSync(nativeHandle_); return bytesPerSync(nativeHandle_);
} }
/**
* Release the memory allocated for the current instance
* in the c++ side.
*/
@Override protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_);
}
static final int DEFAULT_NUM_SHARD_BITS = -1; static final int DEFAULT_NUM_SHARD_BITS = -1;
/** /**
* <p>Private constructor to be used by * <p>Private constructor to be used by
* {@link #getDBOptionsFromProps(java.util.Properties)}</p> * {@link #getDBOptionsFromProps(java.util.Properties)}</p>
* *
* @param handle native handle to DBOptions instance. * @param nativeHandle native handle to DBOptions instance.
*/ */
private DBOptions(final long handle) { private DBOptions(final long nativeHandle) {
super(); super(nativeHandle);
nativeHandle_ = handle;
} }
private static native long getDBOptionsFromProps( private static native long getDBOptionsFromProps(
String optString); String optString);
private native void newDBOptions(); private native static long newDBOptions();
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native void setIncreaseParallelism(long handle, int totalThreads); private native void setIncreaseParallelism(long handle, int totalThreads);
private native void setCreateIfMissing(long handle, boolean flag); private native void setCreateIfMissing(long handle, boolean flag);

@ -15,10 +15,18 @@ package org.rocksdb;
* using @see org.rocksdb.Comparator * using @see org.rocksdb.Comparator
*/ */
public abstract class DirectComparator extends AbstractComparator<DirectSlice> { public abstract class DirectComparator extends AbstractComparator<DirectSlice> {
private final long nativeHandle_;
public DirectComparator(final ComparatorOptions copt) { public DirectComparator(final ComparatorOptions copt) {
super(); super();
createNewDirectComparator0(copt.nativeHandle_); this.nativeHandle_ = createNewDirectComparator0(copt.nativeHandle_);
}
@Override
protected final long getNativeHandle() {
return nativeHandle_;
} }
private native void createNewDirectComparator0(final long comparatorOptionsHandle); private native long createNewDirectComparator0(final long comparatorOptionsHandle);
} }

@ -16,7 +16,6 @@ import java.nio.ByteBuffer;
* values consider using @see org.rocksdb.Slice * values consider using @see org.rocksdb.Slice
*/ */
public class DirectSlice extends AbstractSlice<ByteBuffer> { public class DirectSlice extends AbstractSlice<ByteBuffer> {
//TODO(AR) only needed by WriteBatchWithIndexTest until JDK8
public final static DirectSlice NONE = new DirectSlice(); public final static DirectSlice NONE = new DirectSlice();
/** /**
@ -24,9 +23,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* without an underlying C++ object set * without an underlying C++ object set
* at creation time. * at creation time.
* *
* Note: You should be aware that * Note: You should be aware that it is intentionally marked as
* {@see org.rocksdb.RocksObject#disOwnNativeHandle()} is intentionally
* called from the default DirectSlice constructor, and that it is marked as
* package-private. This is so that developers cannot construct their own default * package-private. This is so that developers cannot construct their own default
* DirectSlice objects (at present). As developers cannot construct their own * DirectSlice objects (at present). As developers cannot construct their own
* DirectSlice objects through this, they are not creating underlying C++ * DirectSlice objects through this, they are not creating underlying C++
@ -34,7 +31,6 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
*/ */
DirectSlice() { DirectSlice() {
super(); super();
disOwnNativeHandle();
} }
/** /**
@ -45,8 +41,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* @param str The string * @param str The string
*/ */
public DirectSlice(final String str) { public DirectSlice(final String str) {
super(); super(createNewSliceFromString(str));
createNewSliceFromString(str);
} }
/** /**
@ -58,9 +53,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* @param length The length of the data to use for the slice * @param length The length of the data to use for the slice
*/ */
public DirectSlice(final ByteBuffer data, final int length) { public DirectSlice(final ByteBuffer data, final int length) {
super(); super(createNewDirectSlice0(ensureDirect(data), length));
assert(data.isDirect());
createNewDirectSlice0(data, length);
} }
/** /**
@ -71,9 +64,13 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* @param data The bugger containing the data * @param data The bugger containing the data
*/ */
public DirectSlice(final ByteBuffer data) { public DirectSlice(final ByteBuffer data) {
super(); super(createNewDirectSlice1(ensureDirect(data)));
}
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()); assert(data.isDirect());
createNewDirectSlice1(data); return data;
} }
/** /**
@ -85,7 +82,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* @return the requested byte * @return the requested byte
*/ */
public byte get(int offset) { public byte get(int offset) {
assert (isInitialized()); assert (isOwningHandle());
return get0(nativeHandle_, offset); return get0(nativeHandle_, offset);
} }
@ -93,7 +90,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* Clears the backing slice * Clears the backing slice
*/ */
public void clear() { public void clear() {
assert (isInitialized()); assert (isOwningHandle());
clear0(nativeHandle_); clear0(nativeHandle_);
} }
@ -105,12 +102,13 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
* @param n The number of bytes to drop * @param n The number of bytes to drop
*/ */
public void removePrefix(final int n) { public void removePrefix(final int n) {
assert (isInitialized()); assert (isOwningHandle());
removePrefix0(nativeHandle_, n); removePrefix0(nativeHandle_, n);
} }
private native void createNewDirectSlice0(ByteBuffer data, int length); private native static long createNewDirectSlice0(final ByteBuffer data,
private native void createNewDirectSlice1(ByteBuffer data); final int length);
private native static long createNewDirectSlice1(final ByteBuffer data);
@Override protected final native ByteBuffer data0(long handle); @Override protected final native ByteBuffer data0(long handle);
private native byte get0(long handle, int offset); private native byte get0(long handle, int offset);
private native void clear0(long handle); private native void clear0(long handle);

@ -70,8 +70,8 @@ public abstract class Env extends RocksObject {
} }
protected Env() { protected Env(final long nativeHandle) {
super(); super(nativeHandle);
} }
static { static {

@ -13,7 +13,10 @@ package org.rocksdb;
* DB::Get() call. * DB::Get() call.
*/ */
public abstract class Filter extends RocksObject { public abstract class Filter extends RocksObject {
protected abstract void createNewFilter();
protected Filter(final long nativeHandle) {
super(nativeHandle);
}
/** /**
* Deletes underlying C++ filter pointer. * Deletes underlying C++ filter pointer.
@ -22,10 +25,11 @@ public abstract class Filter extends RocksObject {
* RocksDB instances referencing the filter are closed. * RocksDB instances referencing the filter are closed.
* Otherwise an undefined behavior will occur. * Otherwise an undefined behavior will occur.
*/ */
@Override protected void disposeInternal() { @Override
assert(isInitialized()); protected void disposeInternal() {
disposeInternal(nativeHandle_); disposeInternal(nativeHandle_);
} }
private native void disposeInternal(long handle); @Override
protected final native void disposeInternal(final long handle);
} }

@ -10,8 +10,7 @@ public class FlushOptions extends RocksObject {
* Construct a new instance of FlushOptions. * Construct a new instance of FlushOptions.
*/ */
public FlushOptions(){ public FlushOptions(){
super(); super(newFlushOptions());
newFlushOptions();
} }
/** /**
@ -23,7 +22,7 @@ public class FlushOptions extends RocksObject {
* @return instance of current FlushOptions. * @return instance of current FlushOptions.
*/ */
public FlushOptions setWaitForFlush(final boolean waitForFlush) { public FlushOptions setWaitForFlush(final boolean waitForFlush) {
assert(isInitialized()); assert(isOwningHandle());
setWaitForFlush(nativeHandle_, waitForFlush); setWaitForFlush(nativeHandle_, waitForFlush);
return this; return this;
} }
@ -35,16 +34,12 @@ public class FlushOptions extends RocksObject {
* waits for termination of the flush process. * waits for termination of the flush process.
*/ */
public boolean waitForFlush() { public boolean waitForFlush() {
assert(isInitialized()); assert(isOwningHandle());
return waitForFlush(nativeHandle_); return waitForFlush(nativeHandle_);
} }
@Override protected void disposeInternal() { private native static long newFlushOptions();
disposeInternal(nativeHandle_); @Override protected final native void disposeInternal(final long handle);
}
private native void newFlushOptions();
private native void disposeInternal(long handle);
private native void setWaitForFlush(long handle, private native void setWaitForFlush(long handle,
boolean wait); boolean wait);
private native boolean waitForFlush(long handle); private native boolean waitForFlush(long handle);

@ -35,7 +35,9 @@ package org.rocksdb;
* {@link org.rocksdb.InfoLogLevel#FATAL_LEVEL}. * {@link org.rocksdb.InfoLogLevel#FATAL_LEVEL}.
* </p> * </p>
*/ */
public abstract class Logger extends RocksObject { public abstract class Logger extends NativeReference {
final long nativeHandle_;
/** /**
* <p>AbstractLogger constructor.</p> * <p>AbstractLogger constructor.</p>
@ -47,7 +49,8 @@ public abstract class Logger extends RocksObject {
* @param options {@link org.rocksdb.Options} instance. * @param options {@link org.rocksdb.Options} instance.
*/ */
public Logger(final Options options) { public Logger(final Options options) {
createNewLoggerOptions(options.nativeHandle_); super(true);
this.nativeHandle_ = createNewLoggerOptions(options.nativeHandle_);
} }
/** /**
@ -60,7 +63,8 @@ public abstract class Logger extends RocksObject {
* @param dboptions {@link org.rocksdb.DBOptions} instance. * @param dboptions {@link org.rocksdb.DBOptions} instance.
*/ */
public Logger(final DBOptions dboptions) { public Logger(final DBOptions dboptions) {
createNewLoggerDbOptions(dboptions.nativeHandle_); super(true);
this.nativeHandle_ = createNewLoggerDbOptions(dboptions.nativeHandle_);
} }
/** /**
@ -93,16 +97,15 @@ public abstract class Logger extends RocksObject {
*/ */
@Override @Override
protected void disposeInternal() { protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_); disposeInternal(nativeHandle_);
} }
protected native void createNewLoggerOptions( protected native long createNewLoggerOptions(
long options); long options);
protected native void createNewLoggerDbOptions( protected native long createNewLoggerDbOptions(
long dbOptions); long dbOptions);
protected native void setInfoLogLevel(long handle, protected native void setInfoLogLevel(long handle,
byte infoLogLevel); byte infoLogLevel);
protected native byte infoLogLevel(long handle); protected native byte infoLogLevel(long handle);
private native void disposeInternal(long handle); private native void disposeInternal(final long handle);
} }

@ -0,0 +1,77 @@
package org.rocksdb;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class NativeReference {
/**
* A flag indicating whether the current {@code RocksObject} is responsible to
* release the c++ object stored in its {@code nativeHandle_}.
*/
private final AtomicBoolean owningHandle_;
protected NativeReference(final boolean owningHandle) {
this.owningHandle_ = new AtomicBoolean(owningHandle);
}
public boolean isOwningHandle() {
return owningHandle_.get();
}
/**
* Revoke ownership of the native object.
* <p>
* This will prevent the object from attempting to delete the underlying
* native object in its finalizer. This must be used when another object
* takes over ownership of the native object or both will attempt to delete
* the underlying object when garbage collected.
* <p>
* When {@code disOwnNativeHandle()} is called, {@code dispose()} will simply set
* {@code nativeHandle_} to 0 without releasing its associated C++ resource.
* As a result, incorrectly use this function may cause memory leak, and this
* function call will not affect the return value of {@code isInitialized()}.
* </p>
* @see #dispose()
*/
protected final void disOwnNativeHandle() {
owningHandle_.set(false);
}
/**
* Release the c++ object manually pointed by the native handle.
* <p>
* Note that {@code dispose()} will also be called during the GC process
* if it was not called before its {@code RocksObject} went out-of-scope.
* However, since Java may wrongly wrongly assume those objects are
* small in that they seems to only hold a long variable. As a result,
* they might have low priority in the GC process. To prevent this,
* it is suggested to call {@code dispose()} manually.
* </p>
* <p>
* Note that once an instance of {@code RocksObject} has been disposed,
* calling its function will lead undefined behavior.
* </p>
*/
public final void dispose() {
if (owningHandle_.compareAndSet(true, false)) {
disposeInternal();
}
}
/**
* The helper function of {@code dispose()} which all subclasses of
* {@code RocksObject} must implement to release their associated
* C++ resource.
*/
protected abstract void disposeInternal();
/**
* Simply calls {@code dispose()} and release its c++ resource if it has not
* yet released.
*/
@Override
protected void finalize() throws Throwable {
dispose();
super.finalize();
}
}

@ -27,8 +27,7 @@ public class Options extends RocksObject
* an {@code rocksdb::Options} in the c++ side. * an {@code rocksdb::Options} in the c++ side.
*/ */
public Options() { public Options() {
super(); super(newOptions());
newOptions();
env_ = Env.getDefault(); env_ = Env.getDefault();
} }
@ -42,28 +41,27 @@ public class Options extends RocksObject
*/ */
public Options(final DBOptions dbOptions, public Options(final DBOptions dbOptions,
final ColumnFamilyOptions columnFamilyOptions) { final ColumnFamilyOptions columnFamilyOptions) {
super(); super(newOptions(dbOptions.nativeHandle_, columnFamilyOptions.nativeHandle_));
newOptions(dbOptions.nativeHandle_, columnFamilyOptions.nativeHandle_);
env_ = Env.getDefault(); env_ = Env.getDefault();
} }
@Override @Override
public Options setIncreaseParallelism(final int totalThreads) { public Options setIncreaseParallelism(final int totalThreads) {
assert(isInitialized()); assert(isOwningHandle());
setIncreaseParallelism(nativeHandle_, totalThreads); setIncreaseParallelism(nativeHandle_, totalThreads);
return this; return this;
} }
@Override @Override
public Options setCreateIfMissing(final boolean flag) { public Options setCreateIfMissing(final boolean flag) {
assert(isInitialized()); assert(isOwningHandle());
setCreateIfMissing(nativeHandle_, flag); setCreateIfMissing(nativeHandle_, flag);
return this; return this;
} }
@Override @Override
public Options setCreateMissingColumnFamilies(final boolean flag) { public Options setCreateMissingColumnFamilies(final boolean flag) {
assert(isInitialized()); assert(isOwningHandle());
setCreateMissingColumnFamilies(nativeHandle_, flag); setCreateMissingColumnFamilies(nativeHandle_, flag);
return this; return this;
} }
@ -77,7 +75,7 @@ public class Options extends RocksObject
* @return the instance of the current Options. * @return the instance of the current Options.
*/ */
public Options setEnv(final Env env) { public Options setEnv(final Env env) {
assert(isInitialized()); assert(isOwningHandle());
setEnv(nativeHandle_, env.nativeHandle_); setEnv(nativeHandle_, env.nativeHandle_);
env_ = env; env_ = env;
return this; return this;
@ -111,13 +109,13 @@ public class Options extends RocksObject
@Override @Override
public boolean createIfMissing() { public boolean createIfMissing() {
assert(isInitialized()); assert(isOwningHandle());
return createIfMissing(nativeHandle_); return createIfMissing(nativeHandle_);
} }
@Override @Override
public boolean createMissingColumnFamilies() { public boolean createMissingColumnFamilies() {
assert(isInitialized()); assert(isOwningHandle());
return createMissingColumnFamilies(nativeHandle_); return createMissingColumnFamilies(nativeHandle_);
} }
@ -161,7 +159,7 @@ public class Options extends RocksObject
@Override @Override
public Options setComparator(final BuiltinComparator builtinComparator) { public Options setComparator(final BuiltinComparator builtinComparator) {
assert(isInitialized()); assert(isOwningHandle());
setComparatorHandle(nativeHandle_, builtinComparator.ordinal()); setComparatorHandle(nativeHandle_, builtinComparator.ordinal());
return this; return this;
} }
@ -169,15 +167,15 @@ public class Options extends RocksObject
@Override @Override
public Options setComparator( public Options setComparator(
final AbstractComparator<? extends AbstractSlice<?>> comparator) { final AbstractComparator<? extends AbstractSlice<?>> comparator) {
assert (isInitialized()); assert(isOwningHandle());
setComparatorHandle(nativeHandle_, comparator.nativeHandle_); setComparatorHandle(nativeHandle_, comparator.getNativeHandle());
comparator_ = comparator; comparator_ = comparator;
return this; return this;
} }
@Override @Override
public Options setMergeOperatorName(final String name) { public Options setMergeOperatorName(final String name) {
assert (isInitialized()); assert(isOwningHandle());
if (name == null) { if (name == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Merge operator name must not be null."); "Merge operator name must not be null.");
@ -194,164 +192,164 @@ public class Options extends RocksObject
@Override @Override
public Options setWriteBufferSize(final long writeBufferSize) { public Options setWriteBufferSize(final long writeBufferSize) {
assert(isInitialized()); assert(isOwningHandle());
setWriteBufferSize(nativeHandle_, writeBufferSize); setWriteBufferSize(nativeHandle_, writeBufferSize);
return this; return this;
} }
@Override @Override
public long writeBufferSize() { public long writeBufferSize() {
assert(isInitialized()); assert(isOwningHandle());
return writeBufferSize(nativeHandle_); return writeBufferSize(nativeHandle_);
} }
@Override @Override
public Options setMaxWriteBufferNumber(final int maxWriteBufferNumber) { public Options setMaxWriteBufferNumber(final int maxWriteBufferNumber) {
assert(isInitialized()); assert(isOwningHandle());
setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber); setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber);
return this; return this;
} }
@Override @Override
public int maxWriteBufferNumber() { public int maxWriteBufferNumber() {
assert(isInitialized()); assert(isOwningHandle());
return maxWriteBufferNumber(nativeHandle_); return maxWriteBufferNumber(nativeHandle_);
} }
@Override @Override
public boolean errorIfExists() { public boolean errorIfExists() {
assert(isInitialized()); assert(isOwningHandle());
return errorIfExists(nativeHandle_); return errorIfExists(nativeHandle_);
} }
@Override @Override
public Options setErrorIfExists(final boolean errorIfExists) { public Options setErrorIfExists(final boolean errorIfExists) {
assert(isInitialized()); assert(isOwningHandle());
setErrorIfExists(nativeHandle_, errorIfExists); setErrorIfExists(nativeHandle_, errorIfExists);
return this; return this;
} }
@Override @Override
public boolean paranoidChecks() { public boolean paranoidChecks() {
assert(isInitialized()); assert(isOwningHandle());
return paranoidChecks(nativeHandle_); return paranoidChecks(nativeHandle_);
} }
@Override @Override
public Options setParanoidChecks(final boolean paranoidChecks) { public Options setParanoidChecks(final boolean paranoidChecks) {
assert(isInitialized()); assert(isOwningHandle());
setParanoidChecks(nativeHandle_, paranoidChecks); setParanoidChecks(nativeHandle_, paranoidChecks);
return this; return this;
} }
@Override @Override
public int maxOpenFiles() { public int maxOpenFiles() {
assert(isInitialized()); assert(isOwningHandle());
return maxOpenFiles(nativeHandle_); return maxOpenFiles(nativeHandle_);
} }
@Override @Override
public Options setMaxTotalWalSize(final long maxTotalWalSize) { public Options setMaxTotalWalSize(final long maxTotalWalSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxTotalWalSize(nativeHandle_, maxTotalWalSize); setMaxTotalWalSize(nativeHandle_, maxTotalWalSize);
return this; return this;
} }
@Override @Override
public long maxTotalWalSize() { public long maxTotalWalSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxTotalWalSize(nativeHandle_); return maxTotalWalSize(nativeHandle_);
} }
@Override @Override
public Options setMaxOpenFiles(final int maxOpenFiles) { public Options setMaxOpenFiles(final int maxOpenFiles) {
assert(isInitialized()); assert(isOwningHandle());
setMaxOpenFiles(nativeHandle_, maxOpenFiles); setMaxOpenFiles(nativeHandle_, maxOpenFiles);
return this; return this;
} }
@Override @Override
public boolean disableDataSync() { public boolean disableDataSync() {
assert(isInitialized()); assert(isOwningHandle());
return disableDataSync(nativeHandle_); return disableDataSync(nativeHandle_);
} }
@Override @Override
public Options setDisableDataSync(final boolean disableDataSync) { public Options setDisableDataSync(final boolean disableDataSync) {
assert(isInitialized()); assert(isOwningHandle());
setDisableDataSync(nativeHandle_, disableDataSync); setDisableDataSync(nativeHandle_, disableDataSync);
return this; return this;
} }
@Override @Override
public boolean useFsync() { public boolean useFsync() {
assert(isInitialized()); assert(isOwningHandle());
return useFsync(nativeHandle_); return useFsync(nativeHandle_);
} }
@Override @Override
public Options setUseFsync(final boolean useFsync) { public Options setUseFsync(final boolean useFsync) {
assert(isInitialized()); assert(isOwningHandle());
setUseFsync(nativeHandle_, useFsync); setUseFsync(nativeHandle_, useFsync);
return this; return this;
} }
@Override @Override
public String dbLogDir() { public String dbLogDir() {
assert(isInitialized()); assert(isOwningHandle());
return dbLogDir(nativeHandle_); return dbLogDir(nativeHandle_);
} }
@Override @Override
public Options setDbLogDir(final String dbLogDir) { public Options setDbLogDir(final String dbLogDir) {
assert(isInitialized()); assert(isOwningHandle());
setDbLogDir(nativeHandle_, dbLogDir); setDbLogDir(nativeHandle_, dbLogDir);
return this; return this;
} }
@Override @Override
public String walDir() { public String walDir() {
assert(isInitialized()); assert(isOwningHandle());
return walDir(nativeHandle_); return walDir(nativeHandle_);
} }
@Override @Override
public Options setWalDir(final String walDir) { public Options setWalDir(final String walDir) {
assert(isInitialized()); assert(isOwningHandle());
setWalDir(nativeHandle_, walDir); setWalDir(nativeHandle_, walDir);
return this; return this;
} }
@Override @Override
public long deleteObsoleteFilesPeriodMicros() { public long deleteObsoleteFilesPeriodMicros() {
assert(isInitialized()); assert(isOwningHandle());
return deleteObsoleteFilesPeriodMicros(nativeHandle_); return deleteObsoleteFilesPeriodMicros(nativeHandle_);
} }
@Override @Override
public Options setDeleteObsoleteFilesPeriodMicros( public Options setDeleteObsoleteFilesPeriodMicros(
final long micros) { final long micros) {
assert(isInitialized()); assert(isOwningHandle());
setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros); setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros);
return this; return this;
} }
@Override @Override
public int maxBackgroundCompactions() { public int maxBackgroundCompactions() {
assert(isInitialized()); assert(isOwningHandle());
return maxBackgroundCompactions(nativeHandle_); return maxBackgroundCompactions(nativeHandle_);
} }
@Override @Override
public Options createStatistics() { public Options createStatistics() {
assert(isInitialized()); assert(isOwningHandle());
createStatistics(nativeHandle_); createStatistics(nativeHandle_);
return this; return this;
} }
@Override @Override
public Statistics statisticsPtr() { public Statistics statisticsPtr() {
assert(isInitialized()); assert(isOwningHandle());
long statsPtr = statisticsPtr(nativeHandle_); long statsPtr = statisticsPtr(nativeHandle_);
if(statsPtr == 0) { if(statsPtr == 0) {
@ -365,74 +363,74 @@ public class Options extends RocksObject
@Override @Override
public Options setMaxBackgroundCompactions( public Options setMaxBackgroundCompactions(
final int maxBackgroundCompactions) { final int maxBackgroundCompactions) {
assert(isInitialized()); assert(isOwningHandle());
setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions); setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions);
return this; return this;
} }
@Override @Override
public int maxBackgroundFlushes() { public int maxBackgroundFlushes() {
assert(isInitialized()); assert(isOwningHandle());
return maxBackgroundFlushes(nativeHandle_); return maxBackgroundFlushes(nativeHandle_);
} }
@Override @Override
public Options setMaxBackgroundFlushes( public Options setMaxBackgroundFlushes(
final int maxBackgroundFlushes) { final int maxBackgroundFlushes) {
assert(isInitialized()); assert(isOwningHandle());
setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes); setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes);
return this; return this;
} }
@Override @Override
public long maxLogFileSize() { public long maxLogFileSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxLogFileSize(nativeHandle_); return maxLogFileSize(nativeHandle_);
} }
@Override @Override
public Options setMaxLogFileSize(final long maxLogFileSize) { public Options setMaxLogFileSize(final long maxLogFileSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxLogFileSize(nativeHandle_, maxLogFileSize); setMaxLogFileSize(nativeHandle_, maxLogFileSize);
return this; return this;
} }
@Override @Override
public long logFileTimeToRoll() { public long logFileTimeToRoll() {
assert(isInitialized()); assert(isOwningHandle());
return logFileTimeToRoll(nativeHandle_); return logFileTimeToRoll(nativeHandle_);
} }
@Override @Override
public Options setLogFileTimeToRoll(final long logFileTimeToRoll) { public Options setLogFileTimeToRoll(final long logFileTimeToRoll) {
assert(isInitialized()); assert(isOwningHandle());
setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll); setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll);
return this; return this;
} }
@Override @Override
public long keepLogFileNum() { public long keepLogFileNum() {
assert(isInitialized()); assert(isOwningHandle());
return keepLogFileNum(nativeHandle_); return keepLogFileNum(nativeHandle_);
} }
@Override @Override
public Options setKeepLogFileNum(final long keepLogFileNum) { public Options setKeepLogFileNum(final long keepLogFileNum) {
assert(isInitialized()); assert(isOwningHandle());
setKeepLogFileNum(nativeHandle_, keepLogFileNum); setKeepLogFileNum(nativeHandle_, keepLogFileNum);
return this; return this;
} }
@Override @Override
public long maxManifestFileSize() { public long maxManifestFileSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxManifestFileSize(nativeHandle_); return maxManifestFileSize(nativeHandle_);
} }
@Override @Override
public Options setMaxManifestFileSize( public Options setMaxManifestFileSize(
final long maxManifestFileSize) { final long maxManifestFileSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxManifestFileSize(nativeHandle_, maxManifestFileSize); setMaxManifestFileSize(nativeHandle_, maxManifestFileSize);
return this; return this;
} }
@ -441,7 +439,7 @@ public class Options extends RocksObject
public Options setMaxTableFilesSizeFIFO( public Options setMaxTableFilesSizeFIFO(
final long maxTableFilesSize) { final long maxTableFilesSize) {
assert(maxTableFilesSize > 0); // unsigned native type assert(maxTableFilesSize > 0); // unsigned native type
assert(isInitialized()); assert(isOwningHandle());
setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize); setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize);
return this; return this;
} }
@ -453,118 +451,118 @@ public class Options extends RocksObject
@Override @Override
public int tableCacheNumshardbits() { public int tableCacheNumshardbits() {
assert(isInitialized()); assert(isOwningHandle());
return tableCacheNumshardbits(nativeHandle_); return tableCacheNumshardbits(nativeHandle_);
} }
@Override @Override
public Options setTableCacheNumshardbits( public Options setTableCacheNumshardbits(
final int tableCacheNumshardbits) { final int tableCacheNumshardbits) {
assert(isInitialized()); assert(isOwningHandle());
setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits); setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits);
return this; return this;
} }
@Override @Override
public long walTtlSeconds() { public long walTtlSeconds() {
assert(isInitialized()); assert(isOwningHandle());
return walTtlSeconds(nativeHandle_); return walTtlSeconds(nativeHandle_);
} }
@Override @Override
public Options setWalTtlSeconds(final long walTtlSeconds) { public Options setWalTtlSeconds(final long walTtlSeconds) {
assert(isInitialized()); assert(isOwningHandle());
setWalTtlSeconds(nativeHandle_, walTtlSeconds); setWalTtlSeconds(nativeHandle_, walTtlSeconds);
return this; return this;
} }
@Override @Override
public long walSizeLimitMB() { public long walSizeLimitMB() {
assert(isInitialized()); assert(isOwningHandle());
return walSizeLimitMB(nativeHandle_); return walSizeLimitMB(nativeHandle_);
} }
@Override @Override
public Options setWalSizeLimitMB(final long sizeLimitMB) { public Options setWalSizeLimitMB(final long sizeLimitMB) {
assert(isInitialized()); assert(isOwningHandle());
setWalSizeLimitMB(nativeHandle_, sizeLimitMB); setWalSizeLimitMB(nativeHandle_, sizeLimitMB);
return this; return this;
} }
@Override @Override
public long manifestPreallocationSize() { public long manifestPreallocationSize() {
assert(isInitialized()); assert(isOwningHandle());
return manifestPreallocationSize(nativeHandle_); return manifestPreallocationSize(nativeHandle_);
} }
@Override @Override
public Options setManifestPreallocationSize(final long size) { public Options setManifestPreallocationSize(final long size) {
assert(isInitialized()); assert(isOwningHandle());
setManifestPreallocationSize(nativeHandle_, size); setManifestPreallocationSize(nativeHandle_, size);
return this; return this;
} }
@Override @Override
public boolean allowOsBuffer() { public boolean allowOsBuffer() {
assert(isInitialized()); assert(isOwningHandle());
return allowOsBuffer(nativeHandle_); return allowOsBuffer(nativeHandle_);
} }
@Override @Override
public Options setAllowOsBuffer(final boolean allowOsBuffer) { public Options setAllowOsBuffer(final boolean allowOsBuffer) {
assert(isInitialized()); assert(isOwningHandle());
setAllowOsBuffer(nativeHandle_, allowOsBuffer); setAllowOsBuffer(nativeHandle_, allowOsBuffer);
return this; return this;
} }
@Override @Override
public boolean allowMmapReads() { public boolean allowMmapReads() {
assert(isInitialized()); assert(isOwningHandle());
return allowMmapReads(nativeHandle_); return allowMmapReads(nativeHandle_);
} }
@Override @Override
public Options setAllowMmapReads(final boolean allowMmapReads) { public Options setAllowMmapReads(final boolean allowMmapReads) {
assert(isInitialized()); assert(isOwningHandle());
setAllowMmapReads(nativeHandle_, allowMmapReads); setAllowMmapReads(nativeHandle_, allowMmapReads);
return this; return this;
} }
@Override @Override
public boolean allowMmapWrites() { public boolean allowMmapWrites() {
assert(isInitialized()); assert(isOwningHandle());
return allowMmapWrites(nativeHandle_); return allowMmapWrites(nativeHandle_);
} }
@Override @Override
public Options setAllowMmapWrites(final boolean allowMmapWrites) { public Options setAllowMmapWrites(final boolean allowMmapWrites) {
assert(isInitialized()); assert(isOwningHandle());
setAllowMmapWrites(nativeHandle_, allowMmapWrites); setAllowMmapWrites(nativeHandle_, allowMmapWrites);
return this; return this;
} }
@Override @Override
public boolean isFdCloseOnExec() { public boolean isFdCloseOnExec() {
assert(isInitialized()); assert(isOwningHandle());
return isFdCloseOnExec(nativeHandle_); return isFdCloseOnExec(nativeHandle_);
} }
@Override @Override
public Options setIsFdCloseOnExec(final boolean isFdCloseOnExec) { public Options setIsFdCloseOnExec(final boolean isFdCloseOnExec) {
assert(isInitialized()); assert(isOwningHandle());
setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec); setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec);
return this; return this;
} }
@Override @Override
public int statsDumpPeriodSec() { public int statsDumpPeriodSec() {
assert(isInitialized()); assert(isOwningHandle());
return statsDumpPeriodSec(nativeHandle_); return statsDumpPeriodSec(nativeHandle_);
} }
@Override @Override
public Options setStatsDumpPeriodSec(final int statsDumpPeriodSec) { public Options setStatsDumpPeriodSec(final int statsDumpPeriodSec) {
assert(isInitialized()); assert(isOwningHandle());
setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec); setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec);
return this; return this;
} }
@ -576,20 +574,20 @@ public class Options extends RocksObject
@Override @Override
public Options setAdviseRandomOnOpen(final boolean adviseRandomOnOpen) { public Options setAdviseRandomOnOpen(final boolean adviseRandomOnOpen) {
assert(isInitialized()); assert(isOwningHandle());
setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen); setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen);
return this; return this;
} }
@Override @Override
public boolean useAdaptiveMutex() { public boolean useAdaptiveMutex() {
assert(isInitialized()); assert(isOwningHandle());
return useAdaptiveMutex(nativeHandle_); return useAdaptiveMutex(nativeHandle_);
} }
@Override @Override
public Options setUseAdaptiveMutex(final boolean useAdaptiveMutex) { public Options setUseAdaptiveMutex(final boolean useAdaptiveMutex) {
assert(isInitialized()); assert(isOwningHandle());
setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex);
return this; return this;
} }
@ -601,7 +599,7 @@ public class Options extends RocksObject
@Override @Override
public Options setBytesPerSync(final long bytesPerSync) { public Options setBytesPerSync(final long bytesPerSync) {
assert(isInitialized()); assert(isOwningHandle());
setBytesPerSync(nativeHandle_, bytesPerSync); setBytesPerSync(nativeHandle_, bytesPerSync);
return this; return this;
} }
@ -622,28 +620,28 @@ public class Options extends RocksObject
@Override @Override
public Options setLogger(final Logger logger) { public Options setLogger(final Logger logger) {
assert(isInitialized()); assert(isOwningHandle());
setLogger(nativeHandle_, logger.nativeHandle_); setLogger(nativeHandle_, logger.nativeHandle_);
return this; return this;
} }
@Override @Override
public Options setInfoLogLevel(final InfoLogLevel infoLogLevel) { public Options setInfoLogLevel(final InfoLogLevel infoLogLevel) {
assert(isInitialized()); assert(isOwningHandle());
setInfoLogLevel(nativeHandle_, infoLogLevel.getValue()); setInfoLogLevel(nativeHandle_, infoLogLevel.getValue());
return this; return this;
} }
@Override @Override
public InfoLogLevel infoLogLevel() { public InfoLogLevel infoLogLevel() {
assert(isInitialized()); assert(isOwningHandle());
return InfoLogLevel.getInfoLogLevel( return InfoLogLevel.getInfoLogLevel(
infoLogLevel(nativeHandle_)); infoLogLevel(nativeHandle_));
} }
@Override @Override
public String memTableFactoryName() { public String memTableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return memTableFactoryName(nativeHandle_); return memTableFactoryName(nativeHandle_);
} }
@ -656,20 +654,20 @@ public class Options extends RocksObject
@Override @Override
public String tableFactoryName() { public String tableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return tableFactoryName(nativeHandle_); return tableFactoryName(nativeHandle_);
} }
@Override @Override
public Options useFixedLengthPrefixExtractor(final int n) { public Options useFixedLengthPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useFixedLengthPrefixExtractor(nativeHandle_, n); useFixedLengthPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@Override @Override
public Options useCappedPrefixExtractor(final int n) { public Options useCappedPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useCappedPrefixExtractor(nativeHandle_, n); useCappedPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@ -1085,19 +1083,10 @@ public class Options extends RocksObject
return optimizeFiltersForHits(nativeHandle_); return optimizeFiltersForHits(nativeHandle_);
} }
/** private native static long newOptions();
* Release the memory allocated for the current instance private native static long newOptions(long dbOptHandle,
* in the c++ side.
*/
@Override protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_);
}
private native void newOptions();
private native void newOptions(long dbOptHandle,
long cfOptHandle); long cfOptHandle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native void setEnv(long optHandle, long envHandle); private native void setEnv(long optHandle, long envHandle);
private native void prepareForBulkLoad(long handle); private native void prepareForBulkLoad(long handle);

@ -13,10 +13,9 @@ package org.rocksdb;
*/ */
public class ReadOptions extends RocksObject { public class ReadOptions extends RocksObject {
public ReadOptions() { public ReadOptions() {
super(); super(newReadOptions());
newReadOptions();
} }
private native void newReadOptions(); private native static long newReadOptions();
/** /**
* If true, all data read from underlying storage will be * If true, all data read from underlying storage will be
@ -26,7 +25,7 @@ public class ReadOptions extends RocksObject {
* @return true if checksum verification is on. * @return true if checksum verification is on.
*/ */
public boolean verifyChecksums() { public boolean verifyChecksums() {
assert(isInitialized()); assert(isOwningHandle());
return verifyChecksums(nativeHandle_); return verifyChecksums(nativeHandle_);
} }
private native boolean verifyChecksums(long handle); private native boolean verifyChecksums(long handle);
@ -42,7 +41,7 @@ public class ReadOptions extends RocksObject {
*/ */
public ReadOptions setVerifyChecksums( public ReadOptions setVerifyChecksums(
final boolean verifyChecksums) { final boolean verifyChecksums) {
assert(isInitialized()); assert(isOwningHandle());
setVerifyChecksums(nativeHandle_, verifyChecksums); setVerifyChecksums(nativeHandle_, verifyChecksums);
return this; return this;
} }
@ -59,7 +58,7 @@ public class ReadOptions extends RocksObject {
* @return true if the fill-cache behavior is on. * @return true if the fill-cache behavior is on.
*/ */
public boolean fillCache() { public boolean fillCache() {
assert(isInitialized()); assert(isOwningHandle());
return fillCache(nativeHandle_); return fillCache(nativeHandle_);
} }
private native boolean fillCache(long handle); private native boolean fillCache(long handle);
@ -74,7 +73,7 @@ public class ReadOptions extends RocksObject {
* @return the reference to the current ReadOptions. * @return the reference to the current ReadOptions.
*/ */
public ReadOptions setFillCache(final boolean fillCache) { public ReadOptions setFillCache(final boolean fillCache) {
assert(isInitialized()); assert(isOwningHandle());
setFillCache(nativeHandle_, fillCache); setFillCache(nativeHandle_, fillCache);
return this; return this;
} }
@ -92,7 +91,7 @@ public class ReadOptions extends RocksObject {
* @return the reference to the current ReadOptions. * @return the reference to the current ReadOptions.
*/ */
public ReadOptions setSnapshot(final Snapshot snapshot) { public ReadOptions setSnapshot(final Snapshot snapshot) {
assert(isInitialized()); assert(isOwningHandle());
if (snapshot != null) { if (snapshot != null) {
setSnapshot(nativeHandle_, snapshot.nativeHandle_); setSnapshot(nativeHandle_, snapshot.nativeHandle_);
} else { } else {
@ -109,7 +108,7 @@ public class ReadOptions extends RocksObject {
* is assigned null. * is assigned null.
*/ */
public Snapshot snapshot() { public Snapshot snapshot() {
assert(isInitialized()); assert(isOwningHandle());
long snapshotHandle = snapshot(nativeHandle_); long snapshotHandle = snapshot(nativeHandle_);
if (snapshotHandle != 0) { if (snapshotHandle != 0) {
return new Snapshot(snapshotHandle); return new Snapshot(snapshotHandle);
@ -130,7 +129,7 @@ public class ReadOptions extends RocksObject {
* @return true if tailing iterator is enabled. * @return true if tailing iterator is enabled.
*/ */
public boolean tailing() { public boolean tailing() {
assert(isInitialized()); assert(isOwningHandle());
return tailing(nativeHandle_); return tailing(nativeHandle_);
} }
private native boolean tailing(long handle); private native boolean tailing(long handle);
@ -147,17 +146,13 @@ public class ReadOptions extends RocksObject {
* @return the reference to the current ReadOptions. * @return the reference to the current ReadOptions.
*/ */
public ReadOptions setTailing(final boolean tailing) { public ReadOptions setTailing(final boolean tailing) {
assert(isInitialized()); assert(isOwningHandle());
setTailing(nativeHandle_, tailing); setTailing(nativeHandle_, tailing);
return this; return this;
} }
private native void setTailing( private native void setTailing(
long handle, boolean tailing); long handle, boolean tailing);
@Override protected final native void disposeInternal(final long handle);
@Override protected void disposeInternal() {
disposeInternal(nativeHandle_);
}
private native void disposeInternal(long handle);
} }

@ -10,9 +10,8 @@ package org.rocksdb;
*/ */
public class RemoveEmptyValueCompactionFilter extends AbstractCompactionFilter<Slice> { public class RemoveEmptyValueCompactionFilter extends AbstractCompactionFilter<Slice> {
public RemoveEmptyValueCompactionFilter() { public RemoveEmptyValueCompactionFilter() {
super(); super(createNewRemoveEmptyValueCompactionFilter0());
createNewRemoveEmptyValueCompactionFilter0();
} }
private native void createNewRemoveEmptyValueCompactionFilter0(); private native static long createNewRemoveEmptyValueCompactionFilter0();
} }

@ -23,8 +23,7 @@ public class RestoreBackupableDB extends RocksObject {
* @param options {@link org.rocksdb.BackupableDBOptions} instance * @param options {@link org.rocksdb.BackupableDBOptions} instance
*/ */
public RestoreBackupableDB(final BackupableDBOptions options) { public RestoreBackupableDB(final BackupableDBOptions options) {
super(); super(newRestoreBackupableDB(options.nativeHandle_));
nativeHandle_ = newRestoreBackupableDB(options.nativeHandle_);
} }
/** /**
@ -52,7 +51,7 @@ public class RestoreBackupableDB extends RocksObject {
public void restoreDBFromBackup(final long backupId, final String dbDir, public void restoreDBFromBackup(final long backupId, final String dbDir,
final String walDir, final RestoreOptions restoreOptions) final String walDir, final RestoreOptions restoreOptions)
throws RocksDBException { throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
restoreDBFromBackup0(nativeHandle_, backupId, dbDir, walDir, restoreDBFromBackup0(nativeHandle_, backupId, dbDir, walDir,
restoreOptions.nativeHandle_); restoreOptions.nativeHandle_);
} }
@ -70,7 +69,7 @@ public class RestoreBackupableDB extends RocksObject {
public void restoreDBFromLatestBackup(final String dbDir, public void restoreDBFromLatestBackup(final String dbDir,
final String walDir, final RestoreOptions restoreOptions) final String walDir, final RestoreOptions restoreOptions)
throws RocksDBException { throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
restoreDBFromLatestBackup0(nativeHandle_, dbDir, walDir, restoreDBFromLatestBackup0(nativeHandle_, dbDir, walDir,
restoreOptions.nativeHandle_); restoreOptions.nativeHandle_);
} }
@ -85,7 +84,7 @@ public class RestoreBackupableDB extends RocksObject {
*/ */
public void purgeOldBackups(final int numBackupsToKeep) public void purgeOldBackups(final int numBackupsToKeep)
throws RocksDBException { throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
purgeOldBackups0(nativeHandle_, numBackupsToKeep); purgeOldBackups0(nativeHandle_, numBackupsToKeep);
} }
@ -99,7 +98,7 @@ public class RestoreBackupableDB extends RocksObject {
*/ */
public void deleteBackup(final int backupId) public void deleteBackup(final int backupId)
throws RocksDBException { throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
deleteBackup0(nativeHandle_, backupId); deleteBackup0(nativeHandle_, backupId);
} }
@ -110,7 +109,7 @@ public class RestoreBackupableDB extends RocksObject {
* @return List of {@link BackupInfo} instances. * @return List of {@link BackupInfo} instances.
*/ */
public List<BackupInfo> getBackupInfos() { public List<BackupInfo> getBackupInfos() {
assert(isInitialized()); assert(isOwningHandle());
return getBackupInfo(nativeHandle_); return getBackupInfo(nativeHandle_);
} }
@ -122,7 +121,7 @@ public class RestoreBackupableDB extends RocksObject {
* @return array of backup ids as int ids. * @return array of backup ids as int ids.
*/ */
public int[] getCorruptedBackups() { public int[] getCorruptedBackups() {
assert(isInitialized()); assert(isOwningHandle());
return getCorruptedBackups(nativeHandle_); return getCorruptedBackups(nativeHandle_);
} }
@ -135,19 +134,11 @@ public class RestoreBackupableDB extends RocksObject {
* native library. * native library.
*/ */
public void garbageCollect() throws RocksDBException { public void garbageCollect() throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
garbageCollect(nativeHandle_); garbageCollect(nativeHandle_);
} }
/** private native static long newRestoreBackupableDB(final long options);
* <p>Release the memory allocated for the current instance
* in the c++ side.</p>
*/
@Override public synchronized void disposeInternal() {
dispose(nativeHandle_);
}
private native long newRestoreBackupableDB(long options);
private native void restoreDBFromBackup0(long nativeHandle, long backupId, private native void restoreDBFromBackup0(long nativeHandle, long backupId,
String dbDir, String walDir, long restoreOptions) String dbDir, String walDir, long restoreOptions)
throws RocksDBException; throws RocksDBException;
@ -162,5 +153,5 @@ public class RestoreBackupableDB extends RocksObject {
private native int[] getCorruptedBackups(long handle); private native int[] getCorruptedBackups(long handle);
private native void garbageCollect(long handle) private native void garbageCollect(long handle)
throws RocksDBException; throws RocksDBException;
private native void dispose(long nativeHandle); @Override protected final native void disposeInternal(final long nativeHandle);
} }

@ -23,19 +23,9 @@ public class RestoreOptions extends RocksObject {
* Default: false * Default: false
*/ */
public RestoreOptions(final boolean keepLogFiles) { public RestoreOptions(final boolean keepLogFiles) {
super(); super(newRestoreOptions(keepLogFiles));
nativeHandle_ = newRestoreOptions(keepLogFiles);
} }
/** private native static long newRestoreOptions(boolean keepLogFiles);
* Release the memory allocated for the current instance @Override protected final native void disposeInternal(final long handle);
* in the c++ side.
*/
@Override public synchronized void disposeInternal() {
assert(isInitialized());
dispose(nativeHandle_);
}
private native long newRestoreOptions(boolean keepLogFiles);
private native void dispose(long handle);
} }

@ -179,9 +179,7 @@ public class RocksDB extends RocksObject {
// when non-default Options is used, keeping an Options reference // when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of // in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB. // the currently-created RocksDB.
RocksDB db = new RocksDB(); final RocksDB db = new RocksDB(open(options.nativeHandle_, path));
db.open(options.nativeHandle_, path);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
return db; return db;
} }
@ -225,13 +223,23 @@ public class RocksDB extends RocksObject {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors, final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
final List<ColumnFamilyHandle> columnFamilyHandles) final List<ColumnFamilyHandle> columnFamilyHandles)
throws RocksDBException { throws RocksDBException {
RocksDB db = new RocksDB();
List<Long> cfReferences = db.open(options.nativeHandle_, path, final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
columnFamilyDescriptors, columnFamilyDescriptors.size()); final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) { for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, cfReferences.get(i))); final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i);
cfNames[i] = cfDescriptor.columnFamilyName();
cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_;
} }
final long[] handles = open(options.nativeHandle_, path, cfNames, cfOptionHandles);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
}
return db; return db;
} }
@ -276,7 +284,7 @@ public class RocksDB extends RocksObject {
throws RocksDBException { throws RocksDBException {
// This allows to use the rocksjni default Options instead of // This allows to use the rocksjni default Options instead of
// the c++ one. // the c++ one.
DBOptions options = new DBOptions(); final DBOptions options = new DBOptions();
return openReadOnly(options, path, columnFamilyDescriptors, return openReadOnly(options, path, columnFamilyDescriptors,
columnFamilyHandles); columnFamilyHandles);
} }
@ -303,9 +311,7 @@ public class RocksDB extends RocksObject {
// when non-default Options is used, keeping an Options reference // when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of // in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB. // the currently-created RocksDB.
RocksDB db = new RocksDB(); final RocksDB db = new RocksDB(openROnly(options.nativeHandle_, path));
db.openROnly(options.nativeHandle_, path);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
return db; return db;
} }
@ -339,14 +345,23 @@ public class RocksDB extends RocksObject {
// when non-default Options is used, keeping an Options reference // when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of // in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB. // the currently-created RocksDB.
RocksDB db = new RocksDB();
List<Long> cfReferences = db.openROnly(options.nativeHandle_, path, final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
columnFamilyDescriptors, columnFamilyDescriptors.size()); final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i=0; i<columnFamilyDescriptors.size(); i++) { for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, cfReferences.get(i))); final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i);
cfNames[i] = cfDescriptor.columnFamilyName();
cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_;
} }
final long[] handles = openROnly(options.nativeHandle_, path, cfNames, cfOptionHandles);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
}
return db; return db;
} }
/** /**
@ -369,13 +384,6 @@ public class RocksDB extends RocksObject {
options_ = options; options_ = options;
} }
@Override protected void disposeInternal() {
synchronized (this) {
assert (isInitialized());
disposeInternal(nativeHandle_);
}
}
/** /**
* Close the RocksDB instance. * Close the RocksDB instance.
* This function is equivalent to dispose(). * This function is equivalent to dispose().
@ -1310,7 +1318,7 @@ public class RocksDB extends RocksObject {
// throws RocksDBException if something goes wrong // throws RocksDBException if something goes wrong
dropColumnFamily(nativeHandle_, columnFamilyHandle.nativeHandle_); dropColumnFamily(nativeHandle_, columnFamilyHandle.nativeHandle_);
// After the drop the native handle is not valid anymore // After the drop the native handle is not valid anymore
columnFamilyHandle.nativeHandle_ = 0; columnFamilyHandle.disOwnNativeHandle();
} }
/** /**
@ -1672,26 +1680,53 @@ public class RocksDB extends RocksObject {
/** /**
* Private constructor. * Private constructor.
*
* @param nativeHandle The native handle of the C++ RocksDB object
*/ */
protected RocksDB() { protected RocksDB(final long nativeHandle) {
super(); super(nativeHandle);
} }
// native methods // native methods
protected native void open( protected native static long open(final long optionsHandle,
long optionsHandle, String path) throws RocksDBException; final String path) throws RocksDBException;
protected native List<Long> open(long optionsHandle, String path,
List<ColumnFamilyDescriptor> columnFamilyDescriptors, /**
int columnFamilyDescriptorsLength) * @param optionsHandle Native handle pointing to an Options object
throws RocksDBException; * @param path The directory path for the database files
* @param columnFamilyNames An array of column family names
* @param columnFamilyOptions An array of native handles pointing to ColumnFamilyOptions objects
*
* @return An array of native handles, [0] is the handle of the RocksDB object
* [1..1+n] are handles of the ColumnFamilyReferences
*
* @throws RocksDBException thrown if the database could not be opened
*/
protected native static long[] open(final long optionsHandle,
final String path, final byte[][] columnFamilyNames,
final long[] columnFamilyOptions) throws RocksDBException;
protected native static long openROnly(final long optionsHandle,
final String path) throws RocksDBException;
/**
* @param optionsHandle Native handle pointing to an Options object
* @param path The directory path for the database files
* @param columnFamilyNames An array of column family names
* @param columnFamilyOptions An array of native handles pointing to ColumnFamilyOptions objects
*
* @return An array of native handles, [0] is the handle of the RocksDB object
* [1..1+n] are handles of the ColumnFamilyReferences
*
* @throws RocksDBException thrown if the database could not be opened
*/
protected native static long[] openROnly(final long optionsHandle,
final String path, final byte[][] columnFamilyNames,
final long[] columnFamilyOptions
) throws RocksDBException;
protected native static List<byte[]> listColumnFamilies( protected native static List<byte[]> listColumnFamilies(
long optionsHandle, String path) throws RocksDBException; long optionsHandle, String path) throws RocksDBException;
protected native void openROnly(
long optionsHandle, String path) throws RocksDBException;
protected native List<Long> openROnly(
long optionsHandle, String path,
List<ColumnFamilyDescriptor> columnFamilyDescriptors,
int columnFamilyDescriptorsLength) throws RocksDBException;
protected native void put( protected native void put(
long handle, byte[] key, int keyLen, long handle, byte[] key, int keyLen,
byte[] value, int valueLen) throws RocksDBException; byte[] value, int valueLen) throws RocksDBException;
@ -1793,7 +1828,7 @@ public class RocksDB extends RocksObject {
protected native long getSnapshot(long nativeHandle); protected native long getSnapshot(long nativeHandle);
protected native void releaseSnapshot( protected native void releaseSnapshot(
long nativeHandle, long snapshotHandle); long nativeHandle, long snapshotHandle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native long getDefaultColumnFamily(long handle); private native long getDefaultColumnFamily(long handle);
private native long createColumnFamily(long handle, private native long createColumnFamily(long handle,
ColumnFamilyDescriptor columnFamilyDescriptor) throws RocksDBException; ColumnFamilyDescriptor columnFamilyDescriptor) throws RocksDBException;

@ -24,8 +24,7 @@ public class RocksEnv extends Env {
* {@code dispose()} of the created RocksEnv will be no-op.</p> * {@code dispose()} of the created RocksEnv will be no-op.</p>
*/ */
RocksEnv(final long handle) { RocksEnv(final long handle) {
super(); super(handle);
nativeHandle_ = handle;
disOwnNativeHandle(); disOwnNativeHandle();
} }
@ -38,6 +37,7 @@ public class RocksEnv extends Env {
* RocksEnv with RocksJava. The default env allocation is managed * RocksEnv with RocksJava. The default env allocation is managed
* by C++.</p> * by C++.</p>
*/ */
@Override protected void disposeInternal() { @Override
protected final void disposeInternal(final long handle) {
} }
} }

@ -33,7 +33,7 @@ public class RocksIterator extends AbstractRocksIterator<RocksDB> {
* @return key for the current entry. * @return key for the current entry.
*/ */
public byte[] key() { public byte[] key() {
assert(isInitialized()); assert(isOwningHandle());
return key0(nativeHandle_); return key0(nativeHandle_);
} }
@ -46,11 +46,11 @@ public class RocksIterator extends AbstractRocksIterator<RocksDB> {
* @return value for the current entry. * @return value for the current entry.
*/ */
public byte[] value() { public byte[] value() {
assert(isInitialized()); assert(isOwningHandle());
return value0(nativeHandle_); return value0(nativeHandle_);
} }
@Override final native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
@Override final native boolean isValid0(long handle); @Override final native boolean isValid0(long handle);
@Override final native void seekToFirst0(long handle); @Override final native void seekToFirst0(long handle);
@Override final native void seekToLast0(long handle); @Override final native void seekToLast0(long handle);

@ -19,15 +19,9 @@ public class RocksMemEnv extends Env {
* <p>{@code *base_env} must remain live while the result is in use.</p> * <p>{@code *base_env} must remain live while the result is in use.</p>
*/ */
public RocksMemEnv() { public RocksMemEnv() {
super(); super(createMemEnv());
nativeHandle_ = createMemEnv();
}
@Override
protected void disposeInternal() {
disposeInternal(nativeHandle_);
} }
private static native long createMemEnv(); private static native long createMemEnv();
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
} }

@ -0,0 +1,33 @@
package org.rocksdb;
public abstract class RocksMutableObject extends NativeReference {
private final boolean shouldOwnHandle;
protected volatile long nativeHandle_;
protected RocksMutableObject() {
super(false);
this.shouldOwnHandle = false;
}
protected RocksMutableObject(final long nativeHandle) {
super(true);
this.shouldOwnHandle = true;
this.nativeHandle_ = nativeHandle;
}
@Override
public boolean isOwningHandle() {
return ((!shouldOwnHandle) || super.isOwningHandle()) && nativeHandle_ != 0;
}
/**
* Deletes underlying C++ object pointer.
*/
@Override
protected void disposeInternal() {
disposeInternal(nativeHandle_);
}
protected abstract void disposeInternal(final long handle);
}

@ -22,104 +22,25 @@ package org.rocksdb;
* as {@code dispose()} will be called in the finalizer during the * as {@code dispose()} will be called in the finalizer during the
* regular GC process.</p> * regular GC process.</p>
*/ */
public abstract class RocksObject { public abstract class RocksObject extends NativeReference {
protected RocksObject() {
nativeHandle_ = 0;
owningHandle_ = true;
}
/**
* Release the c++ object manually pointed by the native handle.
* <p>
* Note that {@code dispose()} will also be called during the GC process
* if it was not called before its {@code RocksObject} went out-of-scope.
* However, since Java may wrongly wrongly assume those objects are
* small in that they seems to only hold a long variable. As a result,
* they might have low priority in the GC process. To prevent this,
* it is suggested to call {@code dispose()} manually.
* </p>
* <p>
* Note that once an instance of {@code RocksObject} has been disposed,
* calling its function will lead undefined behavior.
* </p>
*/
public final synchronized void dispose() {
if (isOwningNativeHandle() && isInitialized()) {
disposeInternal();
}
nativeHandle_ = 0;
disOwnNativeHandle();
}
/**
* The helper function of {@code dispose()} which all subclasses of
* {@code RocksObject} must implement to release their associated
* C++ resource.
*/
protected abstract void disposeInternal();
/**
* Revoke ownership of the native object.
* <p>
* This will prevent the object from attempting to delete the underlying
* native object in its finalizer. This must be used when another object
* takes over ownership of the native object or both will attempt to delete
* the underlying object when garbage collected.
* <p>
* When {@code disOwnNativeHandle()} is called, {@code dispose()} will simply set
* {@code nativeHandle_} to 0 without releasing its associated C++ resource.
* As a result, incorrectly use this function may cause memory leak, and this
* function call will not affect the return value of {@code isInitialized()}.
* </p>
* @see #dispose()
* @see #isInitialized()
*/
protected void disOwnNativeHandle() {
owningHandle_ = false;
}
/** /**
* Returns true if the current {@code RocksObject} is responsible to release * A long variable holding c++ pointer pointing to some RocksDB C++ object.
* its native handle.
*
* @return true if the current {@code RocksObject} is responsible to release
* its native handle.
*
* @see #disOwnNativeHandle()
* @see #dispose()
*/ */
protected boolean isOwningNativeHandle() { protected final long nativeHandle_;
return owningHandle_;
}
/** protected RocksObject(final long nativeHandle) {
* Returns true if the associated native handle has been initialized. super(true);
* this.nativeHandle_ = nativeHandle;
* @return true if the associated native handle has been initialized.
*
* @see #dispose()
*/
protected boolean isInitialized() {
return (nativeHandle_ != 0);
} }
/** /**
* Simply calls {@code dispose()} and release its c++ resource if it has not * Deletes underlying C++ object pointer.
* yet released.
*/ */
@Override protected void finalize() throws Throwable { @Override
dispose(); protected void disposeInternal() {
super.finalize(); disposeInternal(nativeHandle_);
} }
/** protected abstract void disposeInternal(final long handle);
* A long variable holding c++ pointer pointing to some RocksDB C++ object.
*/
protected long nativeHandle_;
/**
* A flag indicating whether the current {@code RocksObject} is responsible to
* release the c++ object stored in its {@code nativeHandle_}.
*/
private boolean owningHandle_;
} }

@ -29,7 +29,6 @@ public class Slice extends AbstractSlice<byte[]> {
*/ */
private Slice() { private Slice() {
super(); super();
disOwnNativeHandle();
} }
/** /**
@ -39,8 +38,7 @@ public class Slice extends AbstractSlice<byte[]> {
* @param str String value. * @param str String value.
*/ */
public Slice(final String str) { public Slice(final String str) {
super(); super(createNewSliceFromString(str));
createNewSliceFromString(str);
} }
/** /**
@ -51,8 +49,7 @@ public class Slice extends AbstractSlice<byte[]> {
* @param offset offset within the byte array. * @param offset offset within the byte array.
*/ */
public Slice(final byte[] data, final int offset) { public Slice(final byte[] data, final int offset) {
super(); super(createNewSlice0(data, offset));
createNewSlice0(data, offset);
} }
/** /**
@ -62,8 +59,7 @@ public class Slice extends AbstractSlice<byte[]> {
* @param data byte array. * @param data byte array.
*/ */
public Slice(final byte[] data) { public Slice(final byte[] data) {
super(); super(createNewSlice1(data));
createNewSlice1(data);
} }
/** /**
@ -82,7 +78,8 @@ public class Slice extends AbstractSlice<byte[]> {
} }
@Override protected final native byte[] data0(long handle); @Override protected final native byte[] data0(long handle);
private native void createNewSlice0(byte[] data, int length); private native static long createNewSlice0(final byte[] data,
private native void createNewSlice1(byte[] data); final int length);
private native void disposeInternalBuf(long handle); private native static long createNewSlice1(final byte[] data);
private native void disposeInternalBuf(final long handle);
} }

@ -10,8 +10,7 @@ package org.rocksdb;
*/ */
public class Snapshot extends RocksObject { public class Snapshot extends RocksObject {
Snapshot(final long nativeHandle) { Snapshot(final long nativeHandle) {
super(); super(nativeHandle);
nativeHandle_ = nativeHandle;
} }
/** /**
@ -21,7 +20,7 @@ public class Snapshot extends RocksObject {
* this snapshot. * this snapshot.
*/ */
public long getSequenceNumber() { public long getSequenceNumber() {
assert(isInitialized()); assert(isOwningHandle());
return getSequenceNumber(nativeHandle_); return getSequenceNumber(nativeHandle_);
} }
@ -30,7 +29,8 @@ public class Snapshot extends RocksObject {
* to the snapshot is released by the database * to the snapshot is released by the database
* instance. * instance.
*/ */
@Override protected void disposeInternal() { @Override
protected final void disposeInternal(final long handle) {
} }
private native long getSequenceNumber(long handle); private native long getSequenceNumber(long handle);

@ -57,12 +57,7 @@ public class TransactionLogIterator extends RocksObject {
* @param nativeHandle address to native address. * @param nativeHandle address to native address.
*/ */
TransactionLogIterator(final long nativeHandle) { TransactionLogIterator(final long nativeHandle) {
super(); super(nativeHandle);
nativeHandle_ = nativeHandle;
}
@Override protected void disposeInternal() {
disposeInternal(nativeHandle_);
} }
/** /**
@ -107,7 +102,7 @@ public class TransactionLogIterator extends RocksObject {
private final WriteBatch writeBatch_; private final WriteBatch writeBatch_;
} }
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native boolean isValid(long handle); private native boolean isValid(long handle);
private native void next(long handle); private native void next(long handle);
private native void status(long handle) private native void status(long handle)

@ -84,9 +84,7 @@ public class TtlDB extends RocksDB {
*/ */
public static TtlDB open(final Options options, final String db_path, public static TtlDB open(final Options options, final String db_path,
final int ttl, final boolean readOnly) throws RocksDBException { final int ttl, final boolean readOnly) throws RocksDBException {
TtlDB ttldb = new TtlDB(); return new TtlDB(open(options.nativeHandle_, db_path, ttl, readOnly));
ttldb.open(options.nativeHandle_, db_path, ttl, readOnly);
return ttldb;
} }
/** /**
@ -117,12 +115,25 @@ public class TtlDB extends RocksDB {
throw new IllegalArgumentException("There must be a ttl value per column" + throw new IllegalArgumentException("There must be a ttl value per column" +
"family handle."); "family handle.");
} }
TtlDB ttlDB = new TtlDB();
List<Long> cfReferences = ttlDB.openCF(options.nativeHandle_, db_path, final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
columnFamilyDescriptors, columnFamilyDescriptors.size(), final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
ttlValues, readOnly); for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
for (int i=0; i<columnFamilyDescriptors.size(); i++) { final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i);
columnFamilyHandles.add(new ColumnFamilyHandle(ttlDB, cfReferences.get(i))); cfNames[i] = cfDescriptor.columnFamilyName();
cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_;
}
final int ttlVals[] = new int[ttlValues.size()];
for(int i = 0; i < ttlValues.size(); i++) {
ttlVals[i] = ttlValues.get(i);
}
final long[] handles = openCF(options.nativeHandle_, db_path,
cfNames, cfOptionHandles, ttlVals, readOnly);
final TtlDB ttlDB = new TtlDB(handles[0]);
for (int i = 1; i < handles.length; i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(ttlDB, handles[i]));
} }
return ttlDB; return ttlDB;
} }
@ -146,7 +157,6 @@ public class TtlDB extends RocksDB {
public ColumnFamilyHandle createColumnFamilyWithTtl( public ColumnFamilyHandle createColumnFamilyWithTtl(
final ColumnFamilyDescriptor columnFamilyDescriptor, final ColumnFamilyDescriptor columnFamilyDescriptor,
final int ttl) throws RocksDBException { final int ttl) throws RocksDBException {
assert(isInitialized());
return new ColumnFamilyHandle(this, return new ColumnFamilyHandle(this,
createColumnFamilyWithTtl(nativeHandle_, createColumnFamilyWithTtl(nativeHandle_,
columnFamilyDescriptor, ttl)); columnFamilyDescriptor, ttl));
@ -161,10 +171,9 @@ public class TtlDB extends RocksDB {
* c++ {@code rocksdb::TtlDB} and should be transparent to * c++ {@code rocksdb::TtlDB} and should be transparent to
* Java developers.</p> * Java developers.</p>
*/ */
@Override public synchronized void close() { @Override
if (isInitialized()) { public void close() {
super.close(); super.close();
}
} }
/** /**
@ -175,22 +184,25 @@ public class TtlDB extends RocksDB {
* {@link #open(DBOptions, String, java.util.List, java.util.List, * {@link #open(DBOptions, String, java.util.List, java.util.List,
* java.util.List, boolean)}. * java.util.List, boolean)}.
* </p> * </p>
*
* @param nativeHandle The native handle of the C++ TtlDB object
*/ */
protected TtlDB() { protected TtlDB(final long nativeHandle) {
super(); super(nativeHandle);
} }
@Override protected void finalize() throws Throwable { @Override protected void finalize() throws Throwable {
close(); close(); //TODO(AR) revisit here when implementing AutoCloseable
super.finalize(); super.finalize();
} }
private native void open(long optionsHandle, String db_path, int ttl, private native static long open(final long optionsHandle,
boolean readOnly) throws RocksDBException; final String db_path, final int ttl, final boolean readOnly)
private native List<Long> openCF(long optionsHandle, String db_path, throws RocksDBException;
List<ColumnFamilyDescriptor> columnFamilyDescriptors, private native static long[] openCF(final long optionsHandle,
int columnFamilyDescriptorsLength, List<Integer> ttlValues, final String db_path, final byte[][] columnFamilyNames,
boolean readOnly) throws RocksDBException; final long[] columnFamilyOptions, final int[] ttlValues,
final boolean readOnly) throws RocksDBException;
private native long createColumnFamilyWithTtl(long handle, private native long createColumnFamilyWithTtl(long handle,
ColumnFamilyDescriptor columnFamilyDescriptor, int ttl) ColumnFamilyDescriptor columnFamilyDescriptor, int ttl)
throws RocksDBException; throws RocksDBException;

@ -23,13 +23,13 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
* @return The WriteEntry of the current entry * @return The WriteEntry of the current entry
*/ */
public WriteEntry entry() { public WriteEntry entry() {
assert(isInitialized()); assert(isOwningHandle());
assert(entry != null); assert(entry != null);
entry1(nativeHandle_, entry); entry1(nativeHandle_, entry);
return entry; return entry;
} }
@Override final native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
@Override final native boolean isValid0(long handle); @Override final native boolean isValid0(long handle);
@Override final native void seekToFirst0(long handle); @Override final native void seekToFirst0(long handle);
@Override final native void seekToLast0(long handle); @Override final native void seekToLast0(long handle);
@ -110,7 +110,7 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
* no value * no value
*/ */
public DirectSlice getValue() { public DirectSlice getValue() {
if(!value.isInitialized()) { if(!value.isOwningHandle()) {
return null; //TODO(AR) migrate to JDK8 java.util.Optional#empty() return null; //TODO(AR) migrate to JDK8 java.util.Optional#empty()
} else { } else {
return value; return value;
@ -139,8 +139,8 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
final WriteEntry otherWriteEntry = (WriteEntry)other; final WriteEntry otherWriteEntry = (WriteEntry)other;
return type.equals(otherWriteEntry.type) return type.equals(otherWriteEntry.type)
&& key.equals(otherWriteEntry.key) && key.equals(otherWriteEntry.key)
&& (value.isInitialized() ? value.equals(otherWriteEntry.value) && (value.isOwningHandle() ? value.equals(otherWriteEntry.value)
: !otherWriteEntry.value.isInitialized()); : !otherWriteEntry.value.isOwningHandle());
} else { } else {
return false; return false;
} }

@ -27,8 +27,7 @@ public class WriteBatch extends AbstractWriteBatch {
* Constructs a WriteBatch instance. * Constructs a WriteBatch instance.
*/ */
public WriteBatch() { public WriteBatch() {
super(); this(0);
newWriteBatch(0);
} }
/** /**
@ -37,8 +36,7 @@ public class WriteBatch extends AbstractWriteBatch {
* @param reserved_bytes reserved size for WriteBatch * @param reserved_bytes reserved size for WriteBatch
*/ */
public WriteBatch(final int reserved_bytes) { public WriteBatch(final int reserved_bytes) {
nativeHandle_ = 0; super(newWriteBatch(reserved_bytes));
newWriteBatch(reserved_bytes);
} }
/** /**
@ -61,12 +59,11 @@ public class WriteBatch extends AbstractWriteBatch {
* @param nativeHandle address of native instance. * @param nativeHandle address of native instance.
*/ */
WriteBatch(final long nativeHandle) { WriteBatch(final long nativeHandle) {
super(); super(nativeHandle);
disOwnNativeHandle(); disOwnNativeHandle();
nativeHandle_ = nativeHandle;
} }
@Override final native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
@Override final native int count0(); @Override final native int count0();
@Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen); @Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen);
@Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen, @Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen,
@ -79,17 +76,18 @@ public class WriteBatch extends AbstractWriteBatch {
@Override final native void putLogData(byte[] blob, int blobLen); @Override final native void putLogData(byte[] blob, int blobLen);
@Override final native void clear0(); @Override final native void clear0();
private native void newWriteBatch(int reserved_bytes); private native static long newWriteBatch(int reserved_bytes);
private native void iterate(long handlerHandle) throws RocksDBException; private native void iterate(long handlerHandle) throws RocksDBException;
/** /**
* Handler callback for iterating over the contents of a batch. * Handler callback for iterating over the contents of a batch.
*/ */
public static abstract class Handler extends RocksObject { public static abstract class Handler extends NativeReference {
private final long nativeHandle_;
public Handler() { public Handler() {
super(); super(true);
createNewHandler0(); this.nativeHandle_ = createNewHandler0();
} }
public abstract void put(byte[] key, byte[] value); public abstract void put(byte[] key, byte[] value);
@ -116,11 +114,10 @@ public class WriteBatch extends AbstractWriteBatch {
*/ */
@Override @Override
protected void disposeInternal() { protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_); disposeInternal(nativeHandle_);
} }
private native void createNewHandler0(); private native long createNewHandler0();
private native void disposeInternal(long handle); private native void disposeInternal(final long handle);
} }
} }

@ -25,8 +25,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* and duplicate keys operations are retained * and duplicate keys operations are retained
*/ */
public WriteBatchWithIndex() { public WriteBatchWithIndex() {
super(); super(newWriteBatchWithIndex());
newWriteBatchWithIndex();
} }
@ -41,8 +40,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* show two entries with the same key. * show two entries with the same key.
*/ */
public WriteBatchWithIndex(final boolean overwriteKey) { public WriteBatchWithIndex(final boolean overwriteKey) {
super(); super(newWriteBatchWithIndex(overwriteKey));
newWriteBatchWithIndex(overwriteKey);
} }
/** /**
@ -60,8 +58,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
*/ */
public WriteBatchWithIndex(final AbstractComparator<? extends AbstractSlice<?>> public WriteBatchWithIndex(final AbstractComparator<? extends AbstractSlice<?>>
fallbackIndexComparator, final int reservedBytes, final boolean overwriteKey) { fallbackIndexComparator, final int reservedBytes, final boolean overwriteKey) {
super(); super(newWriteBatchWithIndex(fallbackIndexComparator.getNativeHandle(), reservedBytes, overwriteKey));
newWriteBatchWithIndex(fallbackIndexComparator.nativeHandle_, reservedBytes, overwriteKey);
} }
/** /**
@ -126,7 +123,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
return newIteratorWithBase(baseIterator.parent_.getDefaultColumnFamily(), baseIterator); return newIteratorWithBase(baseIterator.parent_.getDefaultColumnFamily(), baseIterator);
} }
@Override final native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
@Override final native int count0(); @Override final native int count0();
@Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen); @Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen);
@Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen, @Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen,
@ -139,10 +136,11 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
@Override final native void putLogData(byte[] blob, int blobLen); @Override final native void putLogData(byte[] blob, int blobLen);
@Override final native void clear0(); @Override final native void clear0();
private native void newWriteBatchWithIndex(); private native static long newWriteBatchWithIndex();
private native void newWriteBatchWithIndex(boolean overwriteKey); private native static long newWriteBatchWithIndex(final boolean overwriteKey);
private native void newWriteBatchWithIndex(long fallbackIndexComparatorHandle, int reservedBytes, private native static long newWriteBatchWithIndex(
boolean overwriteKey); final long fallbackIndexComparatorHandle, final int reservedBytes,
final boolean overwriteKey);
private native long iterator0(); private native long iterator0();
private native long iterator1(long cfHandle); private native long iterator1(long cfHandle);
private native long iteratorWithBase(long baseIteratorHandle, long cfHandle); private native long iteratorWithBase(long baseIteratorHandle, long cfHandle);

@ -16,13 +16,8 @@ public class WriteOptions extends RocksObject {
* Construct WriteOptions instance. * Construct WriteOptions instance.
*/ */
public WriteOptions() { public WriteOptions() {
super(); super(newWriteOptions());
newWriteOptions();
}
@Override protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_);
} }
/** /**
@ -97,10 +92,10 @@ public class WriteOptions extends RocksObject {
return disableWAL(nativeHandle_); return disableWAL(nativeHandle_);
} }
private native void newWriteOptions(); private native static long newWriteOptions();
private native void setSync(long handle, boolean flag); private native void setSync(long handle, boolean flag);
private native boolean sync(long handle); private native boolean sync(long handle);
private native void setDisableWAL(long handle, boolean flag); private native void setDisableWAL(long handle, boolean flag);
private native boolean disableWAL(long handle); private native boolean disableWAL(long handle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
} }

@ -209,7 +209,9 @@ public class WriteBatchWithIndexTest {
it.seek(key); it.seek(key);
assertThat(it.isValid()).isTrue(); assertThat(it.isValid()).isTrue();
assertThat(it.entry().equals(expected[testOffset])).isTrue();
final WBWIRocksIterator.WriteEntry entry = it.entry();
assertThat(entry.equals(expected[testOffset])).isTrue();
} }
//forward iterative access //forward iterative access

Loading…
Cancel
Save