From 18eb563058f19856a2723f4cbe867aee7959cc6c Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Wed, 20 Jan 2016 17:05:41 +0000 Subject: [PATCH] Improve the speed and synchronization around the construction of Java/JNI objects --- java/rocksjni/backupablejni.cc | 23 +- java/rocksjni/backupenginejni.cc | 14 +- java/rocksjni/comparator.cc | 12 +- java/rocksjni/filter.cc | 12 +- java/rocksjni/loggerjnicallback.cc | 12 +- java/rocksjni/options.cc | 69 ++-- java/rocksjni/portal.h | 8 +- .../remove_emptyvalue_compactionfilterjni.cc | 13 +- java/rocksjni/restorejni.cc | 16 +- java/rocksjni/rocksjni.cc | 295 +++++++----------- java/rocksjni/slice.cc | 48 +-- java/rocksjni/ttl.cc | 146 ++++----- java/rocksjni/write_batch.cc | 15 +- java/rocksjni/write_batch_with_index.cc | 24 +- .../org/rocksdb/AbstractCompactionFilter.java | 12 +- .../java/org/rocksdb/AbstractComparator.java | 17 +- .../org/rocksdb/AbstractRocksIterator.java | 23 +- .../main/java/org/rocksdb/AbstractSlice.java | 42 +-- .../java/org/rocksdb/AbstractWriteBatch.java | 33 +- .../main/java/org/rocksdb/BackupEngine.java | 36 +-- .../main/java/org/rocksdb/BackupableDB.java | 29 +- .../java/org/rocksdb/BackupableDBOptions.java | 53 ++-- .../main/java/org/rocksdb/BloomFilter.java | 16 +- .../src/main/java/org/rocksdb/Checkpoint.java | 18 +- .../java/org/rocksdb/ColumnFamilyHandle.java | 17 +- .../java/org/rocksdb/ColumnFamilyOptions.java | 45 +-- .../src/main/java/org/rocksdb/Comparator.java | 12 +- .../java/org/rocksdb/ComparatorOptions.java | 16 +- java/src/main/java/org/rocksdb/DBOptions.java | 149 ++++----- .../java/org/rocksdb/DirectComparator.java | 12 +- .../main/java/org/rocksdb/DirectSlice.java | 32 +- java/src/main/java/org/rocksdb/Env.java | 4 +- java/src/main/java/org/rocksdb/Filter.java | 12 +- .../main/java/org/rocksdb/FlushOptions.java | 15 +- java/src/main/java/org/rocksdb/Logger.java | 17 +- .../java/org/rocksdb/NativeReference.java | 77 +++++ java/src/main/java/org/rocksdb/Options.java | 173 +++++----- .../main/java/org/rocksdb/ReadOptions.java | 27 +- .../RemoveEmptyValueCompactionFilter.java | 5 +- .../java/org/rocksdb/RestoreBackupableDB.java | 29 +- .../main/java/org/rocksdb/RestoreOptions.java | 16 +- java/src/main/java/org/rocksdb/RocksDB.java | 113 ++++--- java/src/main/java/org/rocksdb/RocksEnv.java | 6 +- .../main/java/org/rocksdb/RocksIterator.java | 6 +- .../main/java/org/rocksdb/RocksMemEnv.java | 10 +- .../java/org/rocksdb/RocksMutableObject.java | 33 ++ .../main/java/org/rocksdb/RocksObject.java | 107 +------ java/src/main/java/org/rocksdb/Slice.java | 17 +- java/src/main/java/org/rocksdb/Snapshot.java | 8 +- .../org/rocksdb/TransactionLogIterator.java | 9 +- java/src/main/java/org/rocksdb/TtlDB.java | 56 ++-- .../java/org/rocksdb/WBWIRocksIterator.java | 10 +- .../src/main/java/org/rocksdb/WriteBatch.java | 25 +- .../java/org/rocksdb/WriteBatchWithIndex.java | 20 +- .../main/java/org/rocksdb/WriteOptions.java | 11 +- .../org/rocksdb/WriteBatchWithIndexTest.java | 4 +- 56 files changed, 968 insertions(+), 1111 deletions(-) create mode 100644 java/src/main/java/org/rocksdb/NativeReference.java create mode 100644 java/src/main/java/org/rocksdb/RocksMutableObject.java diff --git a/java/rocksjni/backupablejni.cc b/java/rocksjni/backupablejni.cc index f2304dadb..a7aa6e3ef 100644 --- a/java/rocksjni/backupablejni.cc +++ b/java/rocksjni/backupablejni.cc @@ -21,17 +21,17 @@ /* * Class: org_rocksdb_BackupableDB * Method: open - * Signature: (JJ)V + * Signature: (JJ)J */ -void Java_org_rocksdb_BackupableDB_open( - JNIEnv* env, jobject jbdb, jlong jdb_handle, jlong jopt_handle) { - auto db = reinterpret_cast(jdb_handle); - auto opt = reinterpret_cast(jopt_handle); +jlong Java_org_rocksdb_BackupableDB_open( + JNIEnv* env, jclass jcls, jlong jdb_handle, jlong jopt_handle) { + auto* db = reinterpret_cast(jdb_handle); + auto* opt = reinterpret_cast(jopt_handle); auto bdb = new rocksdb::BackupableDB(db, *opt); // as BackupableDB extends RocksDB on the java side, we can reuse // the RocksDB portal here. - rocksdb::RocksDBJni::setHandle(env, jbdb, bdb); + return reinterpret_cast(bdb); } /* @@ -135,14 +135,14 @@ void Java_org_rocksdb_BackupableDB_garbageCollect(JNIEnv* env, /* * Class: org_rocksdb_BackupableDBOptions * Method: newBackupableDBOptions - * Signature: (Ljava/lang/String;)V + * Signature: (Ljava/lang/String;)J */ -void Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions( - JNIEnv* env, jobject jobj, jstring jpath) { - const char* cpath = env->GetStringUTFChars(jpath, 0); +jlong Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions( + JNIEnv* env, jclass jcls, jstring jpath) { + const char* cpath = env->GetStringUTFChars(jpath, NULL); auto bopt = new rocksdb::BackupableDBOptions(cpath); env->ReleaseStringUTFChars(jpath, cpath); - rocksdb::BackupableDBOptionsJni::setHandle(env, jobj, bopt); + return reinterpret_cast(bopt); } /* @@ -320,5 +320,4 @@ void Java_org_rocksdb_BackupableDBOptions_disposeInternal( auto bopt = reinterpret_cast(jhandle); assert(bopt); delete bopt; - rocksdb::BackupableDBOptionsJni::setHandle(env, jopt, nullptr); } diff --git a/java/rocksjni/backupenginejni.cc b/java/rocksjni/backupenginejni.cc index a42399873..a796d6e5b 100644 --- a/java/rocksjni/backupenginejni.cc +++ b/java/rocksjni/backupenginejni.cc @@ -16,10 +16,10 @@ /* * Class: org_rocksdb_BackupEngine * Method: open - * Signature: (JJ)V + * Signature: (JJ)J */ -void Java_org_rocksdb_BackupEngine_open( - JNIEnv* env, jobject jbe, jlong env_handle, +jlong Java_org_rocksdb_BackupEngine_open( + JNIEnv* env, jclass jcls, jlong env_handle, jlong backupable_db_options_handle) { auto* rocks_env = reinterpret_cast(env_handle); auto* backupable_db_options = @@ -30,11 +30,11 @@ void Java_org_rocksdb_BackupEngine_open( *backupable_db_options, &backup_engine); if (status.ok()) { - rocksdb::BackupEngineJni::setHandle(env, jbe, backup_engine); - return; + return reinterpret_cast(backup_engine); + } else { + rocksdb::RocksDBExceptionJni::ThrowNew(env, status); + return 0; } - - rocksdb::RocksDBExceptionJni::ThrowNew(env, status); } /* diff --git a/java/rocksjni/comparator.cc b/java/rocksjni/comparator.cc index 8765daa34..dd11f10e4 100644 --- a/java/rocksjni/comparator.cc +++ b/java/rocksjni/comparator.cc @@ -36,15 +36,15 @@ void Java_org_rocksdb_AbstractComparator_disposeInternal( /* * Class: org_rocksdb_Comparator * 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) { const rocksdb::ComparatorJniCallbackOptions* copt = reinterpret_cast(copt_handle); const rocksdb::ComparatorJniCallback* c = new rocksdb::ComparatorJniCallback(env, jobj, copt); - rocksdb::AbstractComparatorJni::setHandle(env, jobj, c); + return reinterpret_cast(c); } // @@ -53,14 +53,14 @@ void Java_org_rocksdb_Comparator_createNewComparator0( /* * Class: org_rocksdb_DirectComparator * 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) { const rocksdb::ComparatorJniCallbackOptions* copt = reinterpret_cast(copt_handle); const rocksdb::DirectComparatorJniCallback* c = new rocksdb::DirectComparatorJniCallback(env, jobj, copt); - rocksdb::AbstractComparatorJni::setHandle(env, jobj, c); + return reinterpret_cast(c); } // diff --git a/java/rocksjni/filter.cc b/java/rocksjni/filter.cc index 2b662d03f..96ef9856b 100644 --- a/java/rocksjni/filter.cc +++ b/java/rocksjni/filter.cc @@ -19,17 +19,17 @@ /* * Class: org_rocksdb_BloomFilter * Method: createBloomFilter - * Signature: (IZ)V + * Signature: (IZ)J */ -void Java_org_rocksdb_BloomFilter_createNewBloomFilter( - JNIEnv* env, jobject jobj, jint bits_per_key, +jlong Java_org_rocksdb_BloomFilter_createNewBloomFilter( + JNIEnv* env, jclass jcls, jint bits_per_key, jboolean use_block_base_builder) { - rocksdb::FilterPolicy* fp = const_cast( + auto* fp = const_cast( rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder)); - std::shared_ptr *pFilterPolicy = + auto* pFilterPolicy = new std::shared_ptr; *pFilterPolicy = std::shared_ptr(fp); - rocksdb::FilterJni::setHandle(env, jobj, pFilterPolicy); + return reinterpret_cast(pFilterPolicy); } /* diff --git a/java/rocksjni/loggerjnicallback.cc b/java/rocksjni/loggerjnicallback.cc index 56857b750..d92b17c22 100644 --- a/java/rocksjni/loggerjnicallback.cc +++ b/java/rocksjni/loggerjnicallback.cc @@ -125,9 +125,9 @@ LoggerJniCallback::~LoggerJniCallback() { /* * Class: org_rocksdb_Logger * 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) { rocksdb::LoggerJniCallback* c = new rocksdb::LoggerJniCallback(env, jobj); @@ -137,15 +137,15 @@ void Java_org_rocksdb_Logger_createNewLoggerOptions( std::shared_ptr *pLoggerJniCallback = new std::shared_ptr; *pLoggerJniCallback = std::shared_ptr(c); - rocksdb::LoggerJni::setHandle(env, jobj, pLoggerJniCallback); + return reinterpret_cast(pLoggerJniCallback); } /* * Class: org_rocksdb_Logger * 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) { rocksdb::LoggerJniCallback* c = new rocksdb::LoggerJniCallback(env, jobj); @@ -155,7 +155,7 @@ void Java_org_rocksdb_Logger_createNewLoggerDbOptions( std::shared_ptr *pLoggerJniCallback = new std::shared_ptr; *pLoggerJniCallback = std::shared_ptr(c); - rocksdb::LoggerJni::setHandle(env, jobj, pLoggerJniCallback); + return reinterpret_cast(pLoggerJniCallback); } /* diff --git a/java/rocksjni/options.cc b/java/rocksjni/options.cc index 9cb466538..b8d7684ec 100644 --- a/java/rocksjni/options.cc +++ b/java/rocksjni/options.cc @@ -36,25 +36,25 @@ /* * Class: org_rocksdb_Options * 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::OptionsJni::setHandle(env, jobj, op); + return reinterpret_cast(op); } /* * Class: org_rocksdb_Options * 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) { - auto dbOpt = reinterpret_cast(jdboptions); - auto cfOpt = reinterpret_cast( + auto* dbOpt = reinterpret_cast(jdboptions); + auto* cfOpt = reinterpret_cast( jcfoptions); rocksdb::Options* op = new rocksdb::Options(*dbOpt, *cfOpt); - rocksdb::OptionsJni::setHandle(env, jobj, op); + return reinterpret_cast(op); } /* @@ -1932,12 +1932,12 @@ void Java_org_rocksdb_Options_prepareForBulkLoad( /* * Class: org_rocksdb_ColumnFamilyOptions * Method: newColumnFamilyOptions - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions( - JNIEnv* env, jobject jobj) { +jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions( + JNIEnv* env, jclass jcls) { rocksdb::ColumnFamilyOptions* op = new rocksdb::ColumnFamilyOptions(); - rocksdb::ColumnFamilyOptionsJni::setHandle(env, jobj, op); + return reinterpret_cast(op); } /* @@ -3072,12 +3072,12 @@ void Java_org_rocksdb_ColumnFamilyOptions_setOptimizeFiltersForHits( /* * Class: org_rocksdb_DBOptions * Method: newDBOptions - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env, - jobject jobj) { +jlong Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env, + jclass jcls) { rocksdb::DBOptions* dbop = new rocksdb::DBOptions(); - rocksdb::DBOptionsJni::setHandle(env, jobj, dbop); + return reinterpret_cast(dbop); } /* @@ -3872,12 +3872,12 @@ jlong Java_org_rocksdb_DBOptions_bytesPerSync( /* * Class: org_rocksdb_WriteOptions * Method: newWriteOptions - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_WriteOptions_newWriteOptions( - JNIEnv* env, jobject jwrite_options) { +jlong Java_org_rocksdb_WriteOptions_newWriteOptions( + JNIEnv* env, jclass jcls) { rocksdb::WriteOptions* op = new rocksdb::WriteOptions(); - rocksdb::WriteOptionsJni::setHandle(env, jwrite_options, op); + return reinterpret_cast(op); } /* @@ -3889,8 +3889,6 @@ void Java_org_rocksdb_WriteOptions_disposeInternal( JNIEnv* env, jobject jwrite_options, jlong jhandle) { auto write_options = reinterpret_cast(jhandle); delete write_options; - - rocksdb::WriteOptionsJni::setHandle(env, jwrite_options, nullptr); } /* @@ -3939,12 +3937,12 @@ jboolean Java_org_rocksdb_WriteOptions_disableWAL( /* * Class: org_rocksdb_ReadOptions * Method: newReadOptions - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_ReadOptions_newReadOptions( - JNIEnv* env, jobject jobj) { +jlong Java_org_rocksdb_ReadOptions_newReadOptions( + JNIEnv* env, jclass jcls) { auto read_opt = new rocksdb::ReadOptions(); - rocksdb::ReadOptionsJni::setHandle(env, jobj, read_opt); + return reinterpret_cast(read_opt); } /* @@ -3955,7 +3953,6 @@ void Java_org_rocksdb_ReadOptions_newReadOptions( void Java_org_rocksdb_ReadOptions_disposeInternal( JNIEnv* env, jobject jobj, jlong jhandle) { delete reinterpret_cast(jhandle); - rocksdb::ReadOptionsJni::setHandle(env, jobj, nullptr); } /* @@ -4052,12 +4049,12 @@ jlong Java_org_rocksdb_ReadOptions_snapshot( /* * Class: org_rocksdb_ComparatorOptions * Method: newComparatorOptions - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_ComparatorOptions_newComparatorOptions( - JNIEnv* env, jobject jobj) { +jlong Java_org_rocksdb_ComparatorOptions_newComparatorOptions( + JNIEnv* env, jclass jcls) { auto comparator_opt = new rocksdb::ComparatorJniCallbackOptions(); - rocksdb::ComparatorOptionsJni::setHandle(env, jobj, comparator_opt); + return reinterpret_cast(comparator_opt); } /* @@ -4090,7 +4087,6 @@ void Java_org_rocksdb_ComparatorOptions_setUseAdaptiveMutex( void Java_org_rocksdb_ComparatorOptions_disposeInternal( JNIEnv * env, jobject jobj, jlong jhandle) { delete reinterpret_cast(jhandle); - rocksdb::ComparatorOptionsJni::setHandle(env, jobj, nullptr); } ///////////////////////////////////////////////////////////////////// @@ -4099,12 +4095,12 @@ void Java_org_rocksdb_ComparatorOptions_disposeInternal( /* * Class: org_rocksdb_FlushOptions * Method: newFlushOptions - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_FlushOptions_newFlushOptions( - JNIEnv* env, jobject jobj) { +jlong Java_org_rocksdb_FlushOptions_newFlushOptions( + JNIEnv* env, jclass jcls) { auto flush_opt = new rocksdb::FlushOptions(); - rocksdb::FlushOptionsJni::setHandle(env, jobj, flush_opt); + return reinterpret_cast(flush_opt); } /* @@ -4137,5 +4133,4 @@ jboolean Java_org_rocksdb_FlushOptions_waitForFlush( void Java_org_rocksdb_FlushOptions_disposeInternal( JNIEnv * env, jobject jobj, jlong jhandle) { delete reinterpret_cast(jhandle); - rocksdb::FlushOptionsJni::setHandle(env, jobj, nullptr); } diff --git a/java/rocksjni/portal.h b/java/rocksjni/portal.h index 0c5a9245f..9f93be4d1 100644 --- a/java/rocksjni/portal.h +++ b/java/rocksjni/portal.h @@ -64,11 +64,15 @@ template class RocksDBNativeClass { return reinterpret_cast( env->GetLongField(jobj, getHandleFieldID(env))); } +}; +// Native class template for sub-classes of RocksMutableObject +template class NativeRocksMutableObject : public RocksDBNativeClass { + public: // Pass the pointer to the java side. static void setHandle(JNIEnv* env, jobject jdb, PTR ptr) { env->SetLongField( - jdb, getHandleFieldID(env), + jdb, RocksDBNativeClass::getHandleFieldID(env), reinterpret_cast(ptr)); } }; @@ -407,7 +411,7 @@ class AbstractComparatorJni : public RocksDBNativeClass< }; // The portal class for org.rocksdb.AbstractSlice -class AbstractSliceJni : public RocksDBNativeClass< +class AbstractSliceJni : public NativeRocksMutableObject< const rocksdb::Slice*, AbstractSliceJni> { public: static jclass getJClass(JNIEnv* env) { diff --git a/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc b/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc index 3cf7b3a03..ef17efeec 100644 --- a/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc +++ b/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc @@ -12,16 +12,13 @@ /* * Class: org_rocksdb_RemoveEmptyValueCompactionFilter * Method: createNewRemoveEmptyValueCompactionFilter0 - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_RemoveEmptyValueCompactionFilter_createNewRemoveEmptyValueCompactionFilter0( - JNIEnv* env, jobject jobj) { - const rocksdb::RemoveEmptyValueCompactionFilter* compaction_filter = +jlong Java_org_rocksdb_RemoveEmptyValueCompactionFilter_createNewRemoveEmptyValueCompactionFilter0( + JNIEnv* env, jclass jcls) { + auto* compaction_filter = new rocksdb::RemoveEmptyValueCompactionFilter(); // set the native handle to our native compaction filter - static jclass jclazz = - env->FindClass("org/rocksdb/RemoveEmptyValueCompactionFilter"); - static jfieldID fid = env->GetFieldID(jclazz, "nativeHandle_", "J"); - env->SetLongField(jobj, fid, reinterpret_cast(compaction_filter)); + return reinterpret_cast(compaction_filter); } diff --git a/java/rocksjni/restorejni.cc b/java/rocksjni/restorejni.cc index 40b13dac5..e86571dd5 100644 --- a/java/rocksjni/restorejni.cc +++ b/java/rocksjni/restorejni.cc @@ -22,17 +22,17 @@ * Signature: (Z)J */ 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); return reinterpret_cast(ropt); } /* * Class: org_rocksdb_RestoreOptions - * Method: dispose + * Method: disposeInternal * 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) { auto ropt = reinterpret_cast(jhandle); assert(ropt); @@ -45,8 +45,8 @@ void Java_org_rocksdb_RestoreOptions_dispose(JNIEnv* env, jobject jobj, * Signature: (J)J */ jlong Java_org_rocksdb_RestoreBackupableDB_newRestoreBackupableDB(JNIEnv* env, - jobject jobj, jlong jopt_handle) { - auto opt = reinterpret_cast(jopt_handle); + jclass jcls, jlong jopt_handle) { + auto* opt = reinterpret_cast(jopt_handle); auto rdb = new rocksdb::RestoreBackupableDB(rocksdb::Env::Default(), *opt); return reinterpret_cast(rdb); } @@ -185,11 +185,11 @@ void Java_org_rocksdb_RestoreBackupableDB_garbageCollect( /* * Class: org_rocksdb_RestoreBackupableDB - * Method: dispose + * Method: disposeInternal * Signature: (J)V */ -void Java_org_rocksdb_RestoreBackupableDB_dispose(JNIEnv* env, jobject jobj, - jlong jhandle) { +void Java_org_rocksdb_RestoreBackupableDB_disposeInternal(JNIEnv* env, + jobject jobj, jlong jhandle) { auto ropt = reinterpret_cast(jhandle); assert(ropt); delete ropt; diff --git a/java/rocksjni/rocksjni.cc b/java/rocksjni/rocksjni.cc index d9c0c6147..eb704ad26 100644 --- a/java/rocksjni/rocksjni.cc +++ b/java/rocksjni/rocksjni.cc @@ -26,217 +26,142 @@ ////////////////////////////////////////////////////////////////////////////// // rocksdb::DB::Open - -/* - * Class: org_rocksdb_RocksDB - * Method: open - * Signature: (JLjava/lang/String;)V - */ -void Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2( - JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) { - auto opt = reinterpret_cast(jopt_handle); +jlong rocksdb_open_helper(JNIEnv* env, jlong jopt_handle, jstring jdb_path, + std::function open_fn + ) { + auto* opt = reinterpret_cast(jopt_handle); rocksdb::DB* db = nullptr; - const char* db_path = env->GetStringUTFChars(jdb_path, 0); - rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, &db); + const char* db_path = env->GetStringUTFChars(jdb_path, NULL); + rocksdb::Status s = open_fn(*opt, db_path, &db); env->ReleaseStringUTFChars(jdb_path, db_path); if (s.ok()) { - rocksdb::RocksDBJni::setHandle(env, jdb, db); - return; + return reinterpret_cast(db); + } else { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + return 0; } - rocksdb::RocksDBExceptionJni::ThrowNew(env, s); -} - -/* - * Class: org_rocksdb_RocksDB - * Method: openROnly - * Signature: (JLjava/lang/String;)V - */ -void Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2( - JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) { - auto opt = reinterpret_cast(jopt_handle); - rocksdb::DB* db = nullptr; - const char* db_path = env->GetStringUTFChars(jdb_path, 0); - rocksdb::Status s = rocksdb::DB::OpenForReadOnly(*opt, - 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 - * Method: openROnly - * Signature: (JLjava/lang/String;Ljava/util/List;I)Ljava/util/List; - */ -jobject - Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2Ljava_util_List_2I( - JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, - jobject jcfdesc_list, jint jcfdesc_count) { - auto opt = reinterpret_cast(jopt_handle); - rocksdb::DB* db = nullptr; - const char* db_path = env->GetStringUTFChars(jdb_path, 0); - - std::vector cfnames_to_free; - std::vector jcfnames_for_free; - - std::vector column_families; - std::vector 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( - 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(cfname), len), *cfOptions)); - } - - rocksdb::Status s = rocksdb::DB::OpenForReadOnly(*opt, - db_path, column_families, &handles, &db); - env->ReleaseStringUTFChars(jdb_path, db_path); - // free jbyte allocations - for (std::vector::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::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, "", "(J)V"); - jobject obj = env->NewObject(jLongClazz, midLong, - reinterpret_cast(handles[i])); - env->CallBooleanMethod(jcfhandle_list, - rocksdb::ListJni::getListAddMethodId(env), obj); - } - - return jcfhandle_list; - } - rocksdb::RocksDBExceptionJni::ThrowNew(env, s); - return nullptr; } /* * Class: org_rocksdb_RocksDB * Method: open - * Signature: (JLjava/lang/String;Ljava/util/List;I)Ljava/util/List; + * Signature: (JLjava/lang/String;)J */ -jobject Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2Ljava_util_List_2I( - JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, - jobject jcfdesc_list, jint jcfdesc_count) { - auto opt = reinterpret_cast(jopt_handle); - rocksdb::DB* db = nullptr; - const char* db_path = env->GetStringUTFChars(jdb_path, 0); +jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2( + JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path) { + return rocksdb_open_helper(env, jopt_handle, jdb_path, + (rocksdb::Status(*) + (const rocksdb::Options&, const std::string&, rocksdb::DB**) + )&rocksdb::DB::Open + ); +} - std::vector cfnames_to_free; - std::vector jcfnames_for_free; +/* + * Class: org_rocksdb_RocksDB + * Method: openROnly + * Signature: (JLjava/lang/String;)J + */ +jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2( + JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path) { + return rocksdb_open_helper(env, jopt_handle, jdb_path, []( + const rocksdb::Options& options, + const std::string& db_path, rocksdb::DB** db) { + return rocksdb::DB::OpenForReadOnly(options, db_path, db); + }); +} + +jlongArray rocksdb_open_helper(JNIEnv* env, jlong jopt_handle, + jstring jdb_path, jobjectArray jcolumn_names, jlongArray jcolumn_options, + std::function&, + std::vector*, + rocksdb::DB**)> open_fn + ) { + auto* opt = reinterpret_cast(jopt_handle); + const char* db_path = env->GetStringUTFChars(jdb_path, NULL); std::vector column_families; - std::vector 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( - 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); + jsize len_cols = env->GetArrayLength(jcolumn_names); + jlong* jco = env->GetLongArrayElements(jcolumn_options, NULL); + for(int i = 0; i < len_cols; i++) { + jobject jcn = env->GetObjectArrayElement(jcolumn_names, i); + jbyteArray jcn_ba = reinterpret_cast(jcn); + jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, NULL); + const int jcf_name_len = env->GetArrayLength(jcn_ba); - jbyte* cfname = env->GetByteArrayElements(cf_name_in_byte_array, 0); - const int len = env->GetArrayLength(cf_name_in_byte_array); + //TODO(AR) do I need to make a copy of jco[i] ? - // 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(cfname), len), *cfOptions)); + std::string cf_name (reinterpret_cast(jcf_name), jcf_name_len); + rocksdb::ColumnFamilyOptions* cf_options = + reinterpret_cast(jco[i]); + column_families.push_back( + rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options)); + + env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT); + env->DeleteLocalRef(jcn); } + env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT); - rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, column_families, + std::vector handles; + rocksdb::DB* db = nullptr; + rocksdb::Status s = open_fn(*opt, db_path, column_families, &handles, &db); - env->ReleaseStringUTFChars(jdb_path, db_path); - // free jbyte allocations - for (std::vector::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::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, "", "(J)V"); - jobject obj = env->NewObject(jLongClazz, midLong, - reinterpret_cast(handles[i])); - env->CallBooleanMethod(jcfhandle_list, - rocksdb::ListJni::getListAddMethodId(env), obj); + jsize resultsLen = 1 + len_cols; //db handle + column family handles + jlong results[resultsLen]; + results[0] = reinterpret_cast(db); + for(int i = 1; i <= len_cols; i++) { + results[i] = reinterpret_cast(handles[i - 1]); } - 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 + * Method: openROnly + * Signature: (JLjava/lang/String;[[B[J)[J + */ +jlongArray Java_org_rocksdb_RocksDB_openROnly__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, []( + const rocksdb::DBOptions& options, const std::string& db_path, + const std::vector& column_families, + std::vector* handles, rocksdb::DB** db) { + return rocksdb::DB::OpenForReadOnly(options, db_path, column_families, + handles, db); + }); +} + +/* + * Class: org_rocksdb_RocksDB + * Method: open + * 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&, + std::vector*, rocksdb::DB**) + )&rocksdb::DB::Open + ); } ////////////////////////////////////////////////////////////////////////////// diff --git a/java/rocksjni/slice.cc b/java/rocksjni/slice.cc index 5e05e46f7..e5eb383bd 100644 --- a/java/rocksjni/slice.cc +++ b/java/rocksjni/slice.cc @@ -22,12 +22,11 @@ /* * Class: org_rocksdb_AbstractSlice * Method: createNewSliceFromString - * Signature: (Ljava/lang/String;)V + * Signature: (Ljava/lang/String;)J */ -void Java_org_rocksdb_AbstractSlice_createNewSliceFromString( - JNIEnv* env, jobject jobj, jstring jstr) { - - const auto* str = env->GetStringUTFChars(jstr, 0); +jlong Java_org_rocksdb_AbstractSlice_createNewSliceFromString( + JNIEnv * env, jclass jcls, jstring jstr) { + const auto* str = env->GetStringUTFChars(jstr, NULL); const size_t len = strlen(str); char* buf = new char[len + 1]; memcpy(buf, str, len); @@ -35,7 +34,7 @@ void Java_org_rocksdb_AbstractSlice_createNewSliceFromString( env->ReleaseStringUTFChars(jstr, str); const auto* slice = new rocksdb::Slice(buf); - rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); + return reinterpret_cast(slice); } /* @@ -115,10 +114,10 @@ void Java_org_rocksdb_AbstractSlice_disposeInternal( /* * Class: org_rocksdb_Slice * Method: createNewSlice0 - * Signature: ([BI)V + * Signature: ([BI)J */ -void Java_org_rocksdb_Slice_createNewSlice0( - JNIEnv * env, jobject jobj, jbyteArray data, jint offset) { +jlong Java_org_rocksdb_Slice_createNewSlice0( + JNIEnv * env, jclass jcls, jbyteArray data, jint offset) { const jsize dataSize = env->GetArrayLength(data); const int len = dataSize - offset; @@ -126,32 +125,33 @@ void Java_org_rocksdb_Slice_createNewSlice0( env->GetByteArrayRegion(data, offset, len, ptrData); const auto* slice = new rocksdb::Slice((const char*)ptrData, len); - rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); + return reinterpret_cast(slice); } /* * Class: org_rocksdb_Slice * Method: createNewSlice1 - * Signature: ([B)V + * Signature: ([B)J */ -void Java_org_rocksdb_Slice_createNewSlice1( - JNIEnv * env, jobject jobj, jbyteArray data) { +jlong Java_org_rocksdb_Slice_createNewSlice1( + JNIEnv * env, jclass jcls, jbyteArray data) { const int len = env->GetArrayLength(data) + 1; jboolean 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); buf[len-1]='\0'; const auto* slice = new rocksdb::Slice(buf, len - 1); - rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT); - // NOTE: buf will be deleted in the org.rocksdb.Slice#dispose method + + return reinterpret_cast(slice); } /* @@ -187,27 +187,27 @@ void Java_org_rocksdb_Slice_disposeInternalBuf( /* * Class: org_rocksdb_DirectSlice * Method: createNewDirectSlice0 - * Signature: (Ljava/nio/ByteBuffer;I)V + * Signature: (Ljava/nio/ByteBuffer;I)J */ -void Java_org_rocksdb_DirectSlice_createNewDirectSlice0( - JNIEnv* env, jobject jobj, jobject data, jint length) { +jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0( + JNIEnv* env, jclass jcls, jobject data, jint length) { const auto* ptrData = reinterpret_cast(env->GetDirectBufferAddress(data)); const auto* slice = new rocksdb::Slice(ptrData, length); - rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); + return reinterpret_cast(slice); } /* * Class: org_rocksdb_DirectSlice * Method: createNewDirectSlice1 - * Signature: (Ljava/nio/ByteBuffer;)V + * Signature: (Ljava/nio/ByteBuffer;)J */ -void Java_org_rocksdb_DirectSlice_createNewDirectSlice1( - JNIEnv* env, jobject jobj, jobject data) { +jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1( + JNIEnv* env, jclass jcls, jobject data) { const auto* ptrData = reinterpret_cast(env->GetDirectBufferAddress(data)); const auto* slice = new rocksdb::Slice(ptrData); - rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); + return reinterpret_cast(slice); } /* diff --git a/java/rocksjni/ttl.cc b/java/rocksjni/ttl.cc index 219e6c4db..91d3dca9a 100644 --- a/java/rocksjni/ttl.cc +++ b/java/rocksjni/ttl.cc @@ -20,10 +20,10 @@ /* * Class: org_rocksdb_TtlDB * Method: open - * Signature: (JLjava/lang/String;IZ)V + * Signature: (JLjava/lang/String;IZ)J */ -void Java_org_rocksdb_TtlDB_open(JNIEnv* env, - jobject jttldb, jlong joptions_handle, jstring jdb_path, +jlong Java_org_rocksdb_TtlDB_open(JNIEnv* env, + jclass jcls, jlong joptions_handle, jstring jdb_path, jint jttl, jboolean jread_only) { auto* opt = reinterpret_cast(joptions_handle); 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 // the RocksDB portal here. if (s.ok()) { - rocksdb::RocksDBJni::setHandle(env, jttldb, db); - return; + return reinterpret_cast(db); + } else { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + return 0; } - rocksdb::RocksDBExceptionJni::ThrowNew(env, s); } /* * Class: org_rocksdb_TtlDB * Method: openCF - * Signature: (JLjava/lang/String;Ljava/util/List; - * ILjava/util/List;Z)Ljava/util/List; + * Signature: (JLjava/lang/String;[[B[J[IZ)[J */ -jobject +jlongArray Java_org_rocksdb_TtlDB_openCF( - JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, - jobject jcfdesc_list, jint jcfdesc_count, jobject jttl_list, - jboolean jread_only) { - auto* opt = reinterpret_cast(jopt_handle); - rocksdb::DBWithTTL* db = nullptr; - const char* db_path = env->GetStringUTFChars(jdb_path, 0); - - std::vector cfnames_to_free; - std::vector jcfnames_for_free; + JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path, + jobjectArray jcolumn_names, jlongArray jcolumn_options, + jintArray jttls, jboolean jread_only) { + auto* opt = reinterpret_cast(jopt_handle); + const char* db_path = env->GetStringUTFChars(jdb_path, NULL); std::vector column_families; + + jsize len_cols = env->GetArrayLength(jcolumn_names); + jlong* jco = env->GetLongArrayElements(jcolumn_options, NULL); + for(int i = 0; i < len_cols; i++) { + jobject jcn = env->GetObjectArrayElement(jcolumn_names, i); + jbyteArray jcn_ba = reinterpret_cast(jcn); + jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, NULL); + const int jcf_name_len = env->GetArrayLength(jcn_ba); + + //TODO(AR) do I need to make a copy of jco[i] ? + + std::string cf_name (reinterpret_cast(jcf_name), jcf_name_len); + rocksdb::ColumnFamilyOptions* cf_options = + reinterpret_cast(jco[i]); + column_families.push_back( + rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options)); + + env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT); + env->DeleteLocalRef(jcn); + } + env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT); + + std::vector handles; + rocksdb::DBWithTTL* db = nullptr; + std::vector ttl_values; - std::vector 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 byteArray = static_cast(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(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(cfname), len), *cfOptions)); - } - // get iterator for TTL values - iteratorObj = env->CallObjectMethod( - jttl_list, rocksdb::ListJni::getIteratorMethod(env)); - // iterate over TTL values - while (env->CallBooleanMethod( - iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { - // get TTL object - jobject jttl_object = env->CallObjectMethod(iteratorObj, - rocksdb::ListJni::getNextMethod(env)); - // get Integer value - jclass jIntClazz = env->FindClass("java/lang/Integer"); - jmethodID getVal = env->GetMethodID(jIntClazz, "intValue", "()I"); - ttl_values.push_back(env->CallIntMethod(jttl_object, getVal)); + jint* jttlv = env->GetIntArrayElements(jttls, NULL); + jsize len_ttls = env->GetArrayLength(jttls); + for(int i = 0; i < len_ttls; i++) { + ttl_values.push_back(jttlv[i]); } + env->ReleaseIntArrayElements(jttls, jttlv, JNI_ABORT); + rocksdb::Status s = rocksdb::DBWithTTL::Open(*opt, db_path, column_families, &handles, &db, ttl_values, jread_only); - env->ReleaseStringUTFChars(jdb_path, db_path); - // free jbyte allocations - for (std::vector::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::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, "", "(J)V"); - jobject obj = env->NewObject(jLongClazz, midLong, - reinterpret_cast(handles[i])); - env->CallBooleanMethod(jcfhandle_list, - rocksdb::ListJni::getListAddMethodId(env), obj); + jsize resultsLen = 1 + len_cols; //db handle + column family handles + jlong results[resultsLen]; + results[0] = reinterpret_cast(db); + for(int i = 1; i <= len_cols; i++) { + results[i] = reinterpret_cast(handles[i - 1]); } - 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; } /* diff --git a/java/rocksjni/write_batch.cc b/java/rocksjni/write_batch.cc index 83d2e6dfe..41690967c 100644 --- a/java/rocksjni/write_batch.cc +++ b/java/rocksjni/write_batch.cc @@ -27,14 +27,13 @@ /* * Class: org_rocksdb_WriteBatch * Method: newWriteBatch - * Signature: (I)V + * Signature: (I)J */ -void Java_org_rocksdb_WriteBatch_newWriteBatch( - JNIEnv* env, jobject jobj, jint jreserved_bytes) { +jlong Java_org_rocksdb_WriteBatch_newWriteBatch( + JNIEnv* env, jclass jcls, jint jreserved_bytes) { rocksdb::WriteBatch* wb = new rocksdb::WriteBatch( static_cast(jreserved_bytes)); - - rocksdb::WriteBatchJni::setHandle(env, jobj, wb); + return reinterpret_cast(wb); } /* @@ -218,13 +217,13 @@ void Java_org_rocksdb_WriteBatch_disposeInternal( /* * Class: org_rocksdb_WriteBatch_Handler * Method: createNewHandler0 - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0( +jlong Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0( JNIEnv* env, jobject jobj) { const rocksdb::WriteBatchHandlerJniCallback* h = new rocksdb::WriteBatchHandlerJniCallback(env, jobj); - rocksdb::WriteBatchHandlerJni::setHandle(env, jobj, h); + return reinterpret_cast(h); } /* diff --git a/java/rocksjni/write_batch_with_index.cc b/java/rocksjni/write_batch_with_index.cc index 51296427e..1123517d9 100644 --- a/java/rocksjni/write_batch_with_index.cc +++ b/java/rocksjni/write_batch_with_index.cc @@ -15,40 +15,40 @@ /* * Class: org_rocksdb_WriteBatchWithIndex * Method: newWriteBatchWithIndex - * Signature: ()V + * Signature: ()J */ -void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__( - JNIEnv* env, jobject jobj) { +jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__( + JNIEnv* env, jclass jcls) { rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex(); - rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); + return reinterpret_cast(wbwi); } /* * Class: org_rocksdb_WriteBatchWithIndex * Method: newWriteBatchWithIndex - * Signature: (Z)V + * Signature: (Z)J */ -void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z( - JNIEnv* env, jobject jobj, jboolean joverwrite_key) { +jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z( + JNIEnv* env, jclass jcls, jboolean joverwrite_key) { rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex(rocksdb::BytewiseComparator(), 0, static_cast(joverwrite_key)); - rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); + return reinterpret_cast(wbwi); } /* * Class: org_rocksdb_WriteBatchWithIndex * Method: newWriteBatchWithIndex - * Signature: (JIZ)V + * Signature: (JIZ)J */ -void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ( - JNIEnv* env, jobject jobj, jlong jfallback_index_comparator_handle, +jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ( + JNIEnv* env, jclass jcls, jlong jfallback_index_comparator_handle, jint jreserved_bytes, jboolean joverwrite_key) { rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex( reinterpret_cast(jfallback_index_comparator_handle), static_cast(jreserved_bytes), static_cast(joverwrite_key)); - rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); + return reinterpret_cast(wbwi); } /* diff --git a/java/src/main/java/org/rocksdb/AbstractCompactionFilter.java b/java/src/main/java/org/rocksdb/AbstractCompactionFilter.java index 1ecedf156..6853f1d4b 100644 --- a/java/src/main/java/org/rocksdb/AbstractCompactionFilter.java +++ b/java/src/main/java/org/rocksdb/AbstractCompactionFilter.java @@ -13,6 +13,10 @@ package org.rocksdb; public abstract class AbstractCompactionFilter> extends RocksObject { + protected AbstractCompactionFilter(final long nativeHandle) { + super(nativeHandle); + } + /** * Deletes underlying C++ comparator pointer. * @@ -20,10 +24,6 @@ public abstract class AbstractCompactionFilter> * RocksDB instances referencing the comparator are closed. * Otherwise an undefined behavior will occur. */ - @Override protected void disposeInternal() { - assert(isInitialized()); - disposeInternal(nativeHandle_); - } - - private native void disposeInternal(long handle); + @Override + protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/AbstractComparator.java b/java/src/main/java/org/rocksdb/AbstractComparator.java index 04a26bfba..a459a9366 100644 --- a/java/src/main/java/org/rocksdb/AbstractComparator.java +++ b/java/src/main/java/org/rocksdb/AbstractComparator.java @@ -14,8 +14,11 @@ package org.rocksdb; * @see org.rocksdb.Comparator * @see org.rocksdb.DirectComparator */ -public abstract class AbstractComparator> - extends RocksObject { +public abstract class AbstractComparator> extends NativeReference { + + protected AbstractComparator() { + super(true); + } /** * The name of the comparator. Used to check for comparator @@ -91,10 +94,12 @@ public abstract class AbstractComparator> * RocksDB instances referencing the comparator are closed. * Otherwise an undefined behavior will occur. */ - @Override protected void disposeInternal() { - assert(isInitialized()); - disposeInternal(nativeHandle_); + @Override + protected void disposeInternal() { + disposeInternal(getNativeHandle()); } - private native void disposeInternal(long handle); + protected abstract long getNativeHandle(); + + private native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/AbstractRocksIterator.java b/java/src/main/java/org/rocksdb/AbstractRocksIterator.java index b7419cba9..a1547b3b3 100644 --- a/java/src/main/java/org/rocksdb/AbstractRocksIterator.java +++ b/java/src/main/java/org/rocksdb/AbstractRocksIterator.java @@ -25,8 +25,7 @@ public abstract class AbstractRocksIterator

protected AbstractRocksIterator(final P parent, final long nativeHandle) { - super(); - nativeHandle_ = nativeHandle; + super(nativeHandle); // parent must point to a valid RocksDB instance. assert (parent != null); // RocksIterator must hold a reference to the related parent instance @@ -37,43 +36,43 @@ public abstract class AbstractRocksIterator

@Override public boolean isValid() { - assert (isInitialized()); + assert (isOwningHandle()); return isValid0(nativeHandle_); } @Override public void seekToFirst() { - assert (isInitialized()); + assert (isOwningHandle()); seekToFirst0(nativeHandle_); } @Override public void seekToLast() { - assert (isInitialized()); + assert (isOwningHandle()); seekToLast0(nativeHandle_); } @Override public void seek(byte[] target) { - assert (isInitialized()); + assert (isOwningHandle()); seek0(nativeHandle_, target, target.length); } @Override public void next() { - assert (isInitialized()); + assert (isOwningHandle()); next0(nativeHandle_); } @Override public void prev() { - assert (isInitialized()); + assert (isOwningHandle()); prev0(nativeHandle_); } @Override public void status() throws RocksDBException { - assert (isInitialized()); + assert (isOwningHandle()); status0(nativeHandle_); } @@ -87,15 +86,11 @@ public abstract class AbstractRocksIterator

*/ @Override protected void disposeInternal() { - synchronized (parent_) { - assert (isInitialized()); - if (parent_.isInitialized()) { + if (parent_.isOwningHandle()) { disposeInternal(nativeHandle_); } - } } - abstract void disposeInternal(long handle); abstract boolean isValid0(long handle); abstract void seekToFirst0(long handle); abstract void seekToLast0(long handle); diff --git a/java/src/main/java/org/rocksdb/AbstractSlice.java b/java/src/main/java/org/rocksdb/AbstractSlice.java index ea77f5384..b9e67d472 100644 --- a/java/src/main/java/org/rocksdb/AbstractSlice.java +++ b/java/src/main/java/org/rocksdb/AbstractSlice.java @@ -24,7 +24,15 @@ package org.rocksdb; * C++ BaseComparatorJniCallback subclass, which in turn destroys the * Java @see org.rocksdb.AbstractSlice subclass Objects. */ -abstract class AbstractSlice extends RocksObject { +abstract class AbstractSlice extends RocksMutableObject { + + protected AbstractSlice() { + super(); + } + + protected AbstractSlice(final long nativeHandle) { + super(nativeHandle); + } /** * Returns the data of the slice. @@ -34,7 +42,7 @@ abstract class AbstractSlice extends RocksObject { * @see org.rocksdb.AbstractSlice#data0(long) */ public T data() { - assert (isInitialized()); + assert (isOwningHandle()); return data0(nativeHandle_); } @@ -56,7 +64,7 @@ abstract class AbstractSlice extends RocksObject { * @return The length in bytes. */ public int size() { - assert (isInitialized()); + assert (isOwningHandle()); return size0(nativeHandle_); } @@ -67,7 +75,7 @@ abstract class AbstractSlice extends RocksObject { * @return true if there is no data, false otherwise. */ public boolean empty() { - assert (isInitialized()); + assert (isOwningHandle()); return empty0(nativeHandle_); } @@ -80,7 +88,7 @@ abstract class AbstractSlice extends RocksObject { * @return The string representation of the data. */ public String toString(final boolean hex) { - assert (isInitialized()); + assert (isOwningHandle()); return toString0(nativeHandle_, hex); } @@ -101,7 +109,7 @@ abstract class AbstractSlice extends RocksObject { */ public int compare(final AbstractSlice other) { assert (other != null); - assert (isInitialized()); + assert (isOwningHandle()); return compare0(nativeHandle_, other.nativeHandle_); } @@ -141,13 +149,20 @@ abstract class AbstractSlice extends RocksObject { */ public boolean startsWith(final AbstractSlice prefix) { if (prefix != null) { - assert (isInitialized()); + assert (isOwningHandle()); return startsWith0(nativeHandle_, prefix.nativeHandle_); } else { 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. * Note that this function should be called only after all @@ -155,17 +170,6 @@ abstract class AbstractSlice extends RocksObject { * Otherwise an undefined behavior will occur. */ @Override - protected void disposeInternal() { - 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); + protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/AbstractWriteBatch.java b/java/src/main/java/org/rocksdb/AbstractWriteBatch.java index 984e400ab..b40e9461e 100644 --- a/java/src/main/java/org/rocksdb/AbstractWriteBatch.java +++ b/java/src/main/java/org/rocksdb/AbstractWriteBatch.java @@ -7,71 +7,64 @@ package org.rocksdb; public abstract class AbstractWriteBatch extends RocksObject implements WriteBatchInterface { + protected AbstractWriteBatch(final long nativeHandle) { + super(nativeHandle); + } + @Override public int count() { - assert (isInitialized()); + assert (isOwningHandle()); return count0(); } @Override public void put(byte[] key, byte[] value) { - assert (isInitialized()); + assert (isOwningHandle()); put(key, key.length, value, value.length); } @Override public void put(ColumnFamilyHandle columnFamilyHandle, byte[] key, byte[] value) { - assert (isInitialized()); + assert (isOwningHandle()); put(key, key.length, value, value.length, columnFamilyHandle.nativeHandle_); } @Override public void merge(byte[] key, byte[] value) { - assert (isInitialized()); + assert (isOwningHandle()); merge(key, key.length, value, value.length); } @Override public void merge(ColumnFamilyHandle columnFamilyHandle, byte[] key, byte[] value) { - assert (isInitialized()); + assert (isOwningHandle()); merge(key, key.length, value, value.length, columnFamilyHandle.nativeHandle_); } @Override public void remove(byte[] key) { - assert (isInitialized()); + assert (isOwningHandle()); remove(key, key.length); } @Override public void remove(ColumnFamilyHandle columnFamilyHandle, byte[] key) { - assert (isInitialized()); + assert (isOwningHandle()); remove(key, key.length, columnFamilyHandle.nativeHandle_); } @Override public void putLogData(byte[] blob) { - assert (isInitialized()); + assert (isOwningHandle()); putLogData(blob, blob.length); } @Override public void clear() { - assert (isInitialized()); + assert (isOwningHandle()); clear0(); } - /** - * Delete the c++ side pointer. - */ - @Override - protected void disposeInternal() { - assert (isInitialized()); - disposeInternal(nativeHandle_); - } - - abstract void disposeInternal(long handle); - abstract int count0(); abstract void put(byte[] key, int keyLen, byte[] value, int valueLen); diff --git a/java/src/main/java/org/rocksdb/BackupEngine.java b/java/src/main/java/org/rocksdb/BackupEngine.java index 4791719aa..776307a74 100644 --- a/java/src/main/java/org/rocksdb/BackupEngine.java +++ b/java/src/main/java/org/rocksdb/BackupEngine.java @@ -19,8 +19,8 @@ import java.util.List; */ public class BackupEngine extends RocksObject implements AutoCloseable { - protected BackupEngine() { - super(); + protected BackupEngine(final long nativeHandle) { + super(nativeHandle); } /** @@ -33,9 +33,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { */ public static BackupEngine open(final Env env, final BackupableDBOptions options) throws RocksDBException { - final BackupEngine be = new BackupEngine(); - be.open(env.nativeHandle_, options.nativeHandle_); - return be; + return new BackupEngine(open(env.nativeHandle_, options.nativeHandle_)); } /** @@ -74,7 +72,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { public void createNewBackup( final RocksDB db, final boolean flushBeforeBackup) throws RocksDBException { - assert (isInitialized()); + assert (isOwningHandle()); 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 */ public List getBackupInfo() { - assert (isInitialized()); + assert (isOwningHandle()); return getBackupInfo(nativeHandle_); } @@ -97,7 +95,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { * @return array of backup ids as int ids. */ public int[] getCorruptedBackups() { - assert(isInitialized()); + assert(isOwningHandle()); return getCorruptedBackups(nativeHandle_); } @@ -110,7 +108,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { * native library. */ public void garbageCollect() throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); garbageCollect(nativeHandle_); } @@ -121,7 +119,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { */ public void purgeOldBackups( final int numBackupsToKeep) throws RocksDBException { - assert (isInitialized()); + assert (isOwningHandle()); purgeOldBackups(nativeHandle_, numBackupsToKeep); } @@ -131,7 +129,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { * @param backupId The id of the backup to delete */ public void deleteBackup(final int backupId) throws RocksDBException { - assert (isInitialized()); + assert (isOwningHandle()); deleteBackup(nativeHandle_, backupId); } @@ -158,7 +156,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { public void restoreDbFromBackup( final int backupId, final String dbDir, final String walDir, final RestoreOptions restoreOptions) throws RocksDBException { - assert (isInitialized()); + assert (isOwningHandle()); restoreDbFromBackup(nativeHandle_, backupId, dbDir, walDir, restoreOptions.nativeHandle_); } @@ -173,7 +171,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable { public void restoreDbFromLatestBackup( final String dbDir, final String walDir, final RestoreOptions restoreOptions) throws RocksDBException { - assert (isInitialized()); + assert (isOwningHandle()); restoreDbFromLatestBackup(nativeHandle_, dbDir, walDir, restoreOptions.nativeHandle_); } @@ -186,14 +184,8 @@ public class BackupEngine extends RocksObject implements AutoCloseable { dispose(); } - @Override - protected void disposeInternal() { - assert (isInitialized()); - disposeInternal(nativeHandle_); - } - - private native void open(final long env, final long backupableDbOptions) - throws RocksDBException; + private native static long open(final long env, + final long backupableDbOptions) throws RocksDBException; private native void createNewBackup(final long handle, final long dbHandle, 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) throws RocksDBException; - private native void disposeInternal(final long handle); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/BackupableDB.java b/java/src/main/java/org/rocksdb/BackupableDB.java index 6de20736f..9bc29af81 100644 --- a/java/src/main/java/org/rocksdb/BackupableDB.java +++ b/java/src/main/java/org/rocksdb/BackupableDB.java @@ -33,9 +33,8 @@ public class BackupableDB extends RocksDB { final Options opt, final BackupableDBOptions bopt, final String db_path) throws RocksDBException { - RocksDB db = RocksDB.open(opt, db_path); - BackupableDB bdb = new BackupableDB(); - bdb.open(db.nativeHandle_, bopt.nativeHandle_); + final RocksDB db = RocksDB.open(opt, db_path); + final BackupableDB bdb = new BackupableDB(open(db.nativeHandle_, bopt.nativeHandle_)); // Prevent the RocksDB object from attempting to delete // the underly C++ DB object. @@ -56,7 +55,7 @@ public class BackupableDB extends RocksDB { */ public void createNewBackup(final boolean flushBeforeBackup) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); createNewBackup(nativeHandle_, flushBeforeBackup); } @@ -70,7 +69,7 @@ public class BackupableDB extends RocksDB { */ public void purgeOldBackups(final int numBackupsToKeep) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); purgeOldBackups(nativeHandle_, numBackupsToKeep); } @@ -83,7 +82,7 @@ public class BackupableDB extends RocksDB { * native library. */ public void deleteBackup(final int backupId) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); deleteBackup0(nativeHandle_, backupId); } @@ -94,7 +93,7 @@ public class BackupableDB extends RocksDB { * @return List of {@link BackupInfo} instances. */ public List getBackupInfos() { - assert(isInitialized()); + assert(isOwningHandle()); return getBackupInfo(nativeHandle_); } @@ -106,7 +105,7 @@ public class BackupableDB extends RocksDB { * @return array of backup ids as int ids. */ public int[] getCorruptedBackups() { - assert(isInitialized()); + assert(isOwningHandle()); return getCorruptedBackups(nativeHandle_); } @@ -119,7 +118,7 @@ public class BackupableDB extends RocksDB { * native library. */ public void garbageCollect() throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); garbageCollect(nativeHandle_); } @@ -132,19 +131,19 @@ public class BackupableDB extends RocksDB { * of the c++ {@code rocksdb::BackupableDB} and should be transparent * to Java developers.

*/ - @Override public synchronized void close() { - if (isInitialized()) { + @Override public void close() { super.close(); - } } /** *

A protected construction that will be used in the static * factory method {@link #open(Options, BackupableDBOptions, String)}. *

+ * + * @param nativeHandle The native handle of the C++ BackupableDB object */ - protected BackupableDB() { - super(); + protected BackupableDB(final long nativeHandle) { + super(nativeHandle); } @Override protected void finalize() throws Throwable { @@ -152,7 +151,7 @@ public class BackupableDB extends RocksDB { 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) throws RocksDBException; protected native void purgeOldBackups(long handle, int numBackupsToKeep) diff --git a/java/src/main/java/org/rocksdb/BackupableDBOptions.java b/java/src/main/java/org/rocksdb/BackupableDBOptions.java index d32f2db8c..ea5e51a7a 100644 --- a/java/src/main/java/org/rocksdb/BackupableDBOptions.java +++ b/java/src/main/java/org/rocksdb/BackupableDBOptions.java @@ -6,7 +6,6 @@ package org.rocksdb; import java.io.File; -import java.nio.file.Path; /** *

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. */ public BackupableDBOptions(final String path) { - super(); - File backupPath = path == null ? null : new File(path); + super(newBackupableDBOptions(ensureWritableFile(path))); + } + + private static String ensureWritableFile(final String path) { + final File backupPath = path == null ? null : new File(path); if (backupPath == null || !backupPath.isDirectory() || !backupPath.canWrite()) { 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. */ public String backupDir() { - assert(isInitialized()); + assert(isOwningHandle()); return backupDir(nativeHandle_); } @@ -58,7 +61,7 @@ public class BackupableDBOptions extends RocksObject { * @return instance of current BackupableDBOptions. */ public BackupableDBOptions setShareTableFiles(final boolean shareTableFiles) { - assert(isInitialized()); + assert(isOwningHandle()); setShareTableFiles(nativeHandle_, shareTableFiles); return this; } @@ -70,7 +73,7 @@ public class BackupableDBOptions extends RocksObject { * backups. */ public boolean shareTableFiles() { - assert(isInitialized()); + assert(isOwningHandle()); return shareTableFiles(nativeHandle_); } @@ -87,7 +90,7 @@ public class BackupableDBOptions extends RocksObject { * @return instance of current BackupableDBOptions. */ public BackupableDBOptions setSync(final boolean sync) { - assert(isInitialized()); + assert(isOwningHandle()); setSync(nativeHandle_, sync); return this; } @@ -98,7 +101,7 @@ public class BackupableDBOptions extends RocksObject { * @return boolean value if synchronous backups are configured. */ public boolean sync() { - assert(isInitialized()); + assert(isOwningHandle()); return sync(nativeHandle_); } @@ -112,7 +115,7 @@ public class BackupableDBOptions extends RocksObject { * @return instance of current BackupableDBOptions. */ public BackupableDBOptions setDestroyOldData(final boolean destroyOldData) { - assert(isInitialized()); + assert(isOwningHandle()); setDestroyOldData(nativeHandle_, destroyOldData); return this; } @@ -123,7 +126,7 @@ public class BackupableDBOptions extends RocksObject { * @return boolean value indicating if old data will be destroyed. */ public boolean destroyOldData() { - assert(isInitialized()); + assert(isOwningHandle()); return destroyOldData(nativeHandle_); } @@ -139,7 +142,7 @@ public class BackupableDBOptions extends RocksObject { * @return instance of current BackupableDBOptions. */ public BackupableDBOptions setBackupLogFiles(final boolean backupLogFiles) { - assert(isInitialized()); + assert(isOwningHandle()); setBackupLogFiles(nativeHandle_, backupLogFiles); return this; } @@ -150,7 +153,7 @@ public class BackupableDBOptions extends RocksObject { * @return boolean value indicating if log files will be persisted. */ public boolean backupLogFiles() { - assert(isInitialized()); + assert(isOwningHandle()); return backupLogFiles(nativeHandle_); } @@ -165,7 +168,7 @@ public class BackupableDBOptions extends RocksObject { * @return instance of current BackupableDBOptions. */ public BackupableDBOptions setBackupRateLimit(long backupRateLimit) { - assert(isInitialized()); + assert(isOwningHandle()); backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit; setBackupRateLimit(nativeHandle_, backupRateLimit); return this; @@ -178,7 +181,7 @@ public class BackupableDBOptions extends RocksObject { * @return numerical value describing the backup transfer limit in bytes per second. */ public long backupRateLimit() { - assert(isInitialized()); + assert(isOwningHandle()); return backupRateLimit(nativeHandle_); } @@ -193,7 +196,7 @@ public class BackupableDBOptions extends RocksObject { * @return instance of current BackupableDBOptions. */ public BackupableDBOptions setRestoreRateLimit(long restoreRateLimit) { - assert(isInitialized()); + assert(isOwningHandle()); restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit; setRestoreRateLimit(nativeHandle_, restoreRateLimit); return this; @@ -206,7 +209,7 @@ public class BackupableDBOptions extends RocksObject { * @return numerical value describing the restore transfer limit in bytes per second. */ public long restoreRateLimit() { - assert(isInitialized()); + assert(isOwningHandle()); return restoreRateLimit(nativeHandle_); } @@ -227,7 +230,7 @@ public class BackupableDBOptions extends RocksObject { */ public BackupableDBOptions setShareFilesWithChecksum( final boolean shareFilesWithChecksum) { - assert(isInitialized()); + assert(isOwningHandle()); setShareFilesWithChecksum(nativeHandle_, shareFilesWithChecksum); return this; } @@ -239,19 +242,11 @@ public class BackupableDBOptions extends RocksObject { * is active. */ public boolean shareFilesWithChecksum() { - assert(isInitialized()); + assert(isOwningHandle()); return shareFilesWithChecksum(nativeHandle_); } - /** - * 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 static long newBackupableDBOptions(final String path); private native String backupDir(long handle); private native void setShareTableFiles(long handle, boolean flag); private native boolean shareTableFiles(long handle); @@ -267,5 +262,5 @@ public class BackupableDBOptions extends RocksObject { private native long restoreRateLimit(long handle); private native void setShareFilesWithChecksum(long handle, boolean flag); private native boolean shareFilesWithChecksum(long handle); - private native void disposeInternal(long handle); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/BloomFilter.java b/java/src/main/java/org/rocksdb/BloomFilter.java index 2c9585f71..a8c2f7e7f 100644 --- a/java/src/main/java/org/rocksdb/BloomFilter.java +++ b/java/src/main/java/org/rocksdb/BloomFilter.java @@ -22,8 +22,6 @@ public class BloomFilter extends Filter { private static final int DEFAULT_BITS_PER_KEY = 10; private static final boolean DEFAULT_MODE = true; - private final int bitsPerKey_; - private final boolean useBlockBasedMode_; /** * BloomFilter constructor @@ -73,17 +71,9 @@ public class BloomFilter extends Filter { * @param useBlockBasedMode use block based mode or full filter mode */ public BloomFilter(final int bitsPerKey, final boolean useBlockBasedMode) { - super(); - bitsPerKey_ = bitsPerKey; - useBlockBasedMode_ = useBlockBasedMode; - createNewFilter(); + super(createNewBloomFilter(bitsPerKey, useBlockBasedMode)); } - @Override - protected final void createNewFilter() { - createNewBloomFilter(bitsPerKey_, useBlockBasedMode_); - } - - private native void createNewBloomFilter(int bitsKeyKey, - boolean useBlockBasedMode); + private native static long createNewBloomFilter(final int bitsKeyKey, + final boolean useBlockBasedMode); } diff --git a/java/src/main/java/org/rocksdb/Checkpoint.java b/java/src/main/java/org/rocksdb/Checkpoint.java index 9faa355e1..d86722778 100644 --- a/java/src/main/java/org/rocksdb/Checkpoint.java +++ b/java/src/main/java/org/rocksdb/Checkpoint.java @@ -27,7 +27,7 @@ public class Checkpoint extends RocksObject { if (db == null) { throw new IllegalArgumentException( "RocksDB instance shall not be null."); - } else if (!db.isInitialized()) { + } else if (!db.isOwningHandle()) { throw new IllegalStateException( "RocksDB instance must be initialized."); } @@ -51,21 +51,15 @@ public class Checkpoint extends RocksObject { createCheckpoint(nativeHandle_, checkpointPath); } - @Override - protected void disposeInternal() { - disposeInternal(nativeHandle_); + private Checkpoint(final RocksDB db) { + super(newCheckpoint(db.nativeHandle_)); + this.db_ = db; } - private Checkpoint(RocksDB db) { - super(); - nativeHandle_ = newCheckpoint(db.nativeHandle_); - db_ = db; - } - - private RocksDB db_; + private final RocksDB db_; 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) throws RocksDBException; diff --git a/java/src/main/java/org/rocksdb/ColumnFamilyHandle.java b/java/src/main/java/org/rocksdb/ColumnFamilyHandle.java index d414ee587..b9f6bd97e 100644 --- a/java/src/main/java/org/rocksdb/ColumnFamilyHandle.java +++ b/java/src/main/java/org/rocksdb/ColumnFamilyHandle.java @@ -12,14 +12,13 @@ package org.rocksdb; public class ColumnFamilyHandle extends RocksObject { ColumnFamilyHandle(final RocksDB rocksDB, final long nativeHandle) { - super(); - nativeHandle_ = nativeHandle; + super(nativeHandle); // rocksDB must point to a valid RocksDB instance; assert(rocksDB != null); // ColumnFamilyHandle must hold a reference to the related RocksDB instance // to guarantee that while a GC cycle starts ColumnFamilyHandle 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 * before freeing the native handle.

*/ - @Override protected void disposeInternal() { - synchronized (rocksDB_) { - assert (isInitialized()); - if (rocksDB_.isInitialized()) { - disposeInternal(nativeHandle_); - } + @Override + protected void disposeInternal() { + if(rocksDB_.isOwningHandle()) { + disposeInternal(nativeHandle_); } } - private native void disposeInternal(long handle); + @Override protected final native void disposeInternal(final long handle); private final RocksDB rocksDB_; } diff --git a/java/src/main/java/org/rocksdb/ColumnFamilyOptions.java b/java/src/main/java/org/rocksdb/ColumnFamilyOptions.java index 612efbe7f..91457defa 100644 --- a/java/src/main/java/org/rocksdb/ColumnFamilyOptions.java +++ b/java/src/main/java/org/rocksdb/ColumnFamilyOptions.java @@ -29,8 +29,7 @@ public class ColumnFamilyOptions extends RocksObject * an {@code rocksdb::DBOptions} in the c++ side. */ public ColumnFamilyOptions() { - super(); - newColumnFamilyOptions(); + super(newColumnFamilyOptions()); } /** @@ -114,7 +113,7 @@ public class ColumnFamilyOptions extends RocksObject @Override public ColumnFamilyOptions setComparator(final BuiltinComparator builtinComparator) { - assert(isInitialized()); + assert(isOwningHandle()); setComparatorHandle(nativeHandle_, builtinComparator.ordinal()); return this; } @@ -122,15 +121,15 @@ public class ColumnFamilyOptions extends RocksObject @Override public ColumnFamilyOptions setComparator( final AbstractComparator> comparator) { - assert (isInitialized()); - setComparatorHandle(nativeHandle_, comparator.nativeHandle_); + assert (isOwningHandle()); + setComparatorHandle(nativeHandle_, comparator.getNativeHandle()); comparator_ = comparator; return this; } @Override public ColumnFamilyOptions setMergeOperatorName(final String name) { - assert (isInitialized()); + assert (isOwningHandle()); if (name == null) { throw new IllegalArgumentException( "Merge operator name must not be null."); @@ -154,28 +153,28 @@ public class ColumnFamilyOptions extends RocksObject @Override public ColumnFamilyOptions setWriteBufferSize(final long writeBufferSize) { - assert(isInitialized()); + assert(isOwningHandle()); setWriteBufferSize(nativeHandle_, writeBufferSize); return this; } @Override public long writeBufferSize() { - assert(isInitialized()); + assert(isOwningHandle()); return writeBufferSize(nativeHandle_); } @Override public ColumnFamilyOptions setMaxWriteBufferNumber( final int maxWriteBufferNumber) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber); return this; } @Override public int maxWriteBufferNumber() { - assert(isInitialized()); + assert(isOwningHandle()); return maxWriteBufferNumber(nativeHandle_); } @@ -193,14 +192,14 @@ public class ColumnFamilyOptions extends RocksObject @Override public ColumnFamilyOptions useFixedLengthPrefixExtractor(final int n) { - assert(isInitialized()); + assert(isOwningHandle()); useFixedLengthPrefixExtractor(nativeHandle_, n); return this; } @Override public ColumnFamilyOptions useCappedPrefixExtractor(final int n) { - assert(isInitialized()); + assert(isOwningHandle()); useCappedPrefixExtractor(nativeHandle_, n); return this; } @@ -485,7 +484,7 @@ public class ColumnFamilyOptions extends RocksObject public ColumnFamilyOptions setMaxTableFilesSizeFIFO( final long maxTableFilesSize) { assert(maxTableFilesSize > 0); // unsigned native type - assert(isInitialized()); + assert(isOwningHandle()); setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize); return this; } @@ -542,7 +541,7 @@ public class ColumnFamilyOptions extends RocksObject @Override public String memTableFactoryName() { - assert(isInitialized()); + assert(isOwningHandle()); return memTableFactoryName(nativeHandle_); } @@ -556,7 +555,7 @@ public class ColumnFamilyOptions extends RocksObject @Override public String tableFactoryName() { - assert(isInitialized()); + assert(isOwningHandle()); return tableFactoryName(nativeHandle_); } @@ -655,15 +654,6 @@ public class ColumnFamilyOptions extends RocksObject return optimizeFiltersForHits(nativeHandle_); } - /** - * Release the memory allocated for the current instance - * in the c++ side. - */ - @Override protected void disposeInternal() { - assert(isInitialized()); - disposeInternal(nativeHandle_); - } - /** *

Private constructor to be used by * {@link #getColumnFamilyOptionsFromProps(java.util.Properties)}

@@ -671,15 +661,14 @@ public class ColumnFamilyOptions extends RocksObject * @param handle native handle to ColumnFamilyOptions instance. */ private ColumnFamilyOptions(final long handle) { - super(); - nativeHandle_ = handle; + super(handle); } private static native long getColumnFamilyOptionsFromProps( String optString); - private native void newColumnFamilyOptions(); - private native void disposeInternal(long handle); + private static native long newColumnFamilyOptions(); + @Override protected final native void disposeInternal(final long handle); private native void optimizeForPointLookup(long handle, long blockCacheSizeMb); diff --git a/java/src/main/java/org/rocksdb/Comparator.java b/java/src/main/java/org/rocksdb/Comparator.java index 41f7fbc93..009f2e51f 100644 --- a/java/src/main/java/org/rocksdb/Comparator.java +++ b/java/src/main/java/org/rocksdb/Comparator.java @@ -15,10 +15,18 @@ package org.rocksdb; * using @see org.rocksdb.DirectComparator */ public abstract class Comparator extends AbstractComparator { + + private final long nativeHandle_; + public Comparator(final ComparatorOptions copt) { super(); - createNewComparator0(copt.nativeHandle_); + this.nativeHandle_ = createNewComparator0(copt.nativeHandle_); } - private native void createNewComparator0(final long comparatorOptionsHandle); + @Override + protected final long getNativeHandle() { + return nativeHandle_; + } + + private native long createNewComparator0(final long comparatorOptionsHandle); } diff --git a/java/src/main/java/org/rocksdb/ComparatorOptions.java b/java/src/main/java/org/rocksdb/ComparatorOptions.java index f0ba520a3..3a05befa4 100644 --- a/java/src/main/java/org/rocksdb/ComparatorOptions.java +++ b/java/src/main/java/org/rocksdb/ComparatorOptions.java @@ -10,8 +10,7 @@ package org.rocksdb; */ public class ComparatorOptions extends RocksObject { public ComparatorOptions() { - super(); - newComparatorOptions(); + super(newComparatorOptions()); } /** @@ -24,7 +23,7 @@ public class ComparatorOptions extends RocksObject { * @return true if adaptive mutex is used. */ public boolean useAdaptiveMutex() { - assert(isInitialized()); + assert(isOwningHandle()); return useAdaptiveMutex(nativeHandle_); } @@ -39,19 +38,14 @@ public class ComparatorOptions extends RocksObject { * @return the reference to the current comparator options. */ public ComparatorOptions setUseAdaptiveMutex(final boolean useAdaptiveMutex) { - assert (isInitialized()); + assert (isOwningHandle()); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); return this; } - @Override protected void disposeInternal() { - assert(isInitialized()); - disposeInternal(nativeHandle_); - } - - private native void newComparatorOptions(); + private native static long newComparatorOptions(); private native boolean useAdaptiveMutex(final long handle); private native void setUseAdaptiveMutex(final long handle, final boolean useAdaptiveMutex); - private native void disposeInternal(long handle); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/DBOptions.java b/java/src/main/java/org/rocksdb/DBOptions.java index d2e1bf94c..a9ed2527a 100644 --- a/java/src/main/java/org/rocksdb/DBOptions.java +++ b/java/src/main/java/org/rocksdb/DBOptions.java @@ -26,9 +26,8 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { * an {@code rocksdb::DBOptions} in the c++ side. */ public DBOptions() { - super(); + super(newDBOptions()); numShardBits_ = DEFAULT_NUM_SHARD_BITS; - newDBOptions(); } /** @@ -75,70 +74,70 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { @Override public DBOptions setIncreaseParallelism( final int totalThreads) { - assert (isInitialized()); + assert(isOwningHandle()); setIncreaseParallelism(nativeHandle_, totalThreads); return this; } @Override public DBOptions setCreateIfMissing(final boolean flag) { - assert(isInitialized()); + assert(isOwningHandle()); setCreateIfMissing(nativeHandle_, flag); return this; } @Override public boolean createIfMissing() { - assert(isInitialized()); + assert(isOwningHandle()); return createIfMissing(nativeHandle_); } @Override public DBOptions setCreateMissingColumnFamilies( final boolean flag) { - assert(isInitialized()); + assert(isOwningHandle()); setCreateMissingColumnFamilies(nativeHandle_, flag); return this; } @Override public boolean createMissingColumnFamilies() { - assert(isInitialized()); + assert(isOwningHandle()); return createMissingColumnFamilies(nativeHandle_); } @Override public DBOptions setErrorIfExists( final boolean errorIfExists) { - assert(isInitialized()); + assert(isOwningHandle()); setErrorIfExists(nativeHandle_, errorIfExists); return this; } @Override public boolean errorIfExists() { - assert(isInitialized()); + assert(isOwningHandle()); return errorIfExists(nativeHandle_); } @Override public DBOptions setParanoidChecks( final boolean paranoidChecks) { - assert(isInitialized()); + assert(isOwningHandle()); setParanoidChecks(nativeHandle_, paranoidChecks); return this; } @Override public boolean paranoidChecks() { - assert(isInitialized()); + assert(isOwningHandle()); return paranoidChecks(nativeHandle_); } @Override public DBOptions setRateLimiterConfig( final RateLimiterConfig config) { - assert(isInitialized()); + assert(isOwningHandle()); rateLimiterConfig_ = config; setRateLimiter(nativeHandle_, config.newRateLimiterHandle()); return this; @@ -146,7 +145,7 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { @Override public DBOptions setLogger(final Logger logger) { - assert(isInitialized()); + assert(isOwningHandle()); setLogger(nativeHandle_, logger.nativeHandle_); return this; } @@ -154,14 +153,14 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { @Override public DBOptions setInfoLogLevel( final InfoLogLevel infoLogLevel) { - assert(isInitialized()); + assert(isOwningHandle()); setInfoLogLevel(nativeHandle_, infoLogLevel.getValue()); return this; } @Override public InfoLogLevel infoLogLevel() { - assert(isInitialized()); + assert(isOwningHandle()); return InfoLogLevel.getInfoLogLevel( infoLogLevel(nativeHandle_)); } @@ -169,41 +168,41 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { @Override public DBOptions setMaxOpenFiles( final int maxOpenFiles) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxOpenFiles(nativeHandle_, maxOpenFiles); return this; } @Override public int maxOpenFiles() { - assert(isInitialized()); + assert(isOwningHandle()); return maxOpenFiles(nativeHandle_); } @Override public DBOptions setMaxTotalWalSize( final long maxTotalWalSize) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxTotalWalSize(nativeHandle_, maxTotalWalSize); return this; } @Override public long maxTotalWalSize() { - assert(isInitialized()); + assert(isOwningHandle()); return maxTotalWalSize(nativeHandle_); } @Override public DBOptions createStatistics() { - assert(isInitialized()); + assert(isOwningHandle()); createStatistics(nativeHandle_); return this; } @Override public Statistics statisticsPtr() { - assert(isInitialized()); + assert(isOwningHandle()); long statsPtr = statisticsPtr(nativeHandle_); if(statsPtr == 0) { @@ -217,287 +216,287 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { @Override public DBOptions setDisableDataSync( final boolean disableDataSync) { - assert(isInitialized()); + assert(isOwningHandle()); setDisableDataSync(nativeHandle_, disableDataSync); return this; } @Override public boolean disableDataSync() { - assert(isInitialized()); + assert(isOwningHandle()); return disableDataSync(nativeHandle_); } @Override public DBOptions setUseFsync( final boolean useFsync) { - assert(isInitialized()); + assert(isOwningHandle()); setUseFsync(nativeHandle_, useFsync); return this; } @Override public boolean useFsync() { - assert(isInitialized()); + assert(isOwningHandle()); return useFsync(nativeHandle_); } @Override public DBOptions setDbLogDir( final String dbLogDir) { - assert(isInitialized()); + assert(isOwningHandle()); setDbLogDir(nativeHandle_, dbLogDir); return this; } @Override public String dbLogDir() { - assert(isInitialized()); + assert(isOwningHandle()); return dbLogDir(nativeHandle_); } @Override public DBOptions setWalDir( final String walDir) { - assert(isInitialized()); + assert(isOwningHandle()); setWalDir(nativeHandle_, walDir); return this; } @Override public String walDir() { - assert(isInitialized()); + assert(isOwningHandle()); return walDir(nativeHandle_); } @Override public DBOptions setDeleteObsoleteFilesPeriodMicros( final long micros) { - assert(isInitialized()); + assert(isOwningHandle()); setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros); return this; } @Override public long deleteObsoleteFilesPeriodMicros() { - assert(isInitialized()); + assert(isOwningHandle()); return deleteObsoleteFilesPeriodMicros(nativeHandle_); } @Override public DBOptions setMaxBackgroundCompactions( final int maxBackgroundCompactions) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions); return this; } @Override public int maxBackgroundCompactions() { - assert(isInitialized()); + assert(isOwningHandle()); return maxBackgroundCompactions(nativeHandle_); } @Override public DBOptions setMaxBackgroundFlushes( final int maxBackgroundFlushes) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes); return this; } @Override public int maxBackgroundFlushes() { - assert(isInitialized()); + assert(isOwningHandle()); return maxBackgroundFlushes(nativeHandle_); } @Override public DBOptions setMaxLogFileSize( final long maxLogFileSize) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxLogFileSize(nativeHandle_, maxLogFileSize); return this; } @Override public long maxLogFileSize() { - assert(isInitialized()); + assert(isOwningHandle()); return maxLogFileSize(nativeHandle_); } @Override public DBOptions setLogFileTimeToRoll( final long logFileTimeToRoll) { - assert(isInitialized()); + assert(isOwningHandle()); setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll); return this; } @Override public long logFileTimeToRoll() { - assert(isInitialized()); + assert(isOwningHandle()); return logFileTimeToRoll(nativeHandle_); } @Override public DBOptions setKeepLogFileNum( final long keepLogFileNum) { - assert(isInitialized()); + assert(isOwningHandle()); setKeepLogFileNum(nativeHandle_, keepLogFileNum); return this; } @Override public long keepLogFileNum() { - assert(isInitialized()); + assert(isOwningHandle()); return keepLogFileNum(nativeHandle_); } @Override public DBOptions setMaxManifestFileSize( final long maxManifestFileSize) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxManifestFileSize(nativeHandle_, maxManifestFileSize); return this; } @Override public long maxManifestFileSize() { - assert(isInitialized()); + assert(isOwningHandle()); return maxManifestFileSize(nativeHandle_); } @Override public DBOptions setTableCacheNumshardbits( final int tableCacheNumshardbits) { - assert(isInitialized()); + assert(isOwningHandle()); setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits); return this; } @Override public int tableCacheNumshardbits() { - assert(isInitialized()); + assert(isOwningHandle()); return tableCacheNumshardbits(nativeHandle_); } @Override public DBOptions setWalTtlSeconds( final long walTtlSeconds) { - assert(isInitialized()); + assert(isOwningHandle()); setWalTtlSeconds(nativeHandle_, walTtlSeconds); return this; } @Override public long walTtlSeconds() { - assert(isInitialized()); + assert(isOwningHandle()); return walTtlSeconds(nativeHandle_); } @Override public DBOptions setWalSizeLimitMB( final long sizeLimitMB) { - assert(isInitialized()); + assert(isOwningHandle()); setWalSizeLimitMB(nativeHandle_, sizeLimitMB); return this; } @Override public long walSizeLimitMB() { - assert(isInitialized()); + assert(isOwningHandle()); return walSizeLimitMB(nativeHandle_); } @Override public DBOptions setManifestPreallocationSize( final long size) { - assert(isInitialized()); + assert(isOwningHandle()); setManifestPreallocationSize(nativeHandle_, size); return this; } @Override public long manifestPreallocationSize() { - assert(isInitialized()); + assert(isOwningHandle()); return manifestPreallocationSize(nativeHandle_); } @Override public DBOptions setAllowOsBuffer( final boolean allowOsBuffer) { - assert(isInitialized()); + assert(isOwningHandle()); setAllowOsBuffer(nativeHandle_, allowOsBuffer); return this; } @Override public boolean allowOsBuffer() { - assert(isInitialized()); + assert(isOwningHandle()); return allowOsBuffer(nativeHandle_); } @Override public DBOptions setAllowMmapReads( final boolean allowMmapReads) { - assert(isInitialized()); + assert(isOwningHandle()); setAllowMmapReads(nativeHandle_, allowMmapReads); return this; } @Override public boolean allowMmapReads() { - assert(isInitialized()); + assert(isOwningHandle()); return allowMmapReads(nativeHandle_); } @Override public DBOptions setAllowMmapWrites( final boolean allowMmapWrites) { - assert(isInitialized()); + assert(isOwningHandle()); setAllowMmapWrites(nativeHandle_, allowMmapWrites); return this; } @Override public boolean allowMmapWrites() { - assert(isInitialized()); + assert(isOwningHandle()); return allowMmapWrites(nativeHandle_); } @Override public DBOptions setIsFdCloseOnExec( final boolean isFdCloseOnExec) { - assert(isInitialized()); + assert(isOwningHandle()); setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec); return this; } @Override public boolean isFdCloseOnExec() { - assert(isInitialized()); + assert(isOwningHandle()); return isFdCloseOnExec(nativeHandle_); } @Override public DBOptions setStatsDumpPeriodSec( final int statsDumpPeriodSec) { - assert(isInitialized()); + assert(isOwningHandle()); setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec); return this; } @Override public int statsDumpPeriodSec() { - assert(isInitialized()); + assert(isOwningHandle()); return statsDumpPeriodSec(nativeHandle_); } @Override public DBOptions setAdviseRandomOnOpen( final boolean adviseRandomOnOpen) { - assert(isInitialized()); + assert(isOwningHandle()); setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen); return this; } @@ -510,21 +509,21 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { @Override public DBOptions setUseAdaptiveMutex( final boolean useAdaptiveMutex) { - assert(isInitialized()); + assert(isOwningHandle()); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); return this; } @Override public boolean useAdaptiveMutex() { - assert(isInitialized()); + assert(isOwningHandle()); return useAdaptiveMutex(nativeHandle_); } @Override public DBOptions setBytesPerSync( final long bytesPerSync) { - assert(isInitialized()); + assert(isOwningHandle()); setBytesPerSync(nativeHandle_, bytesPerSync); return this; } @@ -534,33 +533,23 @@ public class DBOptions extends RocksObject implements DBOptionsInterface { 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; /** *

Private constructor to be used by * {@link #getDBOptionsFromProps(java.util.Properties)}

* - * @param handle native handle to DBOptions instance. + * @param nativeHandle native handle to DBOptions instance. */ - private DBOptions(final long handle) { - super(); - nativeHandle_ = handle; + private DBOptions(final long nativeHandle) { + super(nativeHandle); } private static native long getDBOptionsFromProps( String optString); - private native void newDBOptions(); - private native void disposeInternal(long handle); + private native static long newDBOptions(); + @Override protected final native void disposeInternal(final long handle); private native void setIncreaseParallelism(long handle, int totalThreads); private native void setCreateIfMissing(long handle, boolean flag); diff --git a/java/src/main/java/org/rocksdb/DirectComparator.java b/java/src/main/java/org/rocksdb/DirectComparator.java index 68ad11f6c..ba3fce798 100644 --- a/java/src/main/java/org/rocksdb/DirectComparator.java +++ b/java/src/main/java/org/rocksdb/DirectComparator.java @@ -15,10 +15,18 @@ package org.rocksdb; * using @see org.rocksdb.Comparator */ public abstract class DirectComparator extends AbstractComparator { + + private final long nativeHandle_; + public DirectComparator(final ComparatorOptions copt) { super(); - createNewDirectComparator0(copt.nativeHandle_); + this.nativeHandle_ = createNewDirectComparator0(copt.nativeHandle_); } - private native void createNewDirectComparator0(final long comparatorOptionsHandle); + @Override + protected final long getNativeHandle() { + return nativeHandle_; + } + + private native long createNewDirectComparator0(final long comparatorOptionsHandle); } diff --git a/java/src/main/java/org/rocksdb/DirectSlice.java b/java/src/main/java/org/rocksdb/DirectSlice.java index 7a59a3d82..9f8269105 100644 --- a/java/src/main/java/org/rocksdb/DirectSlice.java +++ b/java/src/main/java/org/rocksdb/DirectSlice.java @@ -16,7 +16,6 @@ import java.nio.ByteBuffer; * values consider using @see org.rocksdb.Slice */ public class DirectSlice extends AbstractSlice { - //TODO(AR) only needed by WriteBatchWithIndexTest until JDK8 public final static DirectSlice NONE = new DirectSlice(); /** @@ -24,9 +23,7 @@ public class DirectSlice extends AbstractSlice { * without an underlying C++ object set * at creation time. * - * Note: You should be aware that - * {@see org.rocksdb.RocksObject#disOwnNativeHandle()} is intentionally - * called from the default DirectSlice constructor, and that it is marked as + * Note: You should be aware that it is intentionally marked as * package-private. This is so that developers cannot construct their own default * DirectSlice objects (at present). As developers cannot construct their own * DirectSlice objects through this, they are not creating underlying C++ @@ -34,7 +31,6 @@ public class DirectSlice extends AbstractSlice { */ DirectSlice() { super(); - disOwnNativeHandle(); } /** @@ -45,8 +41,7 @@ public class DirectSlice extends AbstractSlice { * @param str The string */ public DirectSlice(final String str) { - super(); - createNewSliceFromString(str); + super(createNewSliceFromString(str)); } /** @@ -58,9 +53,7 @@ public class DirectSlice extends AbstractSlice { * @param length The length of the data to use for the slice */ public DirectSlice(final ByteBuffer data, final int length) { - super(); - assert(data.isDirect()); - createNewDirectSlice0(data, length); + super(createNewDirectSlice0(ensureDirect(data), length)); } /** @@ -71,9 +64,13 @@ public class DirectSlice extends AbstractSlice { * @param data The bugger containing the 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()); - createNewDirectSlice1(data); + return data; } /** @@ -85,7 +82,7 @@ public class DirectSlice extends AbstractSlice { * @return the requested byte */ public byte get(int offset) { - assert (isInitialized()); + assert (isOwningHandle()); return get0(nativeHandle_, offset); } @@ -93,7 +90,7 @@ public class DirectSlice extends AbstractSlice { * Clears the backing slice */ public void clear() { - assert (isInitialized()); + assert (isOwningHandle()); clear0(nativeHandle_); } @@ -105,12 +102,13 @@ public class DirectSlice extends AbstractSlice { * @param n The number of bytes to drop */ public void removePrefix(final int n) { - assert (isInitialized()); + assert (isOwningHandle()); removePrefix0(nativeHandle_, n); } - private native void createNewDirectSlice0(ByteBuffer data, int length); - private native void createNewDirectSlice1(ByteBuffer data); + private native static long createNewDirectSlice0(final ByteBuffer data, + final int length); + private native static long createNewDirectSlice1(final ByteBuffer data); @Override protected final native ByteBuffer data0(long handle); private native byte get0(long handle, int offset); private native void clear0(long handle); diff --git a/java/src/main/java/org/rocksdb/Env.java b/java/src/main/java/org/rocksdb/Env.java index 74088fd86..7d30ea5df 100644 --- a/java/src/main/java/org/rocksdb/Env.java +++ b/java/src/main/java/org/rocksdb/Env.java @@ -70,8 +70,8 @@ public abstract class Env extends RocksObject { } - protected Env() { - super(); + protected Env(final long nativeHandle) { + super(nativeHandle); } static { diff --git a/java/src/main/java/org/rocksdb/Filter.java b/java/src/main/java/org/rocksdb/Filter.java index 1cc0ccd4c..01853d969 100644 --- a/java/src/main/java/org/rocksdb/Filter.java +++ b/java/src/main/java/org/rocksdb/Filter.java @@ -13,7 +13,10 @@ package org.rocksdb; * DB::Get() call. */ public abstract class Filter extends RocksObject { - protected abstract void createNewFilter(); + + protected Filter(final long nativeHandle) { + super(nativeHandle); + } /** * Deletes underlying C++ filter pointer. @@ -22,10 +25,11 @@ public abstract class Filter extends RocksObject { * RocksDB instances referencing the filter are closed. * Otherwise an undefined behavior will occur. */ - @Override protected void disposeInternal() { - assert(isInitialized()); + @Override + protected void disposeInternal() { disposeInternal(nativeHandle_); } - private native void disposeInternal(long handle); + @Override + protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/FlushOptions.java b/java/src/main/java/org/rocksdb/FlushOptions.java index 9ddf95f1c..4931b5d85 100644 --- a/java/src/main/java/org/rocksdb/FlushOptions.java +++ b/java/src/main/java/org/rocksdb/FlushOptions.java @@ -10,8 +10,7 @@ public class FlushOptions extends RocksObject { * Construct a new instance of FlushOptions. */ public FlushOptions(){ - super(); - newFlushOptions(); + super(newFlushOptions()); } /** @@ -23,7 +22,7 @@ public class FlushOptions extends RocksObject { * @return instance of current FlushOptions. */ public FlushOptions setWaitForFlush(final boolean waitForFlush) { - assert(isInitialized()); + assert(isOwningHandle()); setWaitForFlush(nativeHandle_, waitForFlush); return this; } @@ -35,16 +34,12 @@ public class FlushOptions extends RocksObject { * waits for termination of the flush process. */ public boolean waitForFlush() { - assert(isInitialized()); + assert(isOwningHandle()); return waitForFlush(nativeHandle_); } - @Override protected void disposeInternal() { - disposeInternal(nativeHandle_); - } - - private native void newFlushOptions(); - private native void disposeInternal(long handle); + private native static long newFlushOptions(); + @Override protected final native void disposeInternal(final long handle); private native void setWaitForFlush(long handle, boolean wait); private native boolean waitForFlush(long handle); diff --git a/java/src/main/java/org/rocksdb/Logger.java b/java/src/main/java/org/rocksdb/Logger.java index 26359ff2e..868a43260 100644 --- a/java/src/main/java/org/rocksdb/Logger.java +++ b/java/src/main/java/org/rocksdb/Logger.java @@ -35,7 +35,9 @@ package org.rocksdb; * {@link org.rocksdb.InfoLogLevel#FATAL_LEVEL}. *

*/ -public abstract class Logger extends RocksObject { +public abstract class Logger extends NativeReference { + + final long nativeHandle_; /** *

AbstractLogger constructor.

@@ -47,7 +49,8 @@ public abstract class Logger extends RocksObject { * @param options {@link org.rocksdb.Options} instance. */ 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. */ 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 protected void disposeInternal() { - assert(isInitialized()); disposeInternal(nativeHandle_); } - protected native void createNewLoggerOptions( + protected native long createNewLoggerOptions( long options); - protected native void createNewLoggerDbOptions( + protected native long createNewLoggerDbOptions( long dbOptions); protected native void setInfoLogLevel(long handle, byte infoLogLevel); protected native byte infoLogLevel(long handle); - private native void disposeInternal(long handle); + private native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/NativeReference.java b/java/src/main/java/org/rocksdb/NativeReference.java new file mode 100644 index 000000000..0ca44be42 --- /dev/null +++ b/java/src/main/java/org/rocksdb/NativeReference.java @@ -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. + *

+ * 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. + *

+ * 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()}. + *

+ * @see #dispose() + */ + protected final void disOwnNativeHandle() { + owningHandle_.set(false); + } + + /** + * Release the c++ object manually pointed by the native handle. + *

+ * 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. + *

+ *

+ * Note that once an instance of {@code RocksObject} has been disposed, + * calling its function will lead undefined behavior. + *

+ */ + 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(); + } +} diff --git a/java/src/main/java/org/rocksdb/Options.java b/java/src/main/java/org/rocksdb/Options.java index dfce746bf..2c6f2e81f 100644 --- a/java/src/main/java/org/rocksdb/Options.java +++ b/java/src/main/java/org/rocksdb/Options.java @@ -27,8 +27,7 @@ public class Options extends RocksObject * an {@code rocksdb::Options} in the c++ side. */ public Options() { - super(); - newOptions(); + super(newOptions()); env_ = Env.getDefault(); } @@ -42,28 +41,27 @@ public class Options extends RocksObject */ public Options(final DBOptions dbOptions, final ColumnFamilyOptions columnFamilyOptions) { - super(); - newOptions(dbOptions.nativeHandle_, columnFamilyOptions.nativeHandle_); + super(newOptions(dbOptions.nativeHandle_, columnFamilyOptions.nativeHandle_)); env_ = Env.getDefault(); } @Override public Options setIncreaseParallelism(final int totalThreads) { - assert(isInitialized()); + assert(isOwningHandle()); setIncreaseParallelism(nativeHandle_, totalThreads); return this; } @Override public Options setCreateIfMissing(final boolean flag) { - assert(isInitialized()); + assert(isOwningHandle()); setCreateIfMissing(nativeHandle_, flag); return this; } @Override public Options setCreateMissingColumnFamilies(final boolean flag) { - assert(isInitialized()); + assert(isOwningHandle()); setCreateMissingColumnFamilies(nativeHandle_, flag); return this; } @@ -77,7 +75,7 @@ public class Options extends RocksObject * @return the instance of the current Options. */ public Options setEnv(final Env env) { - assert(isInitialized()); + assert(isOwningHandle()); setEnv(nativeHandle_, env.nativeHandle_); env_ = env; return this; @@ -111,13 +109,13 @@ public class Options extends RocksObject @Override public boolean createIfMissing() { - assert(isInitialized()); + assert(isOwningHandle()); return createIfMissing(nativeHandle_); } @Override public boolean createMissingColumnFamilies() { - assert(isInitialized()); + assert(isOwningHandle()); return createMissingColumnFamilies(nativeHandle_); } @@ -161,7 +159,7 @@ public class Options extends RocksObject @Override public Options setComparator(final BuiltinComparator builtinComparator) { - assert(isInitialized()); + assert(isOwningHandle()); setComparatorHandle(nativeHandle_, builtinComparator.ordinal()); return this; } @@ -169,15 +167,15 @@ public class Options extends RocksObject @Override public Options setComparator( final AbstractComparator> comparator) { - assert (isInitialized()); - setComparatorHandle(nativeHandle_, comparator.nativeHandle_); + assert(isOwningHandle()); + setComparatorHandle(nativeHandle_, comparator.getNativeHandle()); comparator_ = comparator; return this; } @Override public Options setMergeOperatorName(final String name) { - assert (isInitialized()); + assert(isOwningHandle()); if (name == null) { throw new IllegalArgumentException( "Merge operator name must not be null."); @@ -194,164 +192,164 @@ public class Options extends RocksObject @Override public Options setWriteBufferSize(final long writeBufferSize) { - assert(isInitialized()); + assert(isOwningHandle()); setWriteBufferSize(nativeHandle_, writeBufferSize); return this; } @Override public long writeBufferSize() { - assert(isInitialized()); + assert(isOwningHandle()); return writeBufferSize(nativeHandle_); } @Override public Options setMaxWriteBufferNumber(final int maxWriteBufferNumber) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber); return this; } @Override public int maxWriteBufferNumber() { - assert(isInitialized()); + assert(isOwningHandle()); return maxWriteBufferNumber(nativeHandle_); } @Override public boolean errorIfExists() { - assert(isInitialized()); + assert(isOwningHandle()); return errorIfExists(nativeHandle_); } @Override public Options setErrorIfExists(final boolean errorIfExists) { - assert(isInitialized()); + assert(isOwningHandle()); setErrorIfExists(nativeHandle_, errorIfExists); return this; } @Override public boolean paranoidChecks() { - assert(isInitialized()); + assert(isOwningHandle()); return paranoidChecks(nativeHandle_); } @Override public Options setParanoidChecks(final boolean paranoidChecks) { - assert(isInitialized()); + assert(isOwningHandle()); setParanoidChecks(nativeHandle_, paranoidChecks); return this; } @Override public int maxOpenFiles() { - assert(isInitialized()); + assert(isOwningHandle()); return maxOpenFiles(nativeHandle_); } @Override public Options setMaxTotalWalSize(final long maxTotalWalSize) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxTotalWalSize(nativeHandle_, maxTotalWalSize); return this; } @Override public long maxTotalWalSize() { - assert(isInitialized()); + assert(isOwningHandle()); return maxTotalWalSize(nativeHandle_); } @Override public Options setMaxOpenFiles(final int maxOpenFiles) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxOpenFiles(nativeHandle_, maxOpenFiles); return this; } @Override public boolean disableDataSync() { - assert(isInitialized()); + assert(isOwningHandle()); return disableDataSync(nativeHandle_); } @Override public Options setDisableDataSync(final boolean disableDataSync) { - assert(isInitialized()); + assert(isOwningHandle()); setDisableDataSync(nativeHandle_, disableDataSync); return this; } @Override public boolean useFsync() { - assert(isInitialized()); + assert(isOwningHandle()); return useFsync(nativeHandle_); } @Override public Options setUseFsync(final boolean useFsync) { - assert(isInitialized()); + assert(isOwningHandle()); setUseFsync(nativeHandle_, useFsync); return this; } @Override public String dbLogDir() { - assert(isInitialized()); + assert(isOwningHandle()); return dbLogDir(nativeHandle_); } @Override public Options setDbLogDir(final String dbLogDir) { - assert(isInitialized()); + assert(isOwningHandle()); setDbLogDir(nativeHandle_, dbLogDir); return this; } @Override public String walDir() { - assert(isInitialized()); + assert(isOwningHandle()); return walDir(nativeHandle_); } @Override public Options setWalDir(final String walDir) { - assert(isInitialized()); + assert(isOwningHandle()); setWalDir(nativeHandle_, walDir); return this; } @Override public long deleteObsoleteFilesPeriodMicros() { - assert(isInitialized()); + assert(isOwningHandle()); return deleteObsoleteFilesPeriodMicros(nativeHandle_); } @Override public Options setDeleteObsoleteFilesPeriodMicros( final long micros) { - assert(isInitialized()); + assert(isOwningHandle()); setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros); return this; } @Override public int maxBackgroundCompactions() { - assert(isInitialized()); + assert(isOwningHandle()); return maxBackgroundCompactions(nativeHandle_); } @Override public Options createStatistics() { - assert(isInitialized()); + assert(isOwningHandle()); createStatistics(nativeHandle_); return this; } @Override public Statistics statisticsPtr() { - assert(isInitialized()); + assert(isOwningHandle()); long statsPtr = statisticsPtr(nativeHandle_); if(statsPtr == 0) { @@ -365,74 +363,74 @@ public class Options extends RocksObject @Override public Options setMaxBackgroundCompactions( final int maxBackgroundCompactions) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions); return this; } @Override public int maxBackgroundFlushes() { - assert(isInitialized()); + assert(isOwningHandle()); return maxBackgroundFlushes(nativeHandle_); } @Override public Options setMaxBackgroundFlushes( final int maxBackgroundFlushes) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes); return this; } @Override public long maxLogFileSize() { - assert(isInitialized()); + assert(isOwningHandle()); return maxLogFileSize(nativeHandle_); } @Override public Options setMaxLogFileSize(final long maxLogFileSize) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxLogFileSize(nativeHandle_, maxLogFileSize); return this; } @Override public long logFileTimeToRoll() { - assert(isInitialized()); + assert(isOwningHandle()); return logFileTimeToRoll(nativeHandle_); } @Override public Options setLogFileTimeToRoll(final long logFileTimeToRoll) { - assert(isInitialized()); + assert(isOwningHandle()); setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll); return this; } @Override public long keepLogFileNum() { - assert(isInitialized()); + assert(isOwningHandle()); return keepLogFileNum(nativeHandle_); } @Override public Options setKeepLogFileNum(final long keepLogFileNum) { - assert(isInitialized()); + assert(isOwningHandle()); setKeepLogFileNum(nativeHandle_, keepLogFileNum); return this; } @Override public long maxManifestFileSize() { - assert(isInitialized()); + assert(isOwningHandle()); return maxManifestFileSize(nativeHandle_); } @Override public Options setMaxManifestFileSize( final long maxManifestFileSize) { - assert(isInitialized()); + assert(isOwningHandle()); setMaxManifestFileSize(nativeHandle_, maxManifestFileSize); return this; } @@ -441,7 +439,7 @@ public class Options extends RocksObject public Options setMaxTableFilesSizeFIFO( final long maxTableFilesSize) { assert(maxTableFilesSize > 0); // unsigned native type - assert(isInitialized()); + assert(isOwningHandle()); setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize); return this; } @@ -453,118 +451,118 @@ public class Options extends RocksObject @Override public int tableCacheNumshardbits() { - assert(isInitialized()); + assert(isOwningHandle()); return tableCacheNumshardbits(nativeHandle_); } @Override public Options setTableCacheNumshardbits( final int tableCacheNumshardbits) { - assert(isInitialized()); + assert(isOwningHandle()); setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits); return this; } @Override public long walTtlSeconds() { - assert(isInitialized()); + assert(isOwningHandle()); return walTtlSeconds(nativeHandle_); } @Override public Options setWalTtlSeconds(final long walTtlSeconds) { - assert(isInitialized()); + assert(isOwningHandle()); setWalTtlSeconds(nativeHandle_, walTtlSeconds); return this; } @Override public long walSizeLimitMB() { - assert(isInitialized()); + assert(isOwningHandle()); return walSizeLimitMB(nativeHandle_); } @Override public Options setWalSizeLimitMB(final long sizeLimitMB) { - assert(isInitialized()); + assert(isOwningHandle()); setWalSizeLimitMB(nativeHandle_, sizeLimitMB); return this; } @Override public long manifestPreallocationSize() { - assert(isInitialized()); + assert(isOwningHandle()); return manifestPreallocationSize(nativeHandle_); } @Override public Options setManifestPreallocationSize(final long size) { - assert(isInitialized()); + assert(isOwningHandle()); setManifestPreallocationSize(nativeHandle_, size); return this; } @Override public boolean allowOsBuffer() { - assert(isInitialized()); + assert(isOwningHandle()); return allowOsBuffer(nativeHandle_); } @Override public Options setAllowOsBuffer(final boolean allowOsBuffer) { - assert(isInitialized()); + assert(isOwningHandle()); setAllowOsBuffer(nativeHandle_, allowOsBuffer); return this; } @Override public boolean allowMmapReads() { - assert(isInitialized()); + assert(isOwningHandle()); return allowMmapReads(nativeHandle_); } @Override public Options setAllowMmapReads(final boolean allowMmapReads) { - assert(isInitialized()); + assert(isOwningHandle()); setAllowMmapReads(nativeHandle_, allowMmapReads); return this; } @Override public boolean allowMmapWrites() { - assert(isInitialized()); + assert(isOwningHandle()); return allowMmapWrites(nativeHandle_); } @Override public Options setAllowMmapWrites(final boolean allowMmapWrites) { - assert(isInitialized()); + assert(isOwningHandle()); setAllowMmapWrites(nativeHandle_, allowMmapWrites); return this; } @Override public boolean isFdCloseOnExec() { - assert(isInitialized()); + assert(isOwningHandle()); return isFdCloseOnExec(nativeHandle_); } @Override public Options setIsFdCloseOnExec(final boolean isFdCloseOnExec) { - assert(isInitialized()); + assert(isOwningHandle()); setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec); return this; } @Override public int statsDumpPeriodSec() { - assert(isInitialized()); + assert(isOwningHandle()); return statsDumpPeriodSec(nativeHandle_); } @Override public Options setStatsDumpPeriodSec(final int statsDumpPeriodSec) { - assert(isInitialized()); + assert(isOwningHandle()); setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec); return this; } @@ -576,20 +574,20 @@ public class Options extends RocksObject @Override public Options setAdviseRandomOnOpen(final boolean adviseRandomOnOpen) { - assert(isInitialized()); + assert(isOwningHandle()); setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen); return this; } @Override public boolean useAdaptiveMutex() { - assert(isInitialized()); + assert(isOwningHandle()); return useAdaptiveMutex(nativeHandle_); } @Override public Options setUseAdaptiveMutex(final boolean useAdaptiveMutex) { - assert(isInitialized()); + assert(isOwningHandle()); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); return this; } @@ -601,7 +599,7 @@ public class Options extends RocksObject @Override public Options setBytesPerSync(final long bytesPerSync) { - assert(isInitialized()); + assert(isOwningHandle()); setBytesPerSync(nativeHandle_, bytesPerSync); return this; } @@ -622,28 +620,28 @@ public class Options extends RocksObject @Override public Options setLogger(final Logger logger) { - assert(isInitialized()); + assert(isOwningHandle()); setLogger(nativeHandle_, logger.nativeHandle_); return this; } @Override public Options setInfoLogLevel(final InfoLogLevel infoLogLevel) { - assert(isInitialized()); + assert(isOwningHandle()); setInfoLogLevel(nativeHandle_, infoLogLevel.getValue()); return this; } @Override public InfoLogLevel infoLogLevel() { - assert(isInitialized()); + assert(isOwningHandle()); return InfoLogLevel.getInfoLogLevel( infoLogLevel(nativeHandle_)); } @Override public String memTableFactoryName() { - assert(isInitialized()); + assert(isOwningHandle()); return memTableFactoryName(nativeHandle_); } @@ -656,20 +654,20 @@ public class Options extends RocksObject @Override public String tableFactoryName() { - assert(isInitialized()); + assert(isOwningHandle()); return tableFactoryName(nativeHandle_); } @Override public Options useFixedLengthPrefixExtractor(final int n) { - assert(isInitialized()); + assert(isOwningHandle()); useFixedLengthPrefixExtractor(nativeHandle_, n); return this; } @Override public Options useCappedPrefixExtractor(final int n) { - assert(isInitialized()); + assert(isOwningHandle()); useCappedPrefixExtractor(nativeHandle_, n); return this; } @@ -1085,19 +1083,10 @@ public class Options extends RocksObject return optimizeFiltersForHits(nativeHandle_); } - /** - * Release the memory allocated for the current instance - * in the c++ side. - */ - @Override protected void disposeInternal() { - assert(isInitialized()); - disposeInternal(nativeHandle_); - } - - private native void newOptions(); - private native void newOptions(long dbOptHandle, + private native static long newOptions(); + private native static long newOptions(long dbOptHandle, 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 prepareForBulkLoad(long handle); diff --git a/java/src/main/java/org/rocksdb/ReadOptions.java b/java/src/main/java/org/rocksdb/ReadOptions.java index 3baf8e808..37d9d2fe4 100644 --- a/java/src/main/java/org/rocksdb/ReadOptions.java +++ b/java/src/main/java/org/rocksdb/ReadOptions.java @@ -13,10 +13,9 @@ package org.rocksdb; */ public class ReadOptions extends RocksObject { public ReadOptions() { - super(); - newReadOptions(); + super(newReadOptions()); } - private native void newReadOptions(); + private native static long newReadOptions(); /** * 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. */ public boolean verifyChecksums() { - assert(isInitialized()); + assert(isOwningHandle()); return verifyChecksums(nativeHandle_); } private native boolean verifyChecksums(long handle); @@ -42,7 +41,7 @@ public class ReadOptions extends RocksObject { */ public ReadOptions setVerifyChecksums( final boolean verifyChecksums) { - assert(isInitialized()); + assert(isOwningHandle()); setVerifyChecksums(nativeHandle_, verifyChecksums); return this; } @@ -59,7 +58,7 @@ public class ReadOptions extends RocksObject { * @return true if the fill-cache behavior is on. */ public boolean fillCache() { - assert(isInitialized()); + assert(isOwningHandle()); return fillCache(nativeHandle_); } private native boolean fillCache(long handle); @@ -74,7 +73,7 @@ public class ReadOptions extends RocksObject { * @return the reference to the current ReadOptions. */ public ReadOptions setFillCache(final boolean fillCache) { - assert(isInitialized()); + assert(isOwningHandle()); setFillCache(nativeHandle_, fillCache); return this; } @@ -92,7 +91,7 @@ public class ReadOptions extends RocksObject { * @return the reference to the current ReadOptions. */ public ReadOptions setSnapshot(final Snapshot snapshot) { - assert(isInitialized()); + assert(isOwningHandle()); if (snapshot != null) { setSnapshot(nativeHandle_, snapshot.nativeHandle_); } else { @@ -109,7 +108,7 @@ public class ReadOptions extends RocksObject { * is assigned null. */ public Snapshot snapshot() { - assert(isInitialized()); + assert(isOwningHandle()); long snapshotHandle = snapshot(nativeHandle_); if (snapshotHandle != 0) { return new Snapshot(snapshotHandle); @@ -130,7 +129,7 @@ public class ReadOptions extends RocksObject { * @return true if tailing iterator is enabled. */ public boolean tailing() { - assert(isInitialized()); + assert(isOwningHandle()); return tailing(nativeHandle_); } private native boolean tailing(long handle); @@ -147,17 +146,13 @@ public class ReadOptions extends RocksObject { * @return the reference to the current ReadOptions. */ public ReadOptions setTailing(final boolean tailing) { - assert(isInitialized()); + assert(isOwningHandle()); setTailing(nativeHandle_, tailing); return this; } private native void setTailing( long handle, boolean tailing); - - @Override protected void disposeInternal() { - disposeInternal(nativeHandle_); - } - private native void disposeInternal(long handle); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/RemoveEmptyValueCompactionFilter.java b/java/src/main/java/org/rocksdb/RemoveEmptyValueCompactionFilter.java index 2f54cdf45..5bc5dbe72 100644 --- a/java/src/main/java/org/rocksdb/RemoveEmptyValueCompactionFilter.java +++ b/java/src/main/java/org/rocksdb/RemoveEmptyValueCompactionFilter.java @@ -10,9 +10,8 @@ package org.rocksdb; */ public class RemoveEmptyValueCompactionFilter extends AbstractCompactionFilter { public RemoveEmptyValueCompactionFilter() { - super(); - createNewRemoveEmptyValueCompactionFilter0(); + super(createNewRemoveEmptyValueCompactionFilter0()); } - private native void createNewRemoveEmptyValueCompactionFilter0(); + private native static long createNewRemoveEmptyValueCompactionFilter0(); } diff --git a/java/src/main/java/org/rocksdb/RestoreBackupableDB.java b/java/src/main/java/org/rocksdb/RestoreBackupableDB.java index 90592e845..86610cc31 100644 --- a/java/src/main/java/org/rocksdb/RestoreBackupableDB.java +++ b/java/src/main/java/org/rocksdb/RestoreBackupableDB.java @@ -23,8 +23,7 @@ public class RestoreBackupableDB extends RocksObject { * @param options {@link org.rocksdb.BackupableDBOptions} instance */ public RestoreBackupableDB(final BackupableDBOptions options) { - super(); - nativeHandle_ = newRestoreBackupableDB(options.nativeHandle_); + super(newRestoreBackupableDB(options.nativeHandle_)); } /** @@ -52,7 +51,7 @@ public class RestoreBackupableDB extends RocksObject { public void restoreDBFromBackup(final long backupId, final String dbDir, final String walDir, final RestoreOptions restoreOptions) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); restoreDBFromBackup0(nativeHandle_, backupId, dbDir, walDir, restoreOptions.nativeHandle_); } @@ -70,7 +69,7 @@ public class RestoreBackupableDB extends RocksObject { public void restoreDBFromLatestBackup(final String dbDir, final String walDir, final RestoreOptions restoreOptions) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); restoreDBFromLatestBackup0(nativeHandle_, dbDir, walDir, restoreOptions.nativeHandle_); } @@ -85,7 +84,7 @@ public class RestoreBackupableDB extends RocksObject { */ public void purgeOldBackups(final int numBackupsToKeep) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); purgeOldBackups0(nativeHandle_, numBackupsToKeep); } @@ -99,7 +98,7 @@ public class RestoreBackupableDB extends RocksObject { */ public void deleteBackup(final int backupId) throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); deleteBackup0(nativeHandle_, backupId); } @@ -110,7 +109,7 @@ public class RestoreBackupableDB extends RocksObject { * @return List of {@link BackupInfo} instances. */ public List getBackupInfos() { - assert(isInitialized()); + assert(isOwningHandle()); return getBackupInfo(nativeHandle_); } @@ -122,7 +121,7 @@ public class RestoreBackupableDB extends RocksObject { * @return array of backup ids as int ids. */ public int[] getCorruptedBackups() { - assert(isInitialized()); + assert(isOwningHandle()); return getCorruptedBackups(nativeHandle_); } @@ -135,19 +134,11 @@ public class RestoreBackupableDB extends RocksObject { * native library. */ public void garbageCollect() throws RocksDBException { - assert(isInitialized()); + assert(isOwningHandle()); garbageCollect(nativeHandle_); } - /** - *

Release the memory allocated for the current instance - * in the c++ side.

- */ - @Override public synchronized void disposeInternal() { - dispose(nativeHandle_); - } - - private native long newRestoreBackupableDB(long options); + private native static long newRestoreBackupableDB(final long options); private native void restoreDBFromBackup0(long nativeHandle, long backupId, String dbDir, String walDir, long restoreOptions) throws RocksDBException; @@ -162,5 +153,5 @@ public class RestoreBackupableDB extends RocksObject { private native int[] getCorruptedBackups(long handle); private native void garbageCollect(long handle) throws RocksDBException; - private native void dispose(long nativeHandle); + @Override protected final native void disposeInternal(final long nativeHandle); } diff --git a/java/src/main/java/org/rocksdb/RestoreOptions.java b/java/src/main/java/org/rocksdb/RestoreOptions.java index 8cfe56640..9eecbc8e1 100644 --- a/java/src/main/java/org/rocksdb/RestoreOptions.java +++ b/java/src/main/java/org/rocksdb/RestoreOptions.java @@ -23,19 +23,9 @@ public class RestoreOptions extends RocksObject { * Default: false */ public RestoreOptions(final boolean keepLogFiles) { - super(); - nativeHandle_ = newRestoreOptions(keepLogFiles); + super(newRestoreOptions(keepLogFiles)); } - /** - * Release the memory allocated for the current instance - * 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); + private native static long newRestoreOptions(boolean keepLogFiles); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/RocksDB.java b/java/src/main/java/org/rocksdb/RocksDB.java index 786335745..87b7de026 100644 --- a/java/src/main/java/org/rocksdb/RocksDB.java +++ b/java/src/main/java/org/rocksdb/RocksDB.java @@ -179,9 +179,7 @@ public class RocksDB extends RocksObject { // when non-default Options is used, keeping an Options reference // in RocksDB can prevent Java to GC during the life-time of // the currently-created RocksDB. - RocksDB db = new RocksDB(); - db.open(options.nativeHandle_, path); - + final RocksDB db = new RocksDB(open(options.nativeHandle_, path)); db.storeOptionsInstance(options); return db; } @@ -225,13 +223,23 @@ public class RocksDB extends RocksObject { final List columnFamilyDescriptors, final List columnFamilyHandles) throws RocksDBException { - RocksDB db = new RocksDB(); - List cfReferences = db.open(options.nativeHandle_, path, - columnFamilyDescriptors, columnFamilyDescriptors.size()); + + final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][]; + final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()]; 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); + + for (int i = 1; i < handles.length; i++) { + columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i])); + } + return db; } @@ -276,7 +284,7 @@ public class RocksDB extends RocksObject { throws RocksDBException { // This allows to use the rocksjni default Options instead of // the c++ one. - DBOptions options = new DBOptions(); + final DBOptions options = new DBOptions(); return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles); } @@ -303,9 +311,7 @@ public class RocksDB extends RocksObject { // when non-default Options is used, keeping an Options reference // in RocksDB can prevent Java to GC during the life-time of // the currently-created RocksDB. - RocksDB db = new RocksDB(); - db.openROnly(options.nativeHandle_, path); - + final RocksDB db = new RocksDB(openROnly(options.nativeHandle_, path)); db.storeOptionsInstance(options); return db; } @@ -339,14 +345,23 @@ public class RocksDB extends RocksObject { // when non-default Options is used, keeping an Options reference // in RocksDB can prevent Java to GC during the life-time of // the currently-created RocksDB. - RocksDB db = new RocksDB(); - List cfReferences = db.openROnly(options.nativeHandle_, path, - columnFamilyDescriptors, columnFamilyDescriptors.size()); - for (int i=0; i open(long optionsHandle, String path, - List columnFamilyDescriptors, - int columnFamilyDescriptorsLength) - throws RocksDBException; + protected native static long open(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[] 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 listColumnFamilies( long optionsHandle, String path) throws RocksDBException; - protected native void openROnly( - long optionsHandle, String path) throws RocksDBException; - protected native List openROnly( - long optionsHandle, String path, - List columnFamilyDescriptors, - int columnFamilyDescriptorsLength) throws RocksDBException; protected native void put( long handle, byte[] key, int keyLen, byte[] value, int valueLen) throws RocksDBException; @@ -1793,7 +1828,7 @@ public class RocksDB extends RocksObject { protected native long getSnapshot(long nativeHandle); protected native void releaseSnapshot( 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 createColumnFamily(long handle, ColumnFamilyDescriptor columnFamilyDescriptor) throws RocksDBException; diff --git a/java/src/main/java/org/rocksdb/RocksEnv.java b/java/src/main/java/org/rocksdb/RocksEnv.java index 4c34a9f4b..72dc22c42 100644 --- a/java/src/main/java/org/rocksdb/RocksEnv.java +++ b/java/src/main/java/org/rocksdb/RocksEnv.java @@ -24,8 +24,7 @@ public class RocksEnv extends Env { * {@code dispose()} of the created RocksEnv will be no-op.

*/ RocksEnv(final long handle) { - super(); - nativeHandle_ = handle; + super(handle); disOwnNativeHandle(); } @@ -38,6 +37,7 @@ public class RocksEnv extends Env { * RocksEnv with RocksJava. The default env allocation is managed * by C++.

*/ - @Override protected void disposeInternal() { + @Override + protected final void disposeInternal(final long handle) { } } diff --git a/java/src/main/java/org/rocksdb/RocksIterator.java b/java/src/main/java/org/rocksdb/RocksIterator.java index d93a96197..42e2460cf 100644 --- a/java/src/main/java/org/rocksdb/RocksIterator.java +++ b/java/src/main/java/org/rocksdb/RocksIterator.java @@ -33,7 +33,7 @@ public class RocksIterator extends AbstractRocksIterator { * @return key for the current entry. */ public byte[] key() { - assert(isInitialized()); + assert(isOwningHandle()); return key0(nativeHandle_); } @@ -46,11 +46,11 @@ public class RocksIterator extends AbstractRocksIterator { * @return value for the current entry. */ public byte[] value() { - assert(isInitialized()); + assert(isOwningHandle()); 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 void seekToFirst0(long handle); @Override final native void seekToLast0(long handle); diff --git a/java/src/main/java/org/rocksdb/RocksMemEnv.java b/java/src/main/java/org/rocksdb/RocksMemEnv.java index 4517577be..d7854eae1 100644 --- a/java/src/main/java/org/rocksdb/RocksMemEnv.java +++ b/java/src/main/java/org/rocksdb/RocksMemEnv.java @@ -19,15 +19,9 @@ public class RocksMemEnv extends Env { *

{@code *base_env} must remain live while the result is in use.

*/ public RocksMemEnv() { - super(); - nativeHandle_ = createMemEnv(); - } - - @Override - protected void disposeInternal() { - disposeInternal(nativeHandle_); + super(createMemEnv()); } private static native long createMemEnv(); - private native void disposeInternal(long handle); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/RocksMutableObject.java b/java/src/main/java/org/rocksdb/RocksMutableObject.java new file mode 100644 index 000000000..f4ca3565d --- /dev/null +++ b/java/src/main/java/org/rocksdb/RocksMutableObject.java @@ -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); +} diff --git a/java/src/main/java/org/rocksdb/RocksObject.java b/java/src/main/java/org/rocksdb/RocksObject.java index 2d645805a..d5c71aecb 100644 --- a/java/src/main/java/org/rocksdb/RocksObject.java +++ b/java/src/main/java/org/rocksdb/RocksObject.java @@ -22,104 +22,25 @@ package org.rocksdb; * as {@code dispose()} will be called in the finalizer during the * regular GC process.

*/ -public abstract class RocksObject { - protected RocksObject() { - nativeHandle_ = 0; - owningHandle_ = true; - } - - /** - * Release the c++ object manually pointed by the native handle. - *

- * 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. - *

- *

- * Note that once an instance of {@code RocksObject} has been disposed, - * calling its function will lead undefined behavior. - *

- */ - 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. - *

- * 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. - *

- * 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()}. - *

- * @see #dispose() - * @see #isInitialized() - */ - protected void disOwnNativeHandle() { - owningHandle_ = false; - } - - /** - * Returns true if the current {@code RocksObject} is responsible to release - * its native handle. - * - * @return true if the current {@code RocksObject} is responsible to release - * its native handle. - * - * @see #disOwnNativeHandle() - * @see #dispose() - */ - protected boolean isOwningNativeHandle() { - return owningHandle_; - } - - /** - * Returns true if the associated native handle has been initialized. - * - * @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 - * yet released. - */ - @Override protected void finalize() throws Throwable { - dispose(); - super.finalize(); - } +public abstract class RocksObject extends NativeReference { /** * A long variable holding c++ pointer pointing to some RocksDB C++ object. */ - protected long nativeHandle_; + protected final long nativeHandle_; + + protected RocksObject(final long nativeHandle) { + super(true); + this.nativeHandle_ = nativeHandle; + } /** - * A flag indicating whether the current {@code RocksObject} is responsible to - * release the c++ object stored in its {@code nativeHandle_}. + * Deletes underlying C++ object pointer. */ - private boolean owningHandle_; + @Override + protected void disposeInternal() { + disposeInternal(nativeHandle_); + } + + protected abstract void disposeInternal(final long handle); } diff --git a/java/src/main/java/org/rocksdb/Slice.java b/java/src/main/java/org/rocksdb/Slice.java index 2a1ae6fae..ae0815392 100644 --- a/java/src/main/java/org/rocksdb/Slice.java +++ b/java/src/main/java/org/rocksdb/Slice.java @@ -29,7 +29,6 @@ public class Slice extends AbstractSlice { */ private Slice() { super(); - disOwnNativeHandle(); } /** @@ -39,8 +38,7 @@ public class Slice extends AbstractSlice { * @param str String value. */ public Slice(final String str) { - super(); - createNewSliceFromString(str); + super(createNewSliceFromString(str)); } /** @@ -51,8 +49,7 @@ public class Slice extends AbstractSlice { * @param offset offset within the byte array. */ public Slice(final byte[] data, final int offset) { - super(); - createNewSlice0(data, offset); + super(createNewSlice0(data, offset)); } /** @@ -62,8 +59,7 @@ public class Slice extends AbstractSlice { * @param data byte array. */ public Slice(final byte[] data) { - super(); - createNewSlice1(data); + super(createNewSlice1(data)); } /** @@ -82,7 +78,8 @@ public class Slice extends AbstractSlice { } @Override protected final native byte[] data0(long handle); - private native void createNewSlice0(byte[] data, int length); - private native void createNewSlice1(byte[] data); - private native void disposeInternalBuf(long handle); + private native static long createNewSlice0(final byte[] data, + final int length); + private native static long createNewSlice1(final byte[] data); + private native void disposeInternalBuf(final long handle); } diff --git a/java/src/main/java/org/rocksdb/Snapshot.java b/java/src/main/java/org/rocksdb/Snapshot.java index c71eac937..8475ec995 100644 --- a/java/src/main/java/org/rocksdb/Snapshot.java +++ b/java/src/main/java/org/rocksdb/Snapshot.java @@ -10,8 +10,7 @@ package org.rocksdb; */ public class Snapshot extends RocksObject { Snapshot(final long nativeHandle) { - super(); - nativeHandle_ = nativeHandle; + super(nativeHandle); } /** @@ -21,7 +20,7 @@ public class Snapshot extends RocksObject { * this snapshot. */ public long getSequenceNumber() { - assert(isInitialized()); + assert(isOwningHandle()); return getSequenceNumber(nativeHandle_); } @@ -30,7 +29,8 @@ public class Snapshot extends RocksObject { * to the snapshot is released by the database * instance. */ - @Override protected void disposeInternal() { + @Override + protected final void disposeInternal(final long handle) { } private native long getSequenceNumber(long handle); diff --git a/java/src/main/java/org/rocksdb/TransactionLogIterator.java b/java/src/main/java/org/rocksdb/TransactionLogIterator.java index 36f7e2cdf..f9684bd72 100644 --- a/java/src/main/java/org/rocksdb/TransactionLogIterator.java +++ b/java/src/main/java/org/rocksdb/TransactionLogIterator.java @@ -57,12 +57,7 @@ public class TransactionLogIterator extends RocksObject { * @param nativeHandle address to native address. */ TransactionLogIterator(final long nativeHandle) { - super(); - nativeHandle_ = nativeHandle; - } - - @Override protected void disposeInternal() { - disposeInternal(nativeHandle_); + super(nativeHandle); } /** @@ -107,7 +102,7 @@ public class TransactionLogIterator extends RocksObject { 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 void next(long handle); private native void status(long handle) diff --git a/java/src/main/java/org/rocksdb/TtlDB.java b/java/src/main/java/org/rocksdb/TtlDB.java index 351ab5c07..d0d2b9e6d 100644 --- a/java/src/main/java/org/rocksdb/TtlDB.java +++ b/java/src/main/java/org/rocksdb/TtlDB.java @@ -84,9 +84,7 @@ public class TtlDB extends RocksDB { */ public static TtlDB open(final Options options, final String db_path, final int ttl, final boolean readOnly) throws RocksDBException { - TtlDB ttldb = new TtlDB(); - ttldb.open(options.nativeHandle_, db_path, ttl, readOnly); - return ttldb; + return new TtlDB(open(options.nativeHandle_, db_path, ttl, readOnly)); } /** @@ -117,12 +115,25 @@ public class TtlDB extends RocksDB { throw new IllegalArgumentException("There must be a ttl value per column" + "family handle."); } - TtlDB ttlDB = new TtlDB(); - List cfReferences = ttlDB.openCF(options.nativeHandle_, db_path, - columnFamilyDescriptors, columnFamilyDescriptors.size(), - ttlValues, readOnly); - for (int i=0; i */ - @Override public synchronized void close() { - if (isInitialized()) { + @Override + public void close() { super.close(); - } } /** @@ -175,22 +184,25 @@ public class TtlDB extends RocksDB { * {@link #open(DBOptions, String, java.util.List, java.util.List, * java.util.List, boolean)}. *

+ * + * @param nativeHandle The native handle of the C++ TtlDB object */ - protected TtlDB() { - super(); + protected TtlDB(final long nativeHandle) { + super(nativeHandle); } @Override protected void finalize() throws Throwable { - close(); + close(); //TODO(AR) revisit here when implementing AutoCloseable super.finalize(); } - private native void open(long optionsHandle, String db_path, int ttl, - boolean readOnly) throws RocksDBException; - private native List openCF(long optionsHandle, String db_path, - List columnFamilyDescriptors, - int columnFamilyDescriptorsLength, List ttlValues, - boolean readOnly) throws RocksDBException; + private native static long open(final long optionsHandle, + final String db_path, final int ttl, final boolean readOnly) + throws RocksDBException; + private native static long[] openCF(final long optionsHandle, + final String db_path, final byte[][] columnFamilyNames, + final long[] columnFamilyOptions, final int[] ttlValues, + final boolean readOnly) throws RocksDBException; private native long createColumnFamilyWithTtl(long handle, ColumnFamilyDescriptor columnFamilyDescriptor, int ttl) throws RocksDBException; diff --git a/java/src/main/java/org/rocksdb/WBWIRocksIterator.java b/java/src/main/java/org/rocksdb/WBWIRocksIterator.java index b807810dc..6d06c8bd3 100644 --- a/java/src/main/java/org/rocksdb/WBWIRocksIterator.java +++ b/java/src/main/java/org/rocksdb/WBWIRocksIterator.java @@ -23,13 +23,13 @@ public class WBWIRocksIterator extends AbstractRocksIterator> fallbackIndexComparator, final int reservedBytes, final boolean overwriteKey) { - super(); - newWriteBatchWithIndex(fallbackIndexComparator.nativeHandle_, reservedBytes, overwriteKey); + super(newWriteBatchWithIndex(fallbackIndexComparator.getNativeHandle(), reservedBytes, overwriteKey)); } /** @@ -126,7 +123,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch { 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 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 clear0(); - private native void newWriteBatchWithIndex(); - private native void newWriteBatchWithIndex(boolean overwriteKey); - private native void newWriteBatchWithIndex(long fallbackIndexComparatorHandle, int reservedBytes, - boolean overwriteKey); + private native static long newWriteBatchWithIndex(); + private native static long newWriteBatchWithIndex(final boolean overwriteKey); + private native static long newWriteBatchWithIndex( + final long fallbackIndexComparatorHandle, final int reservedBytes, + final boolean overwriteKey); private native long iterator0(); private native long iterator1(long cfHandle); private native long iteratorWithBase(long baseIteratorHandle, long cfHandle); diff --git a/java/src/main/java/org/rocksdb/WriteOptions.java b/java/src/main/java/org/rocksdb/WriteOptions.java index d6a32fb4f..4e7abd873 100644 --- a/java/src/main/java/org/rocksdb/WriteOptions.java +++ b/java/src/main/java/org/rocksdb/WriteOptions.java @@ -16,13 +16,8 @@ public class WriteOptions extends RocksObject { * Construct WriteOptions instance. */ public WriteOptions() { - super(); - newWriteOptions(); - } + super(newWriteOptions()); - @Override protected void disposeInternal() { - assert(isInitialized()); - disposeInternal(nativeHandle_); } /** @@ -97,10 +92,10 @@ public class WriteOptions extends RocksObject { return disableWAL(nativeHandle_); } - private native void newWriteOptions(); + private native static long newWriteOptions(); private native void setSync(long handle, boolean flag); private native boolean sync(long handle); private native void setDisableWAL(long handle, boolean flag); private native boolean disableWAL(long handle); - private native void disposeInternal(long handle); + @Override protected final native void disposeInternal(final long handle); } diff --git a/java/src/test/java/org/rocksdb/WriteBatchWithIndexTest.java b/java/src/test/java/org/rocksdb/WriteBatchWithIndexTest.java index 837610d29..08cac9bce 100644 --- a/java/src/test/java/org/rocksdb/WriteBatchWithIndexTest.java +++ b/java/src/test/java/org/rocksdb/WriteBatchWithIndexTest.java @@ -209,7 +209,9 @@ public class WriteBatchWithIndexTest { it.seek(key); 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