Merge pull request #980 from adamretter/java-arm

ARM for the Java API
main
Yueh-Hsuan Chiang 9 years ago
commit 51c9464dfc
  1. 23
      java/rocksjni/backupablejni.cc
  2. 14
      java/rocksjni/backupenginejni.cc
  3. 12
      java/rocksjni/comparator.cc
  4. 6
      java/rocksjni/comparatorjnicallback.cc
  5. 12
      java/rocksjni/filter.cc
  6. 12
      java/rocksjni/loggerjnicallback.cc
  7. 131
      java/rocksjni/options.cc
  8. 93
      java/rocksjni/portal.h
  9. 13
      java/rocksjni/remove_emptyvalue_compactionfilterjni.cc
  10. 16
      java/rocksjni/restorejni.cc
  11. 578
      java/rocksjni/rocksjni.cc
  12. 48
      java/rocksjni/slice.cc
  13. 171
      java/rocksjni/ttl.cc
  14. 90
      java/rocksjni/write_batch.cc
  15. 26
      java/rocksjni/write_batch_test.cc
  16. 183
      java/rocksjni/write_batch_with_index.cc
  17. 56
      java/samples/src/main/java/RocksDBColumnFamilySample.java
  18. 58
      java/samples/src/main/java/RocksDBSample.java
  19. 19
      java/src/main/java/org/rocksdb/AbstractCompactionFilter.java
  20. 16
      java/src/main/java/org/rocksdb/AbstractComparator.java
  21. 66
      java/src/main/java/org/rocksdb/AbstractImmutableNativeReference.java
  22. 76
      java/src/main/java/org/rocksdb/AbstractNativeReference.java
  23. 23
      java/src/main/java/org/rocksdb/AbstractRocksIterator.java
  24. 56
      java/src/main/java/org/rocksdb/AbstractSlice.java
  25. 87
      java/src/main/java/org/rocksdb/AbstractWriteBatch.java
  26. 63
      java/src/main/java/org/rocksdb/BackupEngine.java
  27. 35
      java/src/main/java/org/rocksdb/BackupableDB.java
  28. 119
      java/src/main/java/org/rocksdb/BackupableDBOptions.java
  29. 16
      java/src/main/java/org/rocksdb/BloomFilter.java
  30. 18
      java/src/main/java/org/rocksdb/Checkpoint.java
  31. 21
      java/src/main/java/org/rocksdb/ColumnFamilyHandle.java
  32. 90
      java/src/main/java/org/rocksdb/ColumnFamilyOptions.java
  33. 12
      java/src/main/java/org/rocksdb/Comparator.java
  34. 16
      java/src/main/java/org/rocksdb/ComparatorOptions.java
  35. 153
      java/src/main/java/org/rocksdb/DBOptions.java
  36. 13
      java/src/main/java/org/rocksdb/DirectComparator.java
  37. 45
      java/src/main/java/org/rocksdb/DirectSlice.java
  38. 4
      java/src/main/java/org/rocksdb/Env.java
  39. 12
      java/src/main/java/org/rocksdb/Filter.java
  40. 15
      java/src/main/java/org/rocksdb/FlushOptions.java
  41. 17
      java/src/main/java/org/rocksdb/Logger.java
  42. 201
      java/src/main/java/org/rocksdb/Options.java
  43. 27
      java/src/main/java/org/rocksdb/ReadOptions.java
  44. 8
      java/src/main/java/org/rocksdb/RemoveEmptyValueCompactionFilter.java
  45. 30
      java/src/main/java/org/rocksdb/RestoreBackupableDB.java
  46. 25
      java/src/main/java/org/rocksdb/RestoreOptions.java
  47. 363
      java/src/main/java/org/rocksdb/RocksDB.java
  48. 6
      java/src/main/java/org/rocksdb/RocksEnv.java
  49. 6
      java/src/main/java/org/rocksdb/RocksIterator.java
  50. 10
      java/src/main/java/org/rocksdb/RocksMemEnv.java
  51. 69
      java/src/main/java/org/rocksdb/RocksMutableObject.java
  52. 122
      java/src/main/java/org/rocksdb/RocksObject.java
  53. 22
      java/src/main/java/org/rocksdb/Slice.java
  54. 8
      java/src/main/java/org/rocksdb/Snapshot.java
  55. 9
      java/src/main/java/org/rocksdb/TransactionLogIterator.java
  56. 66
      java/src/main/java/org/rocksdb/TtlDB.java
  57. 49
      java/src/main/java/org/rocksdb/WBWIRocksIterator.java
  58. 60
      java/src/main/java/org/rocksdb/WriteBatch.java
  59. 109
      java/src/main/java/org/rocksdb/WriteBatchWithIndex.java
  60. 11
      java/src/main/java/org/rocksdb/WriteOptions.java
  61. 100
      java/src/test/java/org/rocksdb/AbstractComparatorTest.java
  62. 135
      java/src/test/java/org/rocksdb/BackupEngineTest.java
  63. 170
      java/src/test/java/org/rocksdb/BackupableDBOptionsTest.java
  64. 219
      java/src/test/java/org/rocksdb/BackupableDBTest.java
  65. 24
      java/src/test/java/org/rocksdb/BlockBasedTableConfigTest.java
  66. 63
      java/src/test/java/org/rocksdb/CheckPointTest.java
  67. 445
      java/src/test/java/org/rocksdb/ColumnFamilyOptionsTest.java
  68. 619
      java/src/test/java/org/rocksdb/ColumnFamilyTest.java
  69. 7
      java/src/test/java/org/rocksdb/ComparatorOptionsTest.java
  70. 73
      java/src/test/java/org/rocksdb/ComparatorTest.java
  71. 5
      java/src/test/java/org/rocksdb/CompressionOptionsTest.java
  72. 388
      java/src/test/java/org/rocksdb/DBOptionsTest.java
  73. 64
      java/src/test/java/org/rocksdb/DirectSliceTest.java
  74. 32
      java/src/test/java/org/rocksdb/FilterTest.java
  75. 46
      java/src/test/java/org/rocksdb/FlushTest.java
  76. 50
      java/src/test/java/org/rocksdb/InfoLogLevelTest.java
  77. 58
      java/src/test/java/org/rocksdb/KeyMayExistTest.java
  78. 126
      java/src/test/java/org/rocksdb/LoggerTest.java
  79. 34
      java/src/test/java/org/rocksdb/MemTableTest.java
  80. 283
      java/src/test/java/org/rocksdb/MergeTest.java
  81. 29
      java/src/test/java/org/rocksdb/MixedOptionsTest.java
  82. 2
      java/src/test/java/org/rocksdb/NativeLibraryLoaderTest.java
  83. 737
      java/src/test/java/org/rocksdb/OptionsTest.java
  84. 10
      java/src/test/java/org/rocksdb/PlainTableConfigTest.java
  85. 2
      java/src/test/java/org/rocksdb/PlatformRandomHelper.java
  86. 396
      java/src/test/java/org/rocksdb/ReadOnlyTest.java
  87. 88
      java/src/test/java/org/rocksdb/ReadOptionsTest.java
  88. 439
      java/src/test/java/org/rocksdb/RocksDBTest.java
  89. 3
      java/src/test/java/org/rocksdb/RocksEnvTest.java
  90. 24
      java/src/test/java/org/rocksdb/RocksIteratorTest.java
  91. 96
      java/src/test/java/org/rocksdb/RocksMemEnvTest.java
  92. 4
      java/src/test/java/org/rocksdb/RocksMemoryResource.java
  93. 68
      java/src/test/java/org/rocksdb/SliceTest.java
  94. 112
      java/src/test/java/org/rocksdb/SnapshotTest.java
  95. 32
      java/src/test/java/org/rocksdb/StatisticsCollectorTest.java
  96. 134
      java/src/test/java/org/rocksdb/TransactionLogIteratorTest.java
  97. 120
      java/src/test/java/org/rocksdb/TtlDBTest.java
  98. 63
      java/src/test/java/org/rocksdb/WriteBatchHandlerTest.java
  99. 50
      java/src/test/java/org/rocksdb/WriteBatchTest.java
  100. 96
      java/src/test/java/org/rocksdb/WriteBatchWithIndexTest.java
  101. Some files were not shown because too many files have changed in this diff Show More

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

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

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

@ -60,8 +60,8 @@ int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
// performance. // performance.
mtx_compare->Lock(); mtx_compare->Lock();
AbstractSliceJni::setHandle(m_env, m_jSliceA, &a); AbstractSliceJni::setHandle(m_env, m_jSliceA, &a, JNI_FALSE);
AbstractSliceJni::setHandle(m_env, m_jSliceB, &b); AbstractSliceJni::setHandle(m_env, m_jSliceB, &b, JNI_FALSE);
jint result = jint result =
m_env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA, m_env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA,
m_jSliceB); m_jSliceB);
@ -89,7 +89,7 @@ void BaseComparatorJniCallback::FindShortestSeparator(
// performance. // performance.
mtx_findShortestSeparator->Lock(); mtx_findShortestSeparator->Lock();
AbstractSliceJni::setHandle(m_env, m_jSliceLimit, &limit); AbstractSliceJni::setHandle(m_env, m_jSliceLimit, &limit, JNI_FALSE);
jstring jsResultStart = jstring jsResultStart =
(jstring)m_env->CallObjectMethod(m_jComparator, (jstring)m_env->CallObjectMethod(m_jComparator,
m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit); m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit);

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

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

@ -36,25 +36,25 @@
/* /*
* Class: org_rocksdb_Options * Class: org_rocksdb_Options
* Method: newOptions * Method: newOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_Options_newOptions__(JNIEnv* env, jobject jobj) { jlong Java_org_rocksdb_Options_newOptions__(JNIEnv* env, jclass jcls) {
rocksdb::Options* op = new rocksdb::Options(); rocksdb::Options* op = new rocksdb::Options();
rocksdb::OptionsJni::setHandle(env, jobj, op); return reinterpret_cast<jlong>(op);
} }
/* /*
* Class: org_rocksdb_Options * Class: org_rocksdb_Options
* Method: newOptions * Method: newOptions
* Signature: (JJ)V * Signature: (JJ)J
*/ */
void Java_org_rocksdb_Options_newOptions__JJ(JNIEnv* env, jobject jobj, jlong Java_org_rocksdb_Options_newOptions__JJ(JNIEnv* env, jclass jcls,
jlong jdboptions, jlong jcfoptions) { jlong jdboptions, jlong jcfoptions) {
auto dbOpt = reinterpret_cast<const rocksdb::DBOptions*>(jdboptions); auto* dbOpt = reinterpret_cast<const rocksdb::DBOptions*>(jdboptions);
auto cfOpt = reinterpret_cast<const rocksdb::ColumnFamilyOptions*>( auto* cfOpt = reinterpret_cast<const rocksdb::ColumnFamilyOptions*>(
jcfoptions); jcfoptions);
rocksdb::Options* op = new rocksdb::Options(*dbOpt, *cfOpt); rocksdb::Options* op = new rocksdb::Options(*dbOpt, *cfOpt);
rocksdb::OptionsJni::setHandle(env, jobj, op); return reinterpret_cast<jlong>(op);
} }
/* /*
@ -1081,21 +1081,20 @@ jbyte Java_org_rocksdb_Options_compressionType(
* vector. * vector.
*/ */
std::vector<rocksdb::CompressionType> rocksdb_compression_vector_helper( std::vector<rocksdb::CompressionType> rocksdb_compression_vector_helper(
JNIEnv* env, jobject jcompressionLevels) { JNIEnv* env, jbyteArray jcompressionLevels) {
std::vector<rocksdb::CompressionType> compressionLevels; std::vector<rocksdb::CompressionType> compressionLevels;
// iterate over compressionLevels
jobject iteratorObj = env->CallObjectMethod( jsize len = env->GetArrayLength(jcompressionLevels);
jcompressionLevels, rocksdb::ListJni::getIteratorMethod(env)); jbyte* jcompressionLevel = env->GetByteArrayElements(jcompressionLevels,
while (env->CallBooleanMethod( NULL);
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { for(int i = 0; i < len; i++) {
// get compression jbyte jcl;
jobject jcompression_obj = env->CallObjectMethod(iteratorObj, jcl = jcompressionLevel[i];
rocksdb::ListJni::getNextMethod(env)); compressionLevels.push_back(static_cast<rocksdb::CompressionType>(jcl));
jbyte jcompression = env->CallByteMethod(jcompression_obj,
rocksdb::ByteJni::getByteValueMethod(env));
compressionLevels.push_back(static_cast<rocksdb::CompressionType>(
jcompression));
} }
env->ReleaseByteArrayElements(jcompressionLevels, jcompressionLevel,
JNI_ABORT);
return compressionLevels; return compressionLevels;
} }
@ -1103,34 +1102,29 @@ std::vector<rocksdb::CompressionType> rocksdb_compression_vector_helper(
* Helper method to convert a CompressionType vector to a Java * Helper method to convert a CompressionType vector to a Java
* List. * List.
*/ */
jobject rocksdb_compression_list_helper(JNIEnv* env, jbyteArray rocksdb_compression_list_helper(JNIEnv* env,
std::vector<rocksdb::CompressionType> compressionLevels) { std::vector<rocksdb::CompressionType> compressionLevels) {
jclass jListClazz = env->FindClass("java/util/ArrayList"); jbyte jbuf[compressionLevels.size()];
jmethodID midList = rocksdb::ListJni::getArrayListConstructorMethodId(
env, jListClazz);
jobject jcompressionLevels = env->NewObject(jListClazz,
midList, compressionLevels.size());
// insert in java list
for (std::vector<rocksdb::CompressionType>::size_type i = 0; for (std::vector<rocksdb::CompressionType>::size_type i = 0;
i != compressionLevels.size(); i++) { i != compressionLevels.size(); i++) {
jclass jByteClazz = env->FindClass("java/lang/Byte"); jbuf[i] = compressionLevels[i];
jmethodID midByte = env->GetMethodID(jByteClazz, "<init>", "(B)V");
jobject obj = env->NewObject(jByteClazz, midByte,
compressionLevels[i]);
env->CallBooleanMethod(jcompressionLevels,
rocksdb::ListJni::getListAddMethodId(env), obj);
} }
// insert in java array
jbyteArray jcompressionLevels = env->NewByteArray(
static_cast<jsize>(compressionLevels.size()));
env->SetByteArrayRegion(jcompressionLevels, 0,
static_cast<jsize>(compressionLevels.size()), jbuf);
return jcompressionLevels; return jcompressionLevels;
} }
/* /*
* Class: org_rocksdb_Options * Class: org_rocksdb_Options
* Method: setCompressionPerLevel * Method: setCompressionPerLevel
* Signature: (JLjava/util/List;)V * Signature: (J[B)V
*/ */
void Java_org_rocksdb_Options_setCompressionPerLevel( void Java_org_rocksdb_Options_setCompressionPerLevel(
JNIEnv* env, jobject jobj, jlong jhandle, JNIEnv* env, jobject jobj, jlong jhandle,
jobject jcompressionLevels) { jbyteArray jcompressionLevels) {
auto* options = reinterpret_cast<rocksdb::Options*>(jhandle); auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
std::vector<rocksdb::CompressionType> compressionLevels = std::vector<rocksdb::CompressionType> compressionLevels =
rocksdb_compression_vector_helper(env, jcompressionLevels); rocksdb_compression_vector_helper(env, jcompressionLevels);
@ -1140,9 +1134,9 @@ void Java_org_rocksdb_Options_setCompressionPerLevel(
/* /*
* Class: org_rocksdb_Options * Class: org_rocksdb_Options
* Method: compressionPerLevel * Method: compressionPerLevel
* Signature: (J)Ljava/util/List; * Signature: (J)[B
*/ */
jobject Java_org_rocksdb_Options_compressionPerLevel( jbyteArray Java_org_rocksdb_Options_compressionPerLevel(
JNIEnv* env, jobject jobj, jlong jhandle) { JNIEnv* env, jobject jobj, jlong jhandle) {
auto* options = reinterpret_cast<rocksdb::Options*>(jhandle); auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
return rocksdb_compression_list_helper(env, return rocksdb_compression_list_helper(env,
@ -1932,12 +1926,12 @@ void Java_org_rocksdb_Options_prepareForBulkLoad(
/* /*
* Class: org_rocksdb_ColumnFamilyOptions * Class: org_rocksdb_ColumnFamilyOptions
* Method: newColumnFamilyOptions * Method: newColumnFamilyOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions( jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
rocksdb::ColumnFamilyOptions* op = new rocksdb::ColumnFamilyOptions(); rocksdb::ColumnFamilyOptions* op = new rocksdb::ColumnFamilyOptions();
rocksdb::ColumnFamilyOptionsJni::setHandle(env, jobj, op); return reinterpret_cast<jlong>(op);
} }
/* /*
@ -2285,11 +2279,11 @@ jbyte Java_org_rocksdb_ColumnFamilyOptions_compressionType(
/* /*
* Class: org_rocksdb_ColumnFamilyOptions * Class: org_rocksdb_ColumnFamilyOptions
* Method: setCompressionPerLevel * Method: setCompressionPerLevel
* Signature: (JLjava/util/List;)V * Signature: (J[B)V
*/ */
void Java_org_rocksdb_ColumnFamilyOptions_setCompressionPerLevel( void Java_org_rocksdb_ColumnFamilyOptions_setCompressionPerLevel(
JNIEnv* env, jobject jobj, jlong jhandle, JNIEnv* env, jobject jobj, jlong jhandle,
jobject jcompressionLevels) { jbyteArray jcompressionLevels) {
auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle); auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
std::vector<rocksdb::CompressionType> compressionLevels = std::vector<rocksdb::CompressionType> compressionLevels =
rocksdb_compression_vector_helper(env, jcompressionLevels); rocksdb_compression_vector_helper(env, jcompressionLevels);
@ -2299,9 +2293,9 @@ void Java_org_rocksdb_ColumnFamilyOptions_setCompressionPerLevel(
/* /*
* Class: org_rocksdb_ColumnFamilyOptions * Class: org_rocksdb_ColumnFamilyOptions
* Method: compressionPerLevel * Method: compressionPerLevel
* Signature: (J)Ljava/util/List; * Signature: (J)[B
*/ */
jobject Java_org_rocksdb_ColumnFamilyOptions_compressionPerLevel( jbyteArray Java_org_rocksdb_ColumnFamilyOptions_compressionPerLevel(
JNIEnv* env, jobject jobj, jlong jhandle) { JNIEnv* env, jobject jobj, jlong jhandle) {
auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle); auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
return rocksdb_compression_list_helper(env, return rocksdb_compression_list_helper(env,
@ -3072,12 +3066,12 @@ void Java_org_rocksdb_ColumnFamilyOptions_setOptimizeFiltersForHits(
/* /*
* Class: org_rocksdb_DBOptions * Class: org_rocksdb_DBOptions
* Method: newDBOptions * Method: newDBOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env, jlong Java_org_rocksdb_DBOptions_newDBOptions(JNIEnv* env,
jobject jobj) { jclass jcls) {
rocksdb::DBOptions* dbop = new rocksdb::DBOptions(); rocksdb::DBOptions* dbop = new rocksdb::DBOptions();
rocksdb::DBOptionsJni::setHandle(env, jobj, dbop); return reinterpret_cast<jlong>(dbop);
} }
/* /*
@ -3872,12 +3866,12 @@ jlong Java_org_rocksdb_DBOptions_bytesPerSync(
/* /*
* Class: org_rocksdb_WriteOptions * Class: org_rocksdb_WriteOptions
* Method: newWriteOptions * Method: newWriteOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_WriteOptions_newWriteOptions( jlong Java_org_rocksdb_WriteOptions_newWriteOptions(
JNIEnv* env, jobject jwrite_options) { JNIEnv* env, jclass jcls) {
rocksdb::WriteOptions* op = new rocksdb::WriteOptions(); rocksdb::WriteOptions* op = new rocksdb::WriteOptions();
rocksdb::WriteOptionsJni::setHandle(env, jwrite_options, op); return reinterpret_cast<jlong>(op);
} }
/* /*
@ -3889,8 +3883,6 @@ void Java_org_rocksdb_WriteOptions_disposeInternal(
JNIEnv* env, jobject jwrite_options, jlong jhandle) { JNIEnv* env, jobject jwrite_options, jlong jhandle) {
auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle); auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle);
delete write_options; delete write_options;
rocksdb::WriteOptionsJni::setHandle(env, jwrite_options, nullptr);
} }
/* /*
@ -3939,12 +3931,12 @@ jboolean Java_org_rocksdb_WriteOptions_disableWAL(
/* /*
* Class: org_rocksdb_ReadOptions * Class: org_rocksdb_ReadOptions
* Method: newReadOptions * Method: newReadOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_ReadOptions_newReadOptions( jlong Java_org_rocksdb_ReadOptions_newReadOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
auto read_opt = new rocksdb::ReadOptions(); auto read_opt = new rocksdb::ReadOptions();
rocksdb::ReadOptionsJni::setHandle(env, jobj, read_opt); return reinterpret_cast<jlong>(read_opt);
} }
/* /*
@ -3955,7 +3947,6 @@ void Java_org_rocksdb_ReadOptions_newReadOptions(
void Java_org_rocksdb_ReadOptions_disposeInternal( void Java_org_rocksdb_ReadOptions_disposeInternal(
JNIEnv* env, jobject jobj, jlong jhandle) { JNIEnv* env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::ReadOptions*>(jhandle); delete reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
rocksdb::ReadOptionsJni::setHandle(env, jobj, nullptr);
} }
/* /*
@ -4052,12 +4043,12 @@ jlong Java_org_rocksdb_ReadOptions_snapshot(
/* /*
* Class: org_rocksdb_ComparatorOptions * Class: org_rocksdb_ComparatorOptions
* Method: newComparatorOptions * Method: newComparatorOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_ComparatorOptions_newComparatorOptions( jlong Java_org_rocksdb_ComparatorOptions_newComparatorOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
auto comparator_opt = new rocksdb::ComparatorJniCallbackOptions(); auto comparator_opt = new rocksdb::ComparatorJniCallbackOptions();
rocksdb::ComparatorOptionsJni::setHandle(env, jobj, comparator_opt); return reinterpret_cast<jlong>(comparator_opt);
} }
/* /*
@ -4090,7 +4081,6 @@ void Java_org_rocksdb_ComparatorOptions_setUseAdaptiveMutex(
void Java_org_rocksdb_ComparatorOptions_disposeInternal( void Java_org_rocksdb_ComparatorOptions_disposeInternal(
JNIEnv * env, jobject jobj, jlong jhandle) { JNIEnv * env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle); delete reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle);
rocksdb::ComparatorOptionsJni::setHandle(env, jobj, nullptr);
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -4099,12 +4089,12 @@ void Java_org_rocksdb_ComparatorOptions_disposeInternal(
/* /*
* Class: org_rocksdb_FlushOptions * Class: org_rocksdb_FlushOptions
* Method: newFlushOptions * Method: newFlushOptions
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_FlushOptions_newFlushOptions( jlong Java_org_rocksdb_FlushOptions_newFlushOptions(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
auto flush_opt = new rocksdb::FlushOptions(); auto flush_opt = new rocksdb::FlushOptions();
rocksdb::FlushOptionsJni::setHandle(env, jobj, flush_opt); return reinterpret_cast<jlong>(flush_opt);
} }
/* /*
@ -4137,5 +4127,4 @@ jboolean Java_org_rocksdb_FlushOptions_waitForFlush(
void Java_org_rocksdb_FlushOptions_disposeInternal( void Java_org_rocksdb_FlushOptions_disposeInternal(
JNIEnv * env, jobject jobj, jlong jhandle) { JNIEnv * env, jobject jobj, jlong jhandle) {
delete reinterpret_cast<rocksdb::FlushOptions*>(jhandle); delete reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
rocksdb::FlushOptionsJni::setHandle(env, jobj, nullptr);
} }

@ -49,27 +49,25 @@ template<class PTR, class DERIVED> class RocksDBNativeClass {
assert(jclazz != nullptr); assert(jclazz != nullptr);
return jclazz; return jclazz;
} }
};
// Get the field id of the member variable to store // Native class template for sub-classes of RocksMutableObject
// the ptr template<class PTR, class DERIVED> class NativeRocksMutableObject
static jfieldID getHandleFieldID(JNIEnv* env) { : public RocksDBNativeClass<PTR, DERIVED> {
static jfieldID fid = env->GetFieldID( public:
DERIVED::getJClass(env), "nativeHandle_", "J");
assert(fid != nullptr);
return fid;
}
// Get the pointer from Java static jmethodID getSetNativeHandleMethod(JNIEnv* env) {
static PTR getHandle(JNIEnv* env, jobject jobj) { static jmethodID mid = env->GetMethodID(
return reinterpret_cast<PTR>( DERIVED::getJClass(env), "setNativeHandle", "(JZ)V");
env->GetLongField(jobj, getHandleFieldID(env))); assert(mid != nullptr);
return mid;
} }
// Pass the pointer to the java side. // Pass the pointer to the java side.
static void setHandle(JNIEnv* env, jobject jdb, PTR ptr) { static void setHandle(JNIEnv* env, jobject jobj, PTR ptr,
env->SetLongField( jboolean java_owns_handle) {
jdb, getHandleFieldID(env), env->CallVoidMethod(jobj, getSetNativeHandleMethod(env),
reinterpret_cast<jlong>(ptr)); reinterpret_cast<jlong>(ptr), java_owns_handle);
} }
}; };
@ -407,7 +405,7 @@ class AbstractComparatorJni : public RocksDBNativeClass<
}; };
// The portal class for org.rocksdb.AbstractSlice // The portal class for org.rocksdb.AbstractSlice
class AbstractSliceJni : public RocksDBNativeClass< class AbstractSliceJni : public NativeRocksMutableObject<
const rocksdb::Slice*, AbstractSliceJni> { const rocksdb::Slice*, AbstractSliceJni> {
public: public:
static jclass getJClass(JNIEnv* env) { static jclass getJClass(JNIEnv* env) {
@ -649,67 +647,6 @@ class WriteEntryJni {
assert(jclazz != nullptr); assert(jclazz != nullptr);
return jclazz; return jclazz;
} }
static void setWriteType(JNIEnv* env, jobject jwrite_entry,
WriteType write_type) {
jobject jwrite_type;
switch (write_type) {
case kPutRecord:
jwrite_type = WriteTypeJni::PUT(env);
break;
case kMergeRecord:
jwrite_type = WriteTypeJni::MERGE(env);
break;
case kDeleteRecord:
jwrite_type = WriteTypeJni::DELETE(env);
break;
case kLogDataRecord:
jwrite_type = WriteTypeJni::LOG(env);
break;
default:
jwrite_type = nullptr;
}
assert(jwrite_type != nullptr);
env->SetObjectField(jwrite_entry, getWriteTypeField(env), jwrite_type);
}
static void setKey(JNIEnv* env, jobject jwrite_entry,
const rocksdb::Slice* slice) {
jobject jkey = env->GetObjectField(jwrite_entry, getKeyField(env));
AbstractSliceJni::setHandle(env, jkey, slice);
}
static void setValue(JNIEnv* env, jobject jwrite_entry,
const rocksdb::Slice* slice) {
jobject jvalue = env->GetObjectField(jwrite_entry, getValueField(env));
AbstractSliceJni::setHandle(env, jvalue, slice);
}
private:
static jfieldID getWriteTypeField(JNIEnv* env) {
static jfieldID fid = env->GetFieldID(
getJClass(env), "type", "Lorg/rocksdb/WBWIRocksIterator$WriteType;");
assert(fid != nullptr);
return fid;
}
static jfieldID getKeyField(JNIEnv* env) {
static jfieldID fid = env->GetFieldID(
getJClass(env), "key", "Lorg/rocksdb/DirectSlice;");
assert(fid != nullptr);
return fid;
}
static jfieldID getValueField(JNIEnv* env) {
static jfieldID fid = env->GetFieldID(
getJClass(env), "value", "Lorg/rocksdb/DirectSlice;");
assert(fid != nullptr);
return fid;
}
}; };
class InfoLogLevelJni { class InfoLogLevelJni {

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

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

@ -11,6 +11,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include <tuple>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@ -26,217 +27,142 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// rocksdb::DB::Open // rocksdb::DB::Open
jlong rocksdb_open_helper(JNIEnv* env, jlong jopt_handle, jstring jdb_path,
/* std::function<rocksdb::Status(
* Class: org_rocksdb_RocksDB const rocksdb::Options&, const std::string&, rocksdb::DB**)> open_fn
* Method: open ) {
* Signature: (JLjava/lang/String;)V auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
*/
void Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) {
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
rocksdb::DB* db = nullptr; rocksdb::DB* db = nullptr;
const char* db_path = env->GetStringUTFChars(jdb_path, 0); const char* db_path = env->GetStringUTFChars(jdb_path, NULL);
rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, &db); rocksdb::Status s = open_fn(*opt, db_path, &db);
env->ReleaseStringUTFChars(jdb_path, db_path); env->ReleaseStringUTFChars(jdb_path, db_path);
if (s.ok()) { if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db); return reinterpret_cast<jlong>(db);
return; } else {
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s); rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
}
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: openROnly * Method: open
* Signature: (JLjava/lang/String;)V * Signature: (JLjava/lang/String;)J
*/ */
void Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2( jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) { JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path) {
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); return rocksdb_open_helper(env, jopt_handle, jdb_path,
rocksdb::DB* db = nullptr; (rocksdb::Status(*)
const char* db_path = env->GetStringUTFChars(jdb_path, 0); (const rocksdb::Options&, const std::string&, rocksdb::DB**)
rocksdb::Status s = rocksdb::DB::OpenForReadOnly(*opt, )&rocksdb::DB::Open
db_path, &db); );
env->ReleaseStringUTFChars(jdb_path, db_path);
if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db);
return;
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: openROnly * Method: openROnly
* Signature: (JLjava/lang/String;Ljava/util/List;I)Ljava/util/List; * Signature: (JLjava/lang/String;)J
*/ */
jobject jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2(
Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2Ljava_util_List_2I( JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path) {
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, return rocksdb_open_helper(env, jopt_handle, jdb_path, [](
jobject jcfdesc_list, jint jcfdesc_count) { const rocksdb::Options& options,
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); const std::string& db_path, rocksdb::DB** db) {
rocksdb::DB* db = nullptr; return rocksdb::DB::OpenForReadOnly(options, db_path, db);
const char* db_path = env->GetStringUTFChars(jdb_path, 0); });
}
std::vector<jbyte*> cfnames_to_free;
std::vector<jbyteArray> jcfnames_for_free; jlongArray rocksdb_open_helper(JNIEnv* env, jlong jopt_handle,
jstring jdb_path, jobjectArray jcolumn_names, jlongArray jcolumn_options,
std::function<rocksdb::Status(
const rocksdb::DBOptions&, const std::string&,
const std::vector<rocksdb::ColumnFamilyDescriptor>&,
std::vector<rocksdb::ColumnFamilyHandle*>*,
rocksdb::DB**)> open_fn
) {
auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
const char* db_path = env->GetStringUTFChars(jdb_path, NULL);
std::vector<rocksdb::ColumnFamilyDescriptor> column_families; std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
std::vector<rocksdb::ColumnFamilyHandle* > handles;
// get iterator for ColumnFamilyDescriptors jsize len_cols = env->GetArrayLength(jcolumn_names);
jobject iteratorObj = env->CallObjectMethod( jlong* jco = env->GetLongArrayElements(jcolumn_options, NULL);
jcfdesc_list, rocksdb::ListJni::getIteratorMethod(env)); for(int i = 0; i < len_cols; i++) {
jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
// iterate over ColumnFamilyDescriptors jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
while (env->CallBooleanMethod( jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, NULL);
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { const int jcf_name_len = env->GetArrayLength(jcn_ba);
// get ColumnFamilyDescriptor
jobject jcf_descriptor = env->CallObjectMethod(iteratorObj, //TODO(AR) do I need to make a copy of jco[i] ?
rocksdb::ListJni::getNextMethod(env));
// get ColumnFamilyName std::string cf_name (reinterpret_cast<char *>(jcf_name), jcf_name_len);
jbyteArray cf_name_in_byte_array = static_cast<jbyteArray>( rocksdb::ColumnFamilyOptions* cf_options =
env->CallObjectMethod(jcf_descriptor, reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[i]);
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyNameMethod( column_families.push_back(
env))); rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
// get CF Options
jobject jcf_opt_obj = env->CallObjectMethod(jcf_descriptor, env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyOptionsMethod( env->DeleteLocalRef(jcn);
env));
rocksdb::ColumnFamilyOptions* cfOptions =
rocksdb::ColumnFamilyOptionsJni::getHandle(env, jcf_opt_obj);
jbyte* cfname = env->GetByteArrayElements(cf_name_in_byte_array, 0);
const int len = env->GetArrayLength(cf_name_in_byte_array);
// free allocated cfnames after call to open
cfnames_to_free.push_back(cfname);
jcfnames_for_free.push_back(cf_name_in_byte_array);
column_families.push_back(rocksdb::ColumnFamilyDescriptor(
std::string(reinterpret_cast<char *>(cfname), len), *cfOptions));
}
rocksdb::Status s = rocksdb::DB::OpenForReadOnly(*opt,
db_path, column_families, &handles, &db);
env->ReleaseStringUTFChars(jdb_path, db_path);
// free jbyte allocations
for (std::vector<jbyte*>::size_type i = 0;
i != cfnames_to_free.size(); i++) {
// free cfnames
env->ReleaseByteArrayElements(jcfnames_for_free[i], cfnames_to_free[i], 0);
} }
env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
std::vector<rocksdb::ColumnFamilyHandle*> handles;
rocksdb::DB* db = nullptr;
rocksdb::Status s = open_fn(*opt, db_path, column_families,
&handles, &db);
// check if open operation was successful // check if open operation was successful
if (s.ok()) { if (s.ok()) {
rocksdb::RocksDBJni::setHandle(env, jdb, db); jsize resultsLen = 1 + len_cols; //db handle + column family handles
jclass jListClazz = env->FindClass("java/util/ArrayList"); jlong results[resultsLen];
jmethodID midList = rocksdb::ListJni::getArrayListConstructorMethodId( results[0] = reinterpret_cast<jlong>(db);
env, jListClazz); for(int i = 1; i <= len_cols; i++) {
jobject jcfhandle_list = env->NewObject(jListClazz, results[i] = reinterpret_cast<jlong>(handles[i - 1]);
midList, handles.size());
// insert in java list
for (std::vector<rocksdb::ColumnFamilyHandle*>::size_type i = 0;
i != handles.size(); i++) {
// jlong must be converted to Long due to collections restrictions
jclass jLongClazz = env->FindClass("java/lang/Long");
jmethodID midLong = env->GetMethodID(jLongClazz, "<init>", "(J)V");
jobject obj = env->NewObject(jLongClazz, midLong,
reinterpret_cast<jlong>(handles[i]));
env->CallBooleanMethod(jcfhandle_list,
rocksdb::ListJni::getListAddMethodId(env), obj);
}
return jcfhandle_list;
} }
jlongArray jresults = env->NewLongArray(resultsLen);
env->SetLongArrayRegion(jresults, 0, resultsLen, results);
return jresults;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s); rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return nullptr; return NULL;
}
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: open * Method: openROnly
* Signature: (JLjava/lang/String;Ljava/util/List;I)Ljava/util/List; * Signature: (JLjava/lang/String;[[B[J)[J
*/ */
jobject Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2Ljava_util_List_2I( jlongArray Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3J(
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path, JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path,
jobject jcfdesc_list, jint jcfdesc_count) { jobjectArray jcolumn_names, jlongArray jcolumn_options) {
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); return rocksdb_open_helper(env, jopt_handle, jdb_path, jcolumn_names,
rocksdb::DB* db = nullptr; jcolumn_options, [](
const char* db_path = env->GetStringUTFChars(jdb_path, 0); const rocksdb::DBOptions& options, const std::string& db_path,
const std::vector<rocksdb::ColumnFamilyDescriptor>& column_families,
std::vector<jbyte*> cfnames_to_free; std::vector<rocksdb::ColumnFamilyHandle*>* handles, rocksdb::DB** db) {
std::vector<jbyteArray> jcfnames_for_free; return rocksdb::DB::OpenForReadOnly(options, db_path, column_families,
handles, db);
std::vector<rocksdb::ColumnFamilyDescriptor> column_families; });
std::vector<rocksdb::ColumnFamilyHandle* > handles;
// get iterator for ColumnFamilyDescriptors
jobject iteratorObj = env->CallObjectMethod(
jcfdesc_list, rocksdb::ListJni::getIteratorMethod(env));
// iterate over ColumnFamilyDescriptors
while (env->CallBooleanMethod(
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
// get ColumnFamilyDescriptor
jobject jcf_descriptor = env->CallObjectMethod(iteratorObj,
rocksdb::ListJni::getNextMethod(env));
// get ColumnFamilyName
jbyteArray cf_name_in_byte_array = static_cast<jbyteArray>(
env->CallObjectMethod(jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyNameMethod(
env)));
// get CF Options
jobject jcf_opt_obj = env->CallObjectMethod(jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyOptionsMethod(
env));
rocksdb::ColumnFamilyOptions* cfOptions =
rocksdb::ColumnFamilyOptionsJni::getHandle(env, jcf_opt_obj);
jbyte* cfname = env->GetByteArrayElements(cf_name_in_byte_array, 0);
const int len = env->GetArrayLength(cf_name_in_byte_array);
// free allocated cfnames after call to open
cfnames_to_free.push_back(cfname);
jcfnames_for_free.push_back(cf_name_in_byte_array);
column_families.push_back(rocksdb::ColumnFamilyDescriptor(
std::string(reinterpret_cast<char *>(cfname), len), *cfOptions));
}
rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, column_families,
&handles, &db);
env->ReleaseStringUTFChars(jdb_path, db_path);
// free jbyte allocations
for (std::vector<jbyte*>::size_type i = 0;
i != cfnames_to_free.size(); i++) {
// free cfnames
env->ReleaseByteArrayElements(jcfnames_for_free[i], cfnames_to_free[i], 0);
} }
// check if open operation was successful /*
if (s.ok()) { * Class: org_rocksdb_RocksDB
rocksdb::RocksDBJni::setHandle(env, jdb, db); * Method: open
jclass jListClazz = env->FindClass("java/util/ArrayList"); * Signature: (JLjava/lang/String;[[B[J)[J
jmethodID midList = rocksdb::ListJni::getArrayListConstructorMethodId( */
env, jListClazz); jlongArray Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J(
jobject jcfhandle_list = env->NewObject(jListClazz, JNIEnv* env, jclass jcls, jlong jopt_handle, jstring jdb_path,
midList, handles.size()); jobjectArray jcolumn_names, jlongArray jcolumn_options) {
// insert in java list return rocksdb_open_helper(env, jopt_handle, jdb_path, jcolumn_names,
for (std::vector<rocksdb::ColumnFamilyHandle*>::size_type i = 0; jcolumn_options, (rocksdb::Status(*)
i != handles.size(); i++) { (const rocksdb::DBOptions&, const std::string&,
// jlong must be converted to Long due to collections restrictions const std::vector<rocksdb::ColumnFamilyDescriptor>&,
jclass jLongClazz = env->FindClass("java/lang/Long"); std::vector<rocksdb::ColumnFamilyHandle*>*, rocksdb::DB**)
jmethodID midLong = env->GetMethodID(jLongClazz, "<init>", "(J)V"); )&rocksdb::DB::Open
jobject obj = env->NewObject(jLongClazz, midLong, );
reinterpret_cast<jlong>(handles[i]));
env->CallBooleanMethod(jcfhandle_list,
rocksdb::ListJni::getListAddMethodId(env), obj);
}
return jcfhandle_list;
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return nullptr;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -245,25 +171,21 @@ jobject Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2Ljava_util_List_2I(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: listColumnFamilies * Method: listColumnFamilies
* Signature: (JLjava/lang/String;)Ljava/util/List; * Signature: (JLjava/lang/String;)[[B
*/ */
jobject Java_org_rocksdb_RocksDB_listColumnFamilies( jobjectArray Java_org_rocksdb_RocksDB_listColumnFamilies(
JNIEnv* env, jclass jclazz, jlong jopt_handle, jstring jdb_path) { JNIEnv* env, jclass jclazz, jlong jopt_handle, jstring jdb_path) {
std::vector<std::string> column_family_names; std::vector<std::string> column_family_names;
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
const char* db_path = env->GetStringUTFChars(jdb_path, 0); const char* db_path = env->GetStringUTFChars(jdb_path, 0);
jobject jvalue_list = nullptr;
rocksdb::Status s = rocksdb::DB::ListColumnFamilies(*opt, db_path, rocksdb::Status s = rocksdb::DB::ListColumnFamilies(*opt, db_path,
&column_family_names); &column_family_names);
env->ReleaseStringUTFChars(jdb_path, db_path); env->ReleaseStringUTFChars(jdb_path, db_path);
if (s.ok()) {
// Don't reuse class pointer
jclass jListClazz = env->FindClass("java/util/ArrayList");
jmethodID mid = rocksdb::ListJni::getArrayListConstructorMethodId(env,
jListClazz);
jvalue_list = env->NewObject(jListClazz, mid, column_family_names.size());
jclass jcls_ba = env->FindClass("[B");
jobjectArray jresults = env->NewObjectArray(
static_cast<jsize>(column_family_names.size()), jcls_ba, NULL);
if (s.ok()) {
for (std::vector<std::string>::size_type i = 0; for (std::vector<std::string>::size_type i = 0;
i < column_family_names.size(); i++) { i < column_family_names.size(); i++) {
jbyteArray jcf_value = jbyteArray jcf_value =
@ -271,11 +193,11 @@ jobject Java_org_rocksdb_RocksDB_listColumnFamilies(
env->SetByteArrayRegion( env->SetByteArrayRegion(
jcf_value, 0, static_cast<jsize>(column_family_names[i].size()), jcf_value, 0, static_cast<jsize>(column_family_names[i].size()),
reinterpret_cast<const jbyte*>(column_family_names[i].data())); reinterpret_cast<const jbyte*>(column_family_names[i].data()));
env->CallBooleanMethod(jvalue_list, env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jcf_value);
rocksdb::ListJni::getListAddMethodId(env), jcf_value); env->DeleteLocalRef(jcf_value);
} }
} }
return jvalue_list; return jresults;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -398,12 +320,12 @@ void Java_org_rocksdb_RocksDB_put__JJ_3BI_3BIJ(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: write0 * Method: write0
* Signature: (JJ)V * Signature: (JJJ)V
*/ */
void Java_org_rocksdb_RocksDB_write0( void Java_org_rocksdb_RocksDB_write0(
JNIEnv* env, jobject jdb, JNIEnv* env, jobject jdb, jlong jdb_handle,
jlong jwrite_options_handle, jlong jwb_handle) { jlong jwrite_options_handle, jlong jwb_handle) {
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto* write_options = reinterpret_cast<rocksdb::WriteOptions*>( auto* write_options = reinterpret_cast<rocksdb::WriteOptions*>(
jwrite_options_handle); jwrite_options_handle);
auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
@ -418,12 +340,12 @@ void Java_org_rocksdb_RocksDB_write0(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: write1 * Method: write1
* Signature: (JJ)V * Signature: (JJJ)V
*/ */
void Java_org_rocksdb_RocksDB_write1( void Java_org_rocksdb_RocksDB_write1(
JNIEnv* env, jobject jdb, JNIEnv* env, jobject jdb, jlong jdb_handle,
jlong jwrite_options_handle, jlong jwbwi_handle) { jlong jwrite_options_handle, jlong jwbwi_handle) {
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto* write_options = reinterpret_cast<rocksdb::WriteOptions*>( auto* write_options = reinterpret_cast<rocksdb::WriteOptions*>(
jwrite_options_handle); jwrite_options_handle);
auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle); auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
@ -470,12 +392,12 @@ jboolean key_may_exist_helper(JNIEnv* env, rocksdb::DB* db,
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: keyMayExist * Method: keyMayExist
* Signature: ([BILjava/lang/StringBuffer;)Z * Signature: (J[BILjava/lang/StringBuffer;)Z
*/ */
jboolean Java_org_rocksdb_RocksDB_keyMayExist___3BILjava_lang_StringBuffer_2( jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BILjava_lang_StringBuffer_2(
JNIEnv* env, jobject jdb, jbyteArray jkey, jint jkey_len, JNIEnv* env, jobject jdb, jlong jdb_handle, jbyteArray jkey, jint jkey_len,
jobject jstring_buffer) { jobject jstring_buffer) {
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
return key_may_exist_helper(env, db, rocksdb::ReadOptions(), return key_may_exist_helper(env, db, rocksdb::ReadOptions(),
nullptr, jkey, jkey_len, jstring_buffer); nullptr, jkey, jkey_len, jstring_buffer);
} }
@ -483,13 +405,13 @@ jboolean Java_org_rocksdb_RocksDB_keyMayExist___3BILjava_lang_StringBuffer_2(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: keyMayExist * Method: keyMayExist
* Signature: ([BIJLjava/lang/StringBuffer;)Z * Signature: (J[BIJLjava/lang/StringBuffer;)Z
*/ */
jboolean Java_org_rocksdb_RocksDB_keyMayExist___3BIJLjava_lang_StringBuffer_2( jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BIJLjava_lang_StringBuffer_2(
JNIEnv* env, jobject jdb, jbyteArray jkey, jint jkey_len, JNIEnv* env, jobject jdb, jlong jdb_handle, jbyteArray jkey, jint jkey_len,
jlong jcf_handle, jobject jstring_buffer) { jlong jcf_handle, jobject jstring_buffer) {
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>( auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(
jcf_handle); jcf_handle);
if (cf_handle != nullptr) { if (cf_handle != nullptr) {
return key_may_exist_helper(env, db, rocksdb::ReadOptions(), return key_may_exist_helper(env, db, rocksdb::ReadOptions(),
@ -497,19 +419,19 @@ jboolean Java_org_rocksdb_RocksDB_keyMayExist___3BIJLjava_lang_StringBuffer_2(
} else { } else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::RocksDBExceptionJni::ThrowNew(env,
rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
}
return true; return true;
} }
}
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: keyMayExist * Method: keyMayExist
* Signature: (J[BILjava/lang/StringBuffer;)Z * Signature: (JJ[BILjava/lang/StringBuffer;)Z
*/ */
jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BILjava_lang_StringBuffer_2( jboolean Java_org_rocksdb_RocksDB_keyMayExist__JJ_3BILjava_lang_StringBuffer_2(
JNIEnv* env, jobject jdb, jlong jread_options_handle, JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jread_options_handle,
jbyteArray jkey, jint jkey_len, jobject jstring_buffer) { jbyteArray jkey, jint jkey_len, jobject jstring_buffer) {
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto& read_options = *reinterpret_cast<rocksdb::ReadOptions*>( auto& read_options = *reinterpret_cast<rocksdb::ReadOptions*>(
jread_options_handle); jread_options_handle);
return key_may_exist_helper(env, db, read_options, return key_may_exist_helper(env, db, read_options,
@ -519,15 +441,15 @@ jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BILjava_lang_StringBuffer_2(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: keyMayExist * Method: keyMayExist
* Signature: (J[BIJLjava/lang/StringBuffer;)Z * Signature: (JJ[BIJLjava/lang/StringBuffer;)Z
*/ */
jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BIJLjava_lang_StringBuffer_2( jboolean Java_org_rocksdb_RocksDB_keyMayExist__JJ_3BIJLjava_lang_StringBuffer_2(
JNIEnv* env, jobject jdb, jlong jread_options_handle, JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jread_options_handle,
jbyteArray jkey, jint jkey_len, jlong jcf_handle, jobject jstring_buffer) { jbyteArray jkey, jint jkey_len, jlong jcf_handle, jobject jstring_buffer) {
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb); auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
auto& read_options = *reinterpret_cast<rocksdb::ReadOptions*>( auto& read_options = *reinterpret_cast<rocksdb::ReadOptions*>(
jread_options_handle); jread_options_handle);
auto cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>( auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(
jcf_handle); jcf_handle);
if (cf_handle != nullptr) { if (cf_handle != nullptr) {
return key_may_exist_helper(env, db, read_options, cf_handle, return key_may_exist_helper(env, db, read_options, cf_handle,
@ -535,9 +457,9 @@ jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BIJLjava_lang_StringBuffer_2(
} else { } else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::RocksDBExceptionJni::ThrowNew(env,
rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
}
return true; return true;
} }
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// rocksdb::DB::Get // rocksdb::DB::Get
@ -703,49 +625,38 @@ jint rocksdb_get_helper(
} }
// cf multi get // cf multi get
jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db, jobjectArray multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db,
const rocksdb::ReadOptions& rOpt, jobject jkey_list, jint jkeys_count, const rocksdb::ReadOptions& rOpt, jobjectArray jkeys,
jobject jcfhandle_list) { jlongArray jcolumn_family_handles) {
std::vector<rocksdb::Slice> keys;
std::vector<jbyte*> keys_to_free;
std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
if (jcolumn_family_handles != nullptr) {
if (jcfhandle_list != nullptr) { jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
// get cf iterator jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, NULL);
jobject cfIteratorObj = env->CallObjectMethod( for (int i = 0; i < len_cols; i++) {
jcfhandle_list, rocksdb::ListJni::getIteratorMethod(env)); auto* cf_handle =
reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]);
// iterate over keys and convert java byte array to slice cf_handles.push_back(cf_handle);
while (env->CallBooleanMethod(
cfIteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
jobject jobj = (jbyteArray) env->CallObjectMethod(
cfIteratorObj, rocksdb::ListJni::getNextMethod(env));
rocksdb::ColumnFamilyHandle* cfHandle =
rocksdb::ColumnFamilyHandleJni::getHandle(env, jobj);
cf_handles.push_back(cfHandle);
} }
env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
} }
// Process key list std::vector<rocksdb::Slice> keys;
// get iterator std::vector<std::tuple<jbyteArray, jbyte*, jobject>> keys_to_free;
jobject iteratorObj = env->CallObjectMethod( jsize len_keys = env->GetArrayLength(jkeys);
jkey_list, rocksdb::ListJni::getIteratorMethod(env)); if(env->EnsureLocalCapacity(len_keys) != 0) {
// out of memory
// iterate over keys and convert java byte array to slice return NULL;
while (env->CallBooleanMethod( }
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) { for (int i = 0; i < len_keys; i++) {
jbyteArray jkey = (jbyteArray) env->CallObjectMethod( jobject jk = env->GetObjectArrayElement(jkeys, i);
iteratorObj, rocksdb::ListJni::getNextMethod(env)); jbyteArray jk_ba = reinterpret_cast<jbyteArray>(jk);
jint key_length = env->GetArrayLength(jkey); jsize len_key = env->GetArrayLength(jk_ba);
jbyte* jk_val = env->GetByteArrayElements(jk_ba, NULL);
jbyte* key = new jbyte[key_length];
env->GetByteArrayRegion(jkey, 0, key_length, key); rocksdb::Slice key_slice(reinterpret_cast<char*>(jk_val), len_key);
// store allocated jbyte to free it after multiGet call
keys_to_free.push_back(key);
rocksdb::Slice key_slice(
reinterpret_cast<char*>(key), key_length);
keys.push_back(key_slice); keys.push_back(key_slice);
keys_to_free.push_back(std::make_tuple(jk_ba, jk_val, jk));
} }
std::vector<std::string> values; std::vector<std::string> values;
@ -756,13 +667,23 @@ jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db,
s = db->MultiGet(rOpt, cf_handles, keys, &values); s = db->MultiGet(rOpt, cf_handles, keys, &values);
} }
// Don't reuse class pointer // free up allocated byte arrays
jclass jclazz = env->FindClass("java/util/ArrayList"); for (std::vector<std::tuple<jbyteArray, jbyte*, jobject>>::size_type i = 0;
jmethodID mid = rocksdb::ListJni::getArrayListConstructorMethodId( i < keys_to_free.size(); i++) {
env, jclazz); jobject jk;
jobject jvalue_list = env->NewObject(jclazz, mid, jkeys_count); jbyteArray jk_ba;
jbyte* jk_val;
// insert in java list std::tie(jk_ba, jk_val, jk) = keys_to_free[i];
env->ReleaseByteArrayElements(jk_ba, jk_val, JNI_ABORT);
env->DeleteLocalRef(jk);
}
// prepare the results
jclass jcls_ba = env->FindClass("[B");
jobjectArray jresults =
env->NewObjectArray(static_cast<jsize>(s.size()), jcls_ba, NULL);
// add to the jresults
for (std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) { for (std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) {
if (s[i].ok()) { if (s[i].ok()) {
jbyteArray jentry_value = jbyteArray jentry_value =
@ -770,73 +691,60 @@ jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db,
env->SetByteArrayRegion( env->SetByteArrayRegion(
jentry_value, 0, static_cast<jsize>(values[i].size()), jentry_value, 0, static_cast<jsize>(values[i].size()),
reinterpret_cast<const jbyte*>(values[i].c_str())); reinterpret_cast<const jbyte*>(values[i].c_str()));
env->CallBooleanMethod( env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jentry_value);
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), env->DeleteLocalRef(jentry_value);
jentry_value);
} else {
env->CallBooleanMethod(
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), nullptr);
}
} }
// free up allocated byte arrays
for (std::vector<jbyte*>::size_type i = 0; i != keys_to_free.size(); i++) {
delete[] keys_to_free[i];
} }
keys_to_free.clear();
return jvalue_list; return jresults;
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: multiGet * Method: multiGet
* Signature: (JLjava/util/List;I)Ljava/util/List; * Signature: (J[[B)[[B
*/ */
jobject Java_org_rocksdb_RocksDB_multiGet__JLjava_util_List_2I( jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B(
JNIEnv* env, jobject jdb, jlong jdb_handle, JNIEnv* env, jobject jdb, jlong jdb_handle, jobjectArray jkeys) {
jobject jkey_list, jint jkeys_count) {
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
rocksdb::ReadOptions(), jkey_list, jkeys_count, nullptr); rocksdb::ReadOptions(), jkeys, nullptr);
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: multiGet * Method: multiGet
* Signature: (JLjava/util/List;ILjava/util/List;)Ljava/util/List; * Signature: (J[[B[J)[[B
*/ */
jobject jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3J(
Java_org_rocksdb_RocksDB_multiGet__JLjava_util_List_2ILjava_util_List_2( JNIEnv* env, jobject jdb, jlong jdb_handle, jobjectArray jkeys,
JNIEnv* env, jobject jdb, jlong jdb_handle, jlongArray jcolumn_family_handles) {
jobject jkey_list, jint jkeys_count, jobject jcfhandle_list) {
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
rocksdb::ReadOptions(), jkey_list, jkeys_count, jcfhandle_list); rocksdb::ReadOptions(), jkeys, jcolumn_family_handles);
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: multiGet * Method: multiGet
* Signature: (JJLjava/util/List;I)Ljava/util/List; * Signature: (JJ[[B)[[B
*/ */
jobject Java_org_rocksdb_RocksDB_multiGet__JJLjava_util_List_2I( jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B(
JNIEnv* env, jobject jdb, jlong jdb_handle, JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
jlong jropt_handle, jobject jkey_list, jint jkeys_count) { jobjectArray jkeys) {
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
*reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkey_list, *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkeys, nullptr);
jkeys_count, nullptr);
} }
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: multiGet * Method: multiGet
* Signature: (JJLjava/util/List;ILjava/util/List;)Ljava/util/List; * Signature: (JJ[[B[J)[[B
*/ */
jobject jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3J(
Java_org_rocksdb_RocksDB_multiGet__JJLjava_util_List_2ILjava_util_List_2( JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
JNIEnv* env, jobject jdb, jlong jdb_handle, jobjectArray jkeys, jlongArray jcolumn_family_handles) {
jlong jropt_handle, jobject jkey_list, jint jkeys_count,
jobject jcfhandle_list) {
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
*reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkey_list, *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkeys,
jkeys_count, jcfhandle_list); jcolumn_family_handles);
} }
/* /*
@ -1204,47 +1112,42 @@ jlong Java_org_rocksdb_RocksDB_iteratorCF__JJJ(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: iterators * Method: iterators
* Signature: (JLjava/util/List;J)[J * Signature: (J[JJ)[J
*/ */
jlongArray Java_org_rocksdb_RocksDB_iterators( jlongArray Java_org_rocksdb_RocksDB_iterators(
JNIEnv* env, jobject jdb, jlong db_handle, jobject jcfhandle_list, JNIEnv* env, jobject jdb, jlong db_handle,
jlong jread_options_handle) { jlongArray jcolumn_family_handles, jlong jread_options_handle) {
auto db = reinterpret_cast<rocksdb::DB*>(db_handle); auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
auto& read_options = *reinterpret_cast<rocksdb::ReadOptions*>( auto& read_options = *reinterpret_cast<rocksdb::ReadOptions*>(
jread_options_handle); jread_options_handle);
std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
std::vector<rocksdb::Iterator*> iterators; if (jcolumn_family_handles != nullptr) {
jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
if (jcfhandle_list != nullptr) { jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, NULL);
// get cf iterator for (int i = 0; i < len_cols; i++) {
jobject cfIteratorObj = env->CallObjectMethod( auto* cf_handle =
jcfhandle_list, rocksdb::ListJni::getIteratorMethod(env)); reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]);
cf_handles.push_back(cf_handle);
// iterate over keys and convert java byte array to slice
while (env->CallBooleanMethod(
cfIteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
jobject jobj = (jbyteArray) env->CallObjectMethod(
cfIteratorObj, rocksdb::ListJni::getNextMethod(env));
rocksdb::ColumnFamilyHandle* cfHandle =
rocksdb::ColumnFamilyHandleJni::getHandle(env, jobj);
cf_handles.push_back(cfHandle);
} }
env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
} }
std::vector<rocksdb::Iterator*> iterators;
rocksdb::Status s = db->NewIterators(read_options, rocksdb::Status s = db->NewIterators(read_options,
cf_handles, &iterators); cf_handles, &iterators);
if (s.ok()) { if (s.ok()) {
jlongArray jLongArray = jlongArray jLongArray =
env->NewLongArray(static_cast<jsize>(iterators.size())); env->NewLongArray(static_cast<jsize>(iterators.size()));
for (std::vector<rocksdb::Iterator*>::size_type i = 0; i < iterators.size(); for (std::vector<rocksdb::Iterator*>::size_type i = 0;
i++) { i < iterators.size(); i++) {
env->SetLongArrayRegion(jLongArray, static_cast<jsize>(i), 1, env->SetLongArrayRegion(jLongArray, static_cast<jsize>(i), 1,
reinterpret_cast<const jlong*>(&iterators[i])); reinterpret_cast<const jlong*>(&iterators[i]));
} }
return jLongArray; return jLongArray;
} } else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s); rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return env->NewLongArray(0); return NULL;
}
} }
/* /*
@ -1262,32 +1165,23 @@ jlong Java_org_rocksdb_RocksDB_getDefaultColumnFamily(
/* /*
* Class: org_rocksdb_RocksDB * Class: org_rocksdb_RocksDB
* Method: createColumnFamily * Method: createColumnFamily
* Signature: (JLorg/rocksdb/ColumnFamilyDescriptor;)J; * Signature: (J[BJ)J
*/ */
jlong Java_org_rocksdb_RocksDB_createColumnFamily( jlong Java_org_rocksdb_RocksDB_createColumnFamily(
JNIEnv* env, jobject jdb, jlong jdb_handle, JNIEnv* env, jobject jdb, jlong jdb_handle,
jobject jcf_descriptor) { jbyteArray jcolumn_name, jlong jcolumn_options) {
rocksdb::ColumnFamilyHandle* handle; rocksdb::ColumnFamilyHandle* handle;
auto db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); auto db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
// get ColumnFamilyName jbyte* cfname = env->GetByteArrayElements(jcolumn_name, 0);
jbyteArray byteArray = static_cast<jbyteArray>(env->CallObjectMethod( const int len = env->GetArrayLength(jcolumn_name);
jcf_descriptor,
rocksdb::ColumnFamilyDescriptorJni::getColumnFamilyNameMethod( auto* cfOptions =
env))); reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcolumn_options);
// 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);
rocksdb::Status s = db_handle->CreateColumnFamily( rocksdb::Status s = db_handle->CreateColumnFamily(
*cfOptions, std::string(reinterpret_cast<char *>(cfname), len), &handle); *cfOptions, std::string(reinterpret_cast<char *>(cfname), len), &handle);
env->ReleaseByteArrayElements(byteArray, cfname, 0); env->ReleaseByteArrayElements(jcolumn_name, cfname, 0);
if (s.ok()) { if (s.ok()) {
return reinterpret_cast<jlong>(handle); return reinterpret_cast<jlong>(handle);

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

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

@ -27,23 +27,23 @@
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: newWriteBatch * Method: newWriteBatch
* Signature: (I)V * Signature: (I)J
*/ */
void Java_org_rocksdb_WriteBatch_newWriteBatch( jlong Java_org_rocksdb_WriteBatch_newWriteBatch(
JNIEnv* env, jobject jobj, jint jreserved_bytes) { JNIEnv* env, jclass jcls, jint jreserved_bytes) {
rocksdb::WriteBatch* wb = new rocksdb::WriteBatch( rocksdb::WriteBatch* wb = new rocksdb::WriteBatch(
static_cast<size_t>(jreserved_bytes)); static_cast<size_t>(jreserved_bytes));
return reinterpret_cast<jlong>(wb);
rocksdb::WriteBatchJni::setHandle(env, jobj, wb);
} }
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: count0 * Method: count0
* Signature: ()I * Signature: (J)I
*/ */
jint Java_org_rocksdb_WriteBatch_count0(JNIEnv* env, jobject jobj) { jint Java_org_rocksdb_WriteBatch_count0(JNIEnv* env, jobject jobj,
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); jlong jwb_handle) {
auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
return static_cast<jint>(wb->Count()); return static_cast<jint>(wb->Count());
@ -52,10 +52,11 @@ jint Java_org_rocksdb_WriteBatch_count0(JNIEnv* env, jobject jobj) {
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: clear0 * Method: clear0
* Signature: ()V * Signature: (J)V
*/ */
void Java_org_rocksdb_WriteBatch_clear0(JNIEnv* env, jobject jobj) { void Java_org_rocksdb_WriteBatch_clear0(JNIEnv* env, jobject jobj,
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); jlong jwb_handle) {
auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
wb->Clear(); wb->Clear();
@ -64,13 +65,13 @@ void Java_org_rocksdb_WriteBatch_clear0(JNIEnv* env, jobject jobj) {
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: put * Method: put
* Signature: ([BI[BI)V * Signature: (J[BI[BI)V
*/ */
void Java_org_rocksdb_WriteBatch_put___3BI_3BI( void Java_org_rocksdb_WriteBatch_put__J_3BI_3BI(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwb_handle,
jbyteArray jkey, jint jkey_len, jbyteArray jkey, jint jkey_len,
jbyteArray jentry_value, jint jentry_value_len) { jbyteArray jentry_value, jint jentry_value_len) {
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto put = [&wb] (rocksdb::Slice key, rocksdb::Slice value) { auto put = [&wb] (rocksdb::Slice key, rocksdb::Slice value) {
wb->Put(key, value); wb->Put(key, value);
@ -82,13 +83,13 @@ void Java_org_rocksdb_WriteBatch_put___3BI_3BI(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: put * Method: put
* Signature: ([BI[BIJ)V * Signature: (J[BI[BIJ)V
*/ */
void Java_org_rocksdb_WriteBatch_put___3BI_3BIJ( void Java_org_rocksdb_WriteBatch_put__J_3BI_3BIJ(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwb_handle,
jbyteArray jkey, jint jkey_len, jbyteArray jkey, jint jkey_len,
jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) { jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) {
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
assert(cf_handle != nullptr); assert(cf_handle != nullptr);
@ -102,13 +103,13 @@ void Java_org_rocksdb_WriteBatch_put___3BI_3BIJ(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: merge * Method: merge
* Signature: ([BI[BI)V * Signature: (J[BI[BI)V
*/ */
void Java_org_rocksdb_WriteBatch_merge___3BI_3BI( void Java_org_rocksdb_WriteBatch_merge__J_3BI_3BI(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwb_handle,
jbyteArray jkey, jint jkey_len, jbyteArray jkey, jint jkey_len,
jbyteArray jentry_value, jint jentry_value_len) { jbyteArray jentry_value, jint jentry_value_len) {
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto merge = [&wb] (rocksdb::Slice key, rocksdb::Slice value) { auto merge = [&wb] (rocksdb::Slice key, rocksdb::Slice value) {
wb->Merge(key, value); wb->Merge(key, value);
@ -120,13 +121,13 @@ void Java_org_rocksdb_WriteBatch_merge___3BI_3BI(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: merge * Method: merge
* Signature: ([BI[BIJ)V * Signature: (J[BI[BIJ)V
*/ */
void Java_org_rocksdb_WriteBatch_merge___3BI_3BIJ( void Java_org_rocksdb_WriteBatch_merge__J_3BI_3BIJ(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwb_handle,
jbyteArray jkey, jint jkey_len, jbyteArray jkey, jint jkey_len,
jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) { jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) {
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
assert(cf_handle != nullptr); assert(cf_handle != nullptr);
@ -140,12 +141,12 @@ void Java_org_rocksdb_WriteBatch_merge___3BI_3BIJ(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: remove * Method: remove
* Signature: ([BI)V * Signature: (J[BI)V
*/ */
void Java_org_rocksdb_WriteBatch_remove___3BI( void Java_org_rocksdb_WriteBatch_remove__J_3BI(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwb_handle,
jbyteArray jkey, jint jkey_len) { jbyteArray jkey, jint jkey_len) {
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto remove = [&wb] (rocksdb::Slice key) { auto remove = [&wb] (rocksdb::Slice key) {
wb->Delete(key); wb->Delete(key);
@ -156,12 +157,12 @@ void Java_org_rocksdb_WriteBatch_remove___3BI(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: remove * Method: remove
* Signature: ([BIJ)V * Signature: (J[BIJ)V
*/ */
void Java_org_rocksdb_WriteBatch_remove___3BIJ( void Java_org_rocksdb_WriteBatch_remove__J_3BIJ(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwb_handle,
jbyteArray jkey, jint jkey_len, jlong jcf_handle) { jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
assert(cf_handle != nullptr); assert(cf_handle != nullptr);
@ -174,11 +175,12 @@ void Java_org_rocksdb_WriteBatch_remove___3BIJ(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: putLogData * Method: putLogData
* Signature: ([BI)V * Signature: (J[BI)V
*/ */
void Java_org_rocksdb_WriteBatch_putLogData( void Java_org_rocksdb_WriteBatch_putLogData(
JNIEnv* env, jobject jobj, jbyteArray jblob, jint jblob_len) { JNIEnv* env, jobject jobj, jlong jwb_handle, jbyteArray jblob,
auto* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); jint jblob_len) {
auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
auto putLogData = [&wb] (rocksdb::Slice blob) { auto putLogData = [&wb] (rocksdb::Slice blob) {
wb->PutLogData(blob); wb->PutLogData(blob);
@ -189,11 +191,11 @@ void Java_org_rocksdb_WriteBatch_putLogData(
/* /*
* Class: org_rocksdb_WriteBatch * Class: org_rocksdb_WriteBatch
* Method: iterate * Method: iterate
* Signature: (J)V * Signature: (JJ)V
*/ */
void Java_org_rocksdb_WriteBatch_iterate( void Java_org_rocksdb_WriteBatch_iterate(
JNIEnv* env , jobject jobj, jlong handlerHandle) { JNIEnv* env , jobject jobj, jlong jwb_handle, jlong handlerHandle) {
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
rocksdb::Status s = wb->Iterate( rocksdb::Status s = wb->Iterate(
@ -218,13 +220,13 @@ void Java_org_rocksdb_WriteBatch_disposeInternal(
/* /*
* Class: org_rocksdb_WriteBatch_Handler * Class: org_rocksdb_WriteBatch_Handler
* Method: createNewHandler0 * Method: createNewHandler0
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0( jlong Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0(
JNIEnv* env, jobject jobj) { JNIEnv* env, jobject jobj) {
const rocksdb::WriteBatchHandlerJniCallback* h = const rocksdb::WriteBatchHandlerJniCallback* h =
new rocksdb::WriteBatchHandlerJniCallback(env, jobj); new rocksdb::WriteBatchHandlerJniCallback(env, jobj);
rocksdb::WriteBatchHandlerJni::setHandle(env, jobj, h); return reinterpret_cast<jlong>(h);
} }
/* /*

@ -28,11 +28,11 @@
/* /*
* Class: org_rocksdb_WriteBatchTest * Class: org_rocksdb_WriteBatchTest
* Method: getContents * Method: getContents
* Signature: (Lorg/rocksdb/WriteBatch;)[B * Signature: (J)[B
*/ */
jbyteArray Java_org_rocksdb_WriteBatchTest_getContents( jbyteArray Java_org_rocksdb_WriteBatchTest_getContents(
JNIEnv* env, jclass jclazz, jobject jobj) { JNIEnv* env, jclass jclazz, jlong jwb_handle) {
rocksdb::WriteBatch* b = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* b = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(b != nullptr); assert(b != nullptr);
// todo: Currently the following code is directly copied from // todo: Currently the following code is directly copied from
@ -109,11 +109,11 @@ jbyteArray Java_org_rocksdb_WriteBatchTest_getContents(
/* /*
* Class: org_rocksdb_WriteBatchTestInternalHelper * Class: org_rocksdb_WriteBatchTestInternalHelper
* Method: setSequence * Method: setSequence
* Signature: (Lorg/rocksdb/WriteBatch;J)V * Signature: (JJ)V
*/ */
void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence( void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence(
JNIEnv* env, jclass jclazz, jobject jobj, jlong jsn) { JNIEnv* env, jclass jclazz, jlong jwb_handle, jlong jsn) {
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
rocksdb::WriteBatchInternal::SetSequence( rocksdb::WriteBatchInternal::SetSequence(
@ -123,11 +123,11 @@ void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence(
/* /*
* Class: org_rocksdb_WriteBatchTestInternalHelper * Class: org_rocksdb_WriteBatchTestInternalHelper
* Method: sequence * Method: sequence
* Signature: (Lorg/rocksdb/WriteBatch;)J * Signature: (J)J
*/ */
jlong Java_org_rocksdb_WriteBatchTestInternalHelper_sequence( jlong Java_org_rocksdb_WriteBatchTestInternalHelper_sequence(
JNIEnv* env, jclass jclazz, jobject jobj) { JNIEnv* env, jclass jclazz, jlong jwb_handle) {
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj); auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
assert(wb != nullptr); assert(wb != nullptr);
return static_cast<jlong>(rocksdb::WriteBatchInternal::Sequence(wb)); return static_cast<jlong>(rocksdb::WriteBatchInternal::Sequence(wb));
@ -136,13 +136,13 @@ jlong Java_org_rocksdb_WriteBatchTestInternalHelper_sequence(
/* /*
* Class: org_rocksdb_WriteBatchTestInternalHelper * Class: org_rocksdb_WriteBatchTestInternalHelper
* Method: append * Method: append
* Signature: (Lorg/rocksdb/WriteBatch;Lorg/rocksdb/WriteBatch;)V * Signature: (JJ)V
*/ */
void Java_org_rocksdb_WriteBatchTestInternalHelper_append( void Java_org_rocksdb_WriteBatchTestInternalHelper_append(
JNIEnv* env, jclass jclazz, jobject jwb1, jobject jwb2) { JNIEnv* env, jclass jclazz, jlong jwb_handle_1, jlong jwb_handle_2) {
rocksdb::WriteBatch* wb1 = rocksdb::WriteBatchJni::getHandle(env, jwb1); auto* wb1 = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle_1);
assert(wb1 != nullptr); assert(wb1 != nullptr);
rocksdb::WriteBatch* wb2 = rocksdb::WriteBatchJni::getHandle(env, jwb2); auto* wb2 = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle_2);
assert(wb2 != nullptr); assert(wb2 != nullptr);
rocksdb::WriteBatchInternal::Append(wb1, wb2); rocksdb::WriteBatchInternal::Append(wb1, wb2);

@ -15,51 +15,50 @@
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: newWriteBatchWithIndex * Method: newWriteBatchWithIndex
* Signature: ()V * Signature: ()J
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__( jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__(
JNIEnv* env, jobject jobj) { JNIEnv* env, jclass jcls) {
rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex(); rocksdb::WriteBatchWithIndex* wbwi = new rocksdb::WriteBatchWithIndex();
rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); return reinterpret_cast<jlong>(wbwi);
} }
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: newWriteBatchWithIndex * Method: newWriteBatchWithIndex
* Signature: (Z)V * Signature: (Z)J
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z( jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z(
JNIEnv* env, jobject jobj, jboolean joverwrite_key) { JNIEnv* env, jclass jcls, jboolean joverwrite_key) {
rocksdb::WriteBatchWithIndex* wbwi = rocksdb::WriteBatchWithIndex* wbwi =
new rocksdb::WriteBatchWithIndex(rocksdb::BytewiseComparator(), 0, new rocksdb::WriteBatchWithIndex(rocksdb::BytewiseComparator(), 0,
static_cast<bool>(joverwrite_key)); static_cast<bool>(joverwrite_key));
rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); return reinterpret_cast<jlong>(wbwi);
} }
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: newWriteBatchWithIndex * Method: newWriteBatchWithIndex
* Signature: (JIZ)V * Signature: (JIZ)J
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ( jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JIZ(
JNIEnv* env, jobject jobj, jlong jfallback_index_comparator_handle, JNIEnv* env, jclass jcls, jlong jfallback_index_comparator_handle,
jint jreserved_bytes, jboolean joverwrite_key) { jint jreserved_bytes, jboolean joverwrite_key) {
rocksdb::WriteBatchWithIndex* wbwi = rocksdb::WriteBatchWithIndex* wbwi =
new rocksdb::WriteBatchWithIndex( new rocksdb::WriteBatchWithIndex(
reinterpret_cast<rocksdb::Comparator*>(jfallback_index_comparator_handle), reinterpret_cast<rocksdb::Comparator*>(jfallback_index_comparator_handle),
static_cast<size_t>(jreserved_bytes), static_cast<bool>(joverwrite_key)); static_cast<size_t>(jreserved_bytes), static_cast<bool>(joverwrite_key));
rocksdb::WriteBatchWithIndexJni::setHandle(env, jobj, wbwi); return reinterpret_cast<jlong>(wbwi);
} }
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: count * Method: count0
* Signature: ()I * Signature: (J)I
*/ */
jint Java_org_rocksdb_WriteBatchWithIndex_count0( jint Java_org_rocksdb_WriteBatchWithIndex_count0(
JNIEnv* env, jobject jobj) { JNIEnv* env, jobject jobj, jlong jwbwi_handle) {
rocksdb::WriteBatchWithIndex* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
assert(wbwi != nullptr); assert(wbwi != nullptr);
return static_cast<jint>(wbwi->GetWriteBatch()->Count()); return static_cast<jint>(wbwi->GetWriteBatch()->Count());
@ -68,13 +67,12 @@ jint Java_org_rocksdb_WriteBatchWithIndex_count0(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: put * Method: put
* Signature: ([BI[BI)V * Signature: (J[BI[BI)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_put___3BI_3BI( void Java_org_rocksdb_WriteBatchWithIndex_put__J_3BI_3BI(
JNIEnv* env, jobject jobj, jbyteArray jkey, jint jkey_len, JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
jbyteArray jentry_value, jint jentry_value_len) { jint jkey_len, jbyteArray jentry_value, jint jentry_value_len) {
auto* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto put = [&wbwi] (rocksdb::Slice key, rocksdb::Slice value) { auto put = [&wbwi] (rocksdb::Slice key, rocksdb::Slice value) {
wbwi->Put(key, value); wbwi->Put(key, value);
@ -86,13 +84,13 @@ void Java_org_rocksdb_WriteBatchWithIndex_put___3BI_3BI(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: put * Method: put
* Signature: ([BI[BIJ)V * Signature: (J[BI[BIJ)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_put___3BI_3BIJ( void Java_org_rocksdb_WriteBatchWithIndex_put__J_3BI_3BIJ(
JNIEnv* env, jobject jobj, jbyteArray jkey, jint jkey_len, JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) { jint jkey_len, jbyteArray jentry_value, jint jentry_value_len,
auto* wbwi = jlong jcf_handle) {
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj); auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
assert(cf_handle != nullptr); assert(cf_handle != nullptr);
@ -106,13 +104,12 @@ void Java_org_rocksdb_WriteBatchWithIndex_put___3BI_3BIJ(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: merge * Method: merge
* Signature: ([BI[BI)V * Signature: (J[BI[BI)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_merge___3BI_3BI( void Java_org_rocksdb_WriteBatchWithIndex_merge__J_3BI_3BI(
JNIEnv* env, jobject jobj, jbyteArray jkey, jint jkey_len, JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
jbyteArray jentry_value, jint jentry_value_len) { jint jkey_len, jbyteArray jentry_value, jint jentry_value_len) {
auto* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto merge = [&wbwi] (rocksdb::Slice key, rocksdb::Slice value) { auto merge = [&wbwi] (rocksdb::Slice key, rocksdb::Slice value) {
wbwi->Merge(key, value); wbwi->Merge(key, value);
@ -124,13 +121,13 @@ void Java_org_rocksdb_WriteBatchWithIndex_merge___3BI_3BI(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: merge * Method: merge
* Signature: ([BI[BIJ)V * Signature: (J[BI[BIJ)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_merge___3BI_3BIJ( void Java_org_rocksdb_WriteBatchWithIndex_merge__J_3BI_3BIJ(
JNIEnv* env, jobject jobj, jbyteArray jkey, jint jkey_len, JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) { jint jkey_len, jbyteArray jentry_value, jint jentry_value_len,
auto* wbwi = jlong jcf_handle) {
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj); auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
assert(cf_handle != nullptr); assert(cf_handle != nullptr);
@ -144,12 +141,12 @@ void Java_org_rocksdb_WriteBatchWithIndex_merge___3BI_3BIJ(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: remove * Method: remove
* Signature: ([BI)V * Signature: (J[BI)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_remove___3BI( void Java_org_rocksdb_WriteBatchWithIndex_remove__J_3BI(
JNIEnv* env, jobject jobj, jbyteArray jkey, jint jkey_len) { JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
auto* wbwi = jint jkey_len) {
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj); auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto remove = [&wbwi] (rocksdb::Slice key) { auto remove = [&wbwi] (rocksdb::Slice key) {
wbwi->Delete(key); wbwi->Delete(key);
@ -160,13 +157,12 @@ void Java_org_rocksdb_WriteBatchWithIndex_remove___3BI(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: remove * Method: remove
* Signature: ([BIJ)V * Signature: (J[BIJ)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_remove___3BIJ( void Java_org_rocksdb_WriteBatchWithIndex_remove__J_3BIJ(
JNIEnv* env, jobject jobj, JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
jbyteArray jkey, jint jkey_len, jlong jcf_handle) { jint jkey_len, jlong jcf_handle) {
auto* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
assert(cf_handle != nullptr); assert(cf_handle != nullptr);
@ -179,12 +175,12 @@ void Java_org_rocksdb_WriteBatchWithIndex_remove___3BIJ(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: putLogData * Method: putLogData
* Signature: ([BI)V * Signature: (J[BI)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_putLogData( void Java_org_rocksdb_WriteBatchWithIndex_putLogData(
JNIEnv* env, jobject jobj, jbyteArray jblob, jint jblob_len) { JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jblob,
auto* wbwi = jint jblob_len) {
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj); auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
assert(wbwi != nullptr); assert(wbwi != nullptr);
auto putLogData = [&wbwi] (rocksdb::Slice blob) { auto putLogData = [&wbwi] (rocksdb::Slice blob) {
wbwi->PutLogData(blob); wbwi->PutLogData(blob);
@ -195,12 +191,11 @@ void Java_org_rocksdb_WriteBatchWithIndex_putLogData(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: clear * Method: clear
* Signature: ()V * Signature: (J)V
*/ */
void Java_org_rocksdb_WriteBatchWithIndex_clear0( void Java_org_rocksdb_WriteBatchWithIndex_clear0(
JNIEnv* env, jobject jobj) { JNIEnv* env, jobject jobj, jlong jwbwi_handle) {
rocksdb::WriteBatchWithIndex* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
assert(wbwi != nullptr); assert(wbwi != nullptr);
wbwi->GetWriteBatch()->Clear(); wbwi->GetWriteBatch()->Clear();
@ -209,12 +204,11 @@ void Java_org_rocksdb_WriteBatchWithIndex_clear0(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: iterator0 * Method: iterator0
* Signature: ()J * Signature: (J)J
*/ */
jlong Java_org_rocksdb_WriteBatchWithIndex_iterator0( jlong Java_org_rocksdb_WriteBatchWithIndex_iterator0(
JNIEnv* env, jobject jobj) { JNIEnv* env, jobject jobj, jlong jwbwi_handle) {
rocksdb::WriteBatchWithIndex* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
rocksdb::WBWIIterator* wbwi_iterator = wbwi->NewIterator(); rocksdb::WBWIIterator* wbwi_iterator = wbwi->NewIterator();
return reinterpret_cast<jlong>(wbwi_iterator); return reinterpret_cast<jlong>(wbwi_iterator);
} }
@ -222,12 +216,11 @@ jlong Java_org_rocksdb_WriteBatchWithIndex_iterator0(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: iterator1 * Method: iterator1
* Signature: (J)J * Signature: (JJ)J
*/ */
jlong Java_org_rocksdb_WriteBatchWithIndex_iterator1( jlong Java_org_rocksdb_WriteBatchWithIndex_iterator1(
JNIEnv* env, jobject jobj, jlong jcf_handle) { JNIEnv* env, jobject jobj, jlong jwbwi_handle, jlong jcf_handle) {
rocksdb::WriteBatchWithIndex* wbwi = auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
rocksdb::WBWIIterator* wbwi_iterator = wbwi->NewIterator(cf_handle); rocksdb::WBWIIterator* wbwi_iterator = wbwi->NewIterator(cf_handle);
return reinterpret_cast<jlong>(wbwi_iterator); return reinterpret_cast<jlong>(wbwi_iterator);
@ -236,12 +229,12 @@ jlong Java_org_rocksdb_WriteBatchWithIndex_iterator1(
/* /*
* Class: org_rocksdb_WriteBatchWithIndex * Class: org_rocksdb_WriteBatchWithIndex
* Method: iteratorWithBase * Method: iteratorWithBase
* Signature: (JJ)J * Signature: (JJJ)J
*/ */
jlong Java_org_rocksdb_WriteBatchWithIndex_iteratorWithBase( jlong Java_org_rocksdb_WriteBatchWithIndex_iteratorWithBase(
JNIEnv* env, jobject jobj, jlong jcf_handle, jlong jbi_handle) { JNIEnv* env, jobject jobj, jlong jwbwi_handle, jlong jcf_handle,
rocksdb::WriteBatchWithIndex* wbwi = jlong jbi_handle) {
rocksdb::WriteBatchWithIndexJni::getHandle(env, jobj); auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
auto* base_iterator = reinterpret_cast<rocksdb::Iterator*>(jbi_handle); auto* base_iterator = reinterpret_cast<rocksdb::Iterator*>(jbi_handle);
auto* iterator = wbwi->NewIteratorWithBase(cf_handle, base_iterator); auto* iterator = wbwi->NewIteratorWithBase(cf_handle, base_iterator);
@ -360,27 +353,57 @@ void Java_org_rocksdb_WBWIRocksIterator_status0(
/* /*
* Class: org_rocksdb_WBWIRocksIterator * Class: org_rocksdb_WBWIRocksIterator
* Method: entry1 * Method: entry1
* Signature: (JLorg/rocksdb/WBWIRocksIterator/WriteEntry;)V * Signature: (J)[J
*/ */
void Java_org_rocksdb_WBWIRocksIterator_entry1( jlongArray Java_org_rocksdb_WBWIRocksIterator_entry1(
JNIEnv* env, jobject jobj, jlong handle, jobject jwrite_entry) { JNIEnv* env, jobject jobj, jlong handle) {
auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle); auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
const rocksdb::WriteEntry& we = it->Entry(); const rocksdb::WriteEntry& we = it->Entry();
jobject jwe = rocksdb::WBWIRocksIteratorJni::getWriteEntry(env, jobj);
rocksdb::WriteEntryJni::setWriteType(env, jwe, we.type);
jlong results[3];
//set the type of the write entry
switch (we.type) {
case rocksdb::kPutRecord:
results[0] = 0x1;
break;
case rocksdb::kMergeRecord:
results[0] = 0x2;
break;
case rocksdb::kDeleteRecord:
results[0] = 0x4;
break;
case rocksdb::kLogDataRecord:
results[0] = 0x8;
break;
default:
results[0] = 0x0;
}
//TODO(AR) do we leak buf and value_buf?
//set the pointer to the key slice
char* buf = new char[we.key.size()]; char* buf = new char[we.key.size()];
memcpy(buf, we.key.data(), we.key.size()); memcpy(buf, we.key.data(), we.key.size());
auto* key_slice = new rocksdb::Slice(buf, we.key.size()); auto* key_slice = new rocksdb::Slice(buf, we.key.size());
rocksdb::WriteEntryJni::setKey(env, jwe, key_slice); results[1] = reinterpret_cast<jlong>(key_slice);
//set the pointer to the value slice
if (we.type == rocksdb::kDeleteRecord || we.type == rocksdb::kLogDataRecord) { if (we.type == rocksdb::kDeleteRecord || we.type == rocksdb::kLogDataRecord) {
// set native handle of value slice to null if no value available // set native handle of value slice to null if no value available
rocksdb::WriteEntryJni::setValue(env, jwe, nullptr); results[2] = 0;
} else { } else {
char* value_buf = new char[we.value.size()]; char* value_buf = new char[we.value.size()];
memcpy(value_buf, we.value.data(), we.value.size()); memcpy(value_buf, we.value.data(), we.value.size());
auto* value_slice = new rocksdb::Slice(value_buf, we.value.size()); auto* value_slice = new rocksdb::Slice(value_buf, we.value.size());
rocksdb::WriteEntryJni::setValue(env, jwe, value_slice); results[2] = reinterpret_cast<jlong>(value_slice);
} }
jlongArray jresults = env->NewLongArray(3);
env->SetLongArrayRegion(jresults, 0, 3, results);
return jresults;
} }

@ -22,48 +22,35 @@ public class RocksDBColumnFamilySample {
String db_path = args[0]; String db_path = args[0];
System.out.println("RocksDBColumnFamilySample"); System.out.println("RocksDBColumnFamilySample");
RocksDB db = null; try(final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options, db_path)) {
ColumnFamilyHandle columnFamilyHandle = null;
WriteBatch wb = null;
try {
options = new Options().setCreateIfMissing(true);
db = RocksDB.open(options, db_path);
assert(db != null); assert(db != null);
// create column family // create column family
columnFamilyHandle = db.createColumnFamily( try(final ColumnFamilyHandle columnFamilyHandle = db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf".getBytes(), new ColumnFamilyDescriptor("new_cf".getBytes(),
new ColumnFamilyOptions())); new ColumnFamilyOptions()))) {
assert (columnFamilyHandle != null); assert (columnFamilyHandle != null);
} finally {
if (columnFamilyHandle != null) {
columnFamilyHandle.dispose();
}
if (db != null) {
db.close();
db = null;
}
if (options != null) {
options.dispose();
} }
} }
// open DB with two column families // open DB with two column families
List<ColumnFamilyDescriptor> columnFamilyDescriptors = new ArrayList<>(); final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
new ArrayList<>();
// have to open default column family // have to open default column family
columnFamilyDescriptors.add(new ColumnFamilyDescriptor( columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
RocksDB.DEFAULT_COLUMN_FAMILY, new ColumnFamilyOptions())); RocksDB.DEFAULT_COLUMN_FAMILY, new ColumnFamilyOptions()));
// open the new one, too // open the new one, too
columnFamilyDescriptors.add(new ColumnFamilyDescriptor( columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
"new_cf".getBytes(), new ColumnFamilyOptions())); "new_cf".getBytes(), new ColumnFamilyOptions()));
List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
try { try(final DBOptions options = new DBOptions();
db = RocksDB.open(new DBOptions(), db_path, final RocksDB db = RocksDB.open(options, db_path,
columnFamilyDescriptors, columnFamilyHandles); columnFamilyDescriptors, columnFamilyHandles)) {
assert(db != null); assert(db != null);
try {
// put and get from non-default column family // put and get from non-default column family
db.put(columnFamilyHandles.get(0), new WriteOptions(), db.put(columnFamilyHandles.get(0), new WriteOptions(),
"key".getBytes(), "value".getBytes()); "key".getBytes(), "value".getBytes());
@ -71,24 +58,21 @@ public class RocksDBColumnFamilySample {
"key".getBytes())); "key".getBytes()));
// atomic write // atomic write
wb = new WriteBatch(); try (final WriteBatch wb = new WriteBatch()) {
wb.put(columnFamilyHandles.get(0), "key2".getBytes(), "value2".getBytes()); wb.put(columnFamilyHandles.get(0), "key2".getBytes(),
wb.put(columnFamilyHandles.get(1), "key3".getBytes(), "value3".getBytes()); "value2".getBytes());
wb.put(columnFamilyHandles.get(1), "key3".getBytes(),
"value3".getBytes());
wb.remove(columnFamilyHandles.get(0), "key".getBytes()); wb.remove(columnFamilyHandles.get(0), "key".getBytes());
db.write(new WriteOptions(), wb); db.write(new WriteOptions(), wb);
}
// drop column family // drop column family
db.dropColumnFamily(columnFamilyHandles.get(1)); db.dropColumnFamily(columnFamilyHandles.get(1));
} finally { } finally {
for (ColumnFamilyHandle handle : columnFamilyHandles){ for (final ColumnFamilyHandle handle : columnFamilyHandles) {
handle.dispose(); handle.close();
}
if (db != null) {
db.close();
} }
if (wb != null) {
wb.dispose();
} }
} }
} }

@ -8,8 +8,10 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ArrayList; import java.util.ArrayList;
import org.rocksdb.*; import org.rocksdb.*;
import org.rocksdb.util.SizeUnit; import org.rocksdb.util.SizeUnit;
import java.io.IOException; import java.io.IOException;
public class RocksDBSample { public class RocksDBSample {
@ -26,14 +28,15 @@ public class RocksDBSample {
String db_path_not_found = db_path + "_not_found"; String db_path_not_found = db_path + "_not_found";
System.out.println("RocksDBSample"); System.out.println("RocksDBSample");
RocksDB db = null; try (final Options options = new Options();
Options options = new Options(); final Filter bloomFilter = new BloomFilter(10);
try { final ReadOptions readOptions = new ReadOptions()
db = RocksDB.open(options, db_path_not_found); .setFillCache(false)) {
try (final RocksDB db = RocksDB.open(options, db_path_not_found)) {
assert (false); assert (false);
} catch (RocksDBException e) { } catch (RocksDBException e) {
System.out.format("caught the expceted exception -- %s\n", e); System.out.format("caught the expected exception -- %s\n", e);
assert(db == null);
} }
try { try {
@ -86,9 +89,7 @@ public class RocksDBSample {
10000, 10)); 10000, 10));
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000)); options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000));
final BlockBasedTableConfig table_options = new BlockBasedTableConfig();
Filter bloomFilter = new BloomFilter(10);
BlockBasedTableConfig table_options = new BlockBasedTableConfig();
table_options.setBlockCacheSize(64 * SizeUnit.KB) table_options.setBlockCacheSize(64 * SizeUnit.KB)
.setFilter(bloomFilter) .setFilter(bloomFilter)
.setCacheNumShardBits(6) .setCacheNumShardBits(6)
@ -111,8 +112,7 @@ public class RocksDBSample {
options.setTableFormatConfig(table_options); options.setTableFormatConfig(table_options);
assert (options.tableFactoryName().equals("BlockBasedTable")); assert (options.tableFactoryName().equals("BlockBasedTable"));
try { try (final RocksDB db = RocksDB.open(options, db_path)) {
db = RocksDB.open(options, db_path);
db.put("hello".getBytes(), "world".getBytes()); db.put("hello".getBytes(), "world".getBytes());
byte[] value = db.get("hello".getBytes()); byte[] value = db.get("hello".getBytes());
assert ("world".equals(new String(value))); assert ("world".equals(new String(value)));
@ -120,17 +120,10 @@ public class RocksDBSample {
assert (str != null && !str.equals("")); assert (str != null && !str.equals(""));
} catch (RocksDBException e) { } catch (RocksDBException e) {
System.out.format("[ERROR] caught the unexpceted exception -- %s\n", e); System.out.format("[ERROR] caught the unexpceted exception -- %s\n", e);
assert(db == null);
assert (false); assert (false);
} }
// be sure to release the c++ pointer
db.close();
ReadOptions readOptions = new ReadOptions();
readOptions.setFillCache(false);
try { try (final RocksDB db = RocksDB.open(options, db_path)) {
db = RocksDB.open(options, db_path);
db.put("hello".getBytes(), "world".getBytes()); db.put("hello".getBytes(), "world".getBytes());
byte[] value = db.get("hello".getBytes()); byte[] value = db.get("hello".getBytes());
System.out.format("Get('hello') = %s\n", System.out.format("Get('hello') = %s\n",
@ -152,15 +145,16 @@ public class RocksDBSample {
} }
// write batch test // write batch test
WriteOptions writeOpt = new WriteOptions(); try (final WriteOptions writeOpt = new WriteOptions()) {
for (int i = 10; i <= 19; ++i) { for (int i = 10; i <= 19; ++i) {
WriteBatch batch = new WriteBatch(); try (final WriteBatch batch = new WriteBatch()) {
for (int j = 10; j <= 19; ++j) { for (int j = 10; j <= 19; ++j) {
batch.put(String.format("%dx%d", i, j).getBytes(), batch.put(String.format("%dx%d", i, j).getBytes(),
String.format("%d", i * j).getBytes()); String.format("%d", i * j).getBytes());
} }
db.write(writeOpt, batch); db.write(writeOpt, batch);
batch.dispose(); }
}
} }
for (int i = 10; i <= 19; ++i) { for (int i = 10; i <= 19; ++i) {
for (int j = 10; j <= 19; ++j) { for (int j = 10; j <= 19; ++j) {
@ -172,7 +166,6 @@ public class RocksDBSample {
} }
System.out.println(""); System.out.println("");
} }
writeOpt.dispose();
value = db.get("1x1".getBytes()); value = db.get("1x1".getBytes());
assert (value != null); assert (value != null);
@ -216,7 +209,7 @@ public class RocksDBSample {
assert (len == RocksDB.NOT_FOUND); assert (len == RocksDB.NOT_FOUND);
// repeat the test with WriteOptions // repeat the test with WriteOptions
WriteOptions writeOpts = new WriteOptions(); try (final WriteOptions writeOpts = new WriteOptions()) {
writeOpts.setSync(true); writeOpts.setSync(true);
writeOpts.setDisableWAL(true); writeOpts.setDisableWAL(true);
db.put(writeOpts, testKey, testValue); db.put(writeOpts, testKey, testValue);
@ -224,7 +217,7 @@ public class RocksDBSample {
assert (len == testValue.length); assert (len == testValue.length);
assert (new String(testValue).equals( assert (new String(testValue).equals(
new String(enoughArray, 0, len))); new String(enoughArray, 0, len)));
writeOpts.dispose(); }
try { try {
for (TickerType statsType : TickerType.values()) { for (TickerType statsType : TickerType.values()) {
@ -246,7 +239,7 @@ public class RocksDBSample {
assert (false); //Should never reach here. assert (false); //Should never reach here.
} }
RocksIterator iterator = db.newIterator(); try (final RocksIterator iterator = db.newIterator()) {
boolean seekToFirstPassed = false; boolean seekToFirstPassed = false;
for (iterator.seekToFirst(); iterator.isValid(); iterator.next()) { for (iterator.seekToFirst(); iterator.isValid(); iterator.next()) {
@ -278,15 +271,15 @@ public class RocksDBSample {
System.out.println("iterator seek test passed."); System.out.println("iterator seek test passed.");
iterator.dispose(); }
System.out.println("iterator tests passed."); System.out.println("iterator tests passed.");
iterator = db.newIterator(); final List<byte[]> keys = new ArrayList<>();
List<byte[]> keys = new ArrayList<byte[]>(); try (final RocksIterator iterator = db.newIterator()) {
for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) { for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) {
keys.add(iterator.key()); keys.add(iterator.key());
} }
iterator.dispose(); }
Map<byte[], byte[]> values = db.multiGet(keys); Map<byte[], byte[]> values = db.multiGet(keys);
assert (values.size() == keys.size()); assert (values.size() == keys.size());
@ -302,11 +295,6 @@ public class RocksDBSample {
} catch (RocksDBException e) { } catch (RocksDBException e) {
System.err.println(e); System.err.println(e);
} }
if (db != null) {
db.close();
} }
// be sure to dispose c++ pointers
options.dispose();
readOptions.dispose();
} }
} }

@ -8,22 +8,23 @@ package org.rocksdb;
* A CompactionFilter allows an application to modify/delete a key-value at * A CompactionFilter allows an application to modify/delete a key-value at
* the time of compaction. * the time of compaction.
* *
* At present we just permit an overriding Java class to wrap a C++ implementation * At present we just permit an overriding Java class to wrap a C++
* implementation
*/ */
public abstract class AbstractCompactionFilter<T extends AbstractSlice<?>> public abstract class AbstractCompactionFilter<T extends AbstractSlice<?>>
extends RocksObject { extends RocksObject {
protected AbstractCompactionFilter(final long nativeHandle) {
super(nativeHandle);
}
/** /**
* Deletes underlying C++ comparator pointer. * Deletes underlying C++ compaction pointer.
* *
* Note that this function should be called only after all * Note that this function should be called only after all
* RocksDB instances referencing the comparator are closed. * RocksDB instances referencing the compaction filter are closed.
* Otherwise an undefined behavior will occur. * Otherwise an undefined behavior will occur.
*/ */
@Override protected void disposeInternal() { @Override
assert(isInitialized()); protected final native void disposeInternal(final long handle);
disposeInternal(nativeHandle_);
}
private native void disposeInternal(long handle);
} }

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

@ -0,0 +1,66 @@
// Copyright (c) 2016, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Offers functionality for implementations of
* {@link AbstractNativeReference} which have an immutable reference to the
* underlying native C++ object
*/
public abstract class AbstractImmutableNativeReference
extends AbstractNativeReference {
/**
* A flag indicating whether the current {@code AbstractNativeReference} is
* responsible to free the underlying C++ object
*/
private final AtomicBoolean owningHandle_;
protected AbstractImmutableNativeReference(final boolean owningHandle) {
this.owningHandle_ = new AtomicBoolean(owningHandle);
}
@Override
public boolean isOwningHandle() {
return owningHandle_.get();
}
/**
* Releases this {@code AbstractNativeReference} from the responsibility of
* freeing the underlying native C++ object
* <p>
* This will prevent the object from attempting to delete the underlying
* native object in its finalizer. This must be used when another object
* takes over ownership of the native object or both will attempt to delete
* the underlying object when garbage collected.
* <p>
* When {@code disOwnNativeHandle()} is called, {@code dispose()} will
* subsequently take no action. As a result, incorrect use of this function
* may cause a memory leak.
* </p>
*
* @see #dispose()
*/
protected final void disOwnNativeHandle() {
owningHandle_.set(false);
}
@Override
public void close() {
if (owningHandle_.compareAndSet(true, false)) {
disposeInternal();
}
}
/**
* The helper function of {@link AbstractImmutableNativeReference#dispose()}
* which all subclasses of {@code AbstractImmutableNativeReference} must
* implement to release their underlying native C++ objects.
*/
protected abstract void disposeInternal();
}

@ -0,0 +1,76 @@
// Copyright (c) 2016, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb;
/**
* AbstractNativeReference is the base-class of all RocksDB classes that have
* a pointer to a native C++ {@code rocksdb} object.
* <p>
* AbstractNativeReference has the {@link AbstractNativeReference#dispose()}
* method, which frees its associated C++ object.</p>
* <p>
* This function should be called manually, however, if required it will be
* called automatically during the regular Java GC process via
* {@link AbstractNativeReference#finalize()}.</p>
* <p>
* Note - Java can only see the long member variable (which is the C++ pointer
* value to the native object), as such it does not know the real size of the
* object and therefore may assign a low GC priority for it; So it is strongly
* suggested that you manually dispose of objects when you are finished with
* them.</p>
*/
public abstract class AbstractNativeReference implements AutoCloseable {
/**
* Returns true if we are responsible for freeing the underlying C++ object
*
* @return true if we are responsible to free the C++ object
* @see #dispose()
*/
protected abstract boolean isOwningHandle();
/**
* Frees the underlying C++ object
* <p>
* It is strong recommended that the developer calls this after they
* have finished using the object.</p>
* <p>
* Note, that once an instance of {@link AbstractNativeReference} has been
* disposed, calling any of its functions will lead to undefined
* behavior.</p>
*/
@Override
public abstract void close();
/**
* @deprecated Instead use {@link AbstractNativeReference#close()}
*/
@Deprecated
public final void dispose() {
close();
}
/**
* Simply calls {@link AbstractNativeReference#dispose()} to free
* any underlying C++ object reference which has not yet been manually
* released.
*
* @deprecated You should not rely on GC of Rocks objects, and instead should
* either call {@link AbstractNativeReference#close()} manually or make
* use of some sort of ARM (Automatic Resource Management) such as
* Java 7's <a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html">try-with-resources</a>
* statement
*/
@Override
@Deprecated
protected void finalize() throws Throwable {
if(isOwningHandle()) {
//TODO(AR) log a warning message... developer should have called close()
}
dispose();
super.finalize();
}
}

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

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

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

@ -19,8 +19,8 @@ import java.util.List;
*/ */
public class BackupEngine extends RocksObject implements AutoCloseable { public class BackupEngine extends RocksObject implements AutoCloseable {
protected BackupEngine() { protected BackupEngine(final long nativeHandle) {
super(); super(nativeHandle);
} }
/** /**
@ -30,12 +30,11 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @param options Any options for the backup engine * @param options Any options for the backup engine
* *
* @return A new BackupEngine instance * @return A new BackupEngine instance
* @throws RocksDBException thrown if the backup engine could not be opened
*/ */
public static BackupEngine open(final Env env, public static BackupEngine open(final Env env,
final BackupableDBOptions options) throws RocksDBException { final BackupableDBOptions options) throws RocksDBException {
final BackupEngine be = new BackupEngine(); return new BackupEngine(open(env.nativeHandle_, options.nativeHandle_));
be.open(env.nativeHandle_, options.nativeHandle_);
return be;
} }
/** /**
@ -47,6 +46,8 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @param db The database to backup * @param db The database to backup
* *
* Note - This method is not thread safe * Note - This method is not thread safe
*
* @throws RocksDBException thrown if a new backup could not be created
*/ */
public void createNewBackup(final RocksDB db) throws RocksDBException { public void createNewBackup(final RocksDB db) throws RocksDBException {
createNewBackup(db, false); createNewBackup(db, false);
@ -70,11 +71,13 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* parameter. * parameter.
* *
* Note - This method is not thread safe * Note - This method is not thread safe
*
* @throws RocksDBException thrown if a new backup could not be created
*/ */
public void createNewBackup( public void createNewBackup(
final RocksDB db, final boolean flushBeforeBackup) final RocksDB db, final boolean flushBeforeBackup)
throws RocksDBException { throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
createNewBackup(nativeHandle_, db.nativeHandle_, flushBeforeBackup); createNewBackup(nativeHandle_, db.nativeHandle_, flushBeforeBackup);
} }
@ -85,7 +88,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @return A list of information about each available backup * @return A list of information about each available backup
*/ */
public List<BackupInfo> getBackupInfo() { public List<BackupInfo> getBackupInfo() {
assert (isInitialized()); assert (isOwningHandle());
return getBackupInfo(nativeHandle_); return getBackupInfo(nativeHandle_);
} }
@ -97,7 +100,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @return array of backup ids as int ids. * @return array of backup ids as int ids.
*/ */
public int[] getCorruptedBackups() { public int[] getCorruptedBackups() {
assert(isInitialized()); assert(isOwningHandle());
return getCorruptedBackups(nativeHandle_); return getCorruptedBackups(nativeHandle_);
} }
@ -110,7 +113,7 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* native library. * native library.
*/ */
public void garbageCollect() throws RocksDBException { public void garbageCollect() throws RocksDBException {
assert(isInitialized()); assert(isOwningHandle());
garbageCollect(nativeHandle_); garbageCollect(nativeHandle_);
} }
@ -118,10 +121,12 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* Deletes old backups, keeping just the latest numBackupsToKeep * Deletes old backups, keeping just the latest numBackupsToKeep
* *
* @param numBackupsToKeep The latest n backups to keep * @param numBackupsToKeep The latest n backups to keep
*
* @throws RocksDBException thrown if the old backups could not be deleted
*/ */
public void purgeOldBackups( public void purgeOldBackups(
final int numBackupsToKeep) throws RocksDBException { final int numBackupsToKeep) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
purgeOldBackups(nativeHandle_, numBackupsToKeep); purgeOldBackups(nativeHandle_, numBackupsToKeep);
} }
@ -129,9 +134,11 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* Deletes a backup * Deletes a backup
* *
* @param backupId The id of the backup to delete * @param backupId The id of the backup to delete
*
* @throws RocksDBException thrown if the backup could not be deleted
*/ */
public void deleteBackup(final int backupId) throws RocksDBException { public void deleteBackup(final int backupId) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
deleteBackup(nativeHandle_, backupId); deleteBackup(nativeHandle_, backupId);
} }
@ -154,11 +161,13 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
* @param walDir The location of the log files for your database, * @param walDir The location of the log files for your database,
* often the same as dbDir * often the same as dbDir
* @param restoreOptions Options for controlling the restore * @param restoreOptions Options for controlling the restore
*
* @throws RocksDBException thrown if the database could not be restored
*/ */
public void restoreDbFromBackup( public void restoreDbFromBackup(
final int backupId, final String dbDir, final String walDir, final int backupId, final String dbDir, final String walDir,
final RestoreOptions restoreOptions) throws RocksDBException { final RestoreOptions restoreOptions) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
restoreDbFromBackup(nativeHandle_, backupId, dbDir, walDir, restoreDbFromBackup(nativeHandle_, backupId, dbDir, walDir,
restoreOptions.nativeHandle_); restoreOptions.nativeHandle_);
} }
@ -166,34 +175,24 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
/** /**
* Restore the database from the latest backup * Restore the database from the latest backup
* *
* @param dbDir The directory to restore the backup to, i.e. where your database is * @param dbDir The directory to restore the backup to, i.e. where your
* @param walDir The location of the log files for your database, often the same as dbDir * database is
* @param walDir The location of the log files for your database, often the
* same as dbDir
* @param restoreOptions Options for controlling the restore * @param restoreOptions Options for controlling the restore
*
* @throws RocksDBException thrown if the database could not be restored
*/ */
public void restoreDbFromLatestBackup( public void restoreDbFromLatestBackup(
final String dbDir, final String walDir, final String dbDir, final String walDir,
final RestoreOptions restoreOptions) throws RocksDBException { final RestoreOptions restoreOptions) throws RocksDBException {
assert (isInitialized()); assert (isOwningHandle());
restoreDbFromLatestBackup(nativeHandle_, dbDir, walDir, restoreDbFromLatestBackup(nativeHandle_, dbDir, walDir,
restoreOptions.nativeHandle_); restoreOptions.nativeHandle_);
} }
/** private native static long open(final long env,
* Close the Backup Engine final long backupableDbOptions) throws RocksDBException;
*/
@Override
public void close() throws RocksDBException {
dispose();
}
@Override
protected void disposeInternal() {
assert (isInitialized());
disposeInternal(nativeHandle_);
}
private native void open(final long env, final long backupableDbOptions)
throws RocksDBException;
private native void createNewBackup(final long handle, final long dbHandle, private native void createNewBackup(final long handle, final long dbHandle,
final boolean flushBeforeBackup) throws RocksDBException; final boolean flushBeforeBackup) throws RocksDBException;
@ -218,5 +217,5 @@ public class BackupEngine extends RocksObject implements AutoCloseable {
final String dbDir, final String walDir, final long restoreOptionsHandle) final String dbDir, final String walDir, final long restoreOptionsHandle)
throws RocksDBException; throws RocksDBException;
private native void disposeInternal(final long handle); @Override protected final native void disposeInternal(final long handle);
} }

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

@ -6,7 +6,6 @@
package org.rocksdb; package org.rocksdb;
import java.io.File; import java.io.File;
import java.nio.file.Path;
/** /**
* <p>BackupableDBOptions to control the behavior of a backupable database. * <p>BackupableDBOptions to control the behavior of a backupable database.
@ -22,17 +21,22 @@ public class BackupableDBOptions extends RocksObject {
/** /**
* <p>BackupableDBOptions constructor.</p> * <p>BackupableDBOptions constructor.</p>
* *
* @param path Where to keep the backup files. Has to be different than db name. * @param path Where to keep the backup files. Has to be different than db
* Best to set this to {@code db name_ + "/backups"} * name. Best to set this to {@code db name_ + "/backups"}
* @throws java.lang.IllegalArgumentException if illegal path is used. * @throws java.lang.IllegalArgumentException if illegal path is used.
*/ */
public BackupableDBOptions(final String path) { public BackupableDBOptions(final String path) {
super(); super(newBackupableDBOptions(ensureWritableFile(path)));
File backupPath = path == null ? null : new File(path); }
if (backupPath == null || !backupPath.isDirectory() || !backupPath.canWrite()) {
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."); throw new IllegalArgumentException("Illegal path provided.");
} else {
return path;
} }
newBackupableDBOptions(path);
} }
/** /**
@ -41,24 +45,25 @@ public class BackupableDBOptions extends RocksObject {
* @return the path to the BackupableDB directory. * @return the path to the BackupableDB directory.
*/ */
public String backupDir() { public String backupDir() {
assert(isInitialized()); assert(isOwningHandle());
return backupDir(nativeHandle_); return backupDir(nativeHandle_);
} }
/** /**
* <p>Share table files between backups.</p> * <p>Share table files between backups.</p>
* *
* @param shareTableFiles If {@code share_table_files == true}, backup will assume * @param shareTableFiles If {@code share_table_files == true}, backup will
* that table files with same name have the same contents. This enables incremental * assume that table files with same name have the same contents. This
* backups and avoids unnecessary data copies. If {@code share_table_files == false}, * enables incremental backups and avoids unnecessary data copies. If
* each backup will be on its own and will not share any data with other backups. * {@code share_table_files == false}, each backup will be on its own and
* will not share any data with other backups.
* *
* <p>Default: true</p> * <p>Default: true</p>
* *
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setShareTableFiles(final boolean shareTableFiles) { public BackupableDBOptions setShareTableFiles(final boolean shareTableFiles) {
assert(isInitialized()); assert(isOwningHandle());
setShareTableFiles(nativeHandle_, shareTableFiles); setShareTableFiles(nativeHandle_, shareTableFiles);
return this; return this;
} }
@ -70,24 +75,24 @@ public class BackupableDBOptions extends RocksObject {
* backups. * backups.
*/ */
public boolean shareTableFiles() { public boolean shareTableFiles() {
assert(isInitialized()); assert(isOwningHandle());
return shareTableFiles(nativeHandle_); return shareTableFiles(nativeHandle_);
} }
/** /**
* <p>Set synchronous backups.</p> * <p>Set synchronous backups.</p>
* *
* @param sync If {@code sync == true}, we can guarantee you'll get consistent backup * @param sync If {@code sync == true}, we can guarantee you'll get consistent
* even on a machine crash/reboot. Backup process is slower with sync enabled. * backup even on a machine crash/reboot. Backup process is slower with sync
* If {@code sync == false}, we don't guarantee anything on machine reboot. * enabled. If {@code sync == false}, we don't guarantee anything on machine
* However,chances are some of the backups are consistent. * reboot. However, chances are some of the backups are consistent.
* *
* <p>Default: true</p> * <p>Default: true</p>
* *
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setSync(final boolean sync) { public BackupableDBOptions setSync(final boolean sync) {
assert(isInitialized()); assert(isOwningHandle());
setSync(nativeHandle_, sync); setSync(nativeHandle_, sync);
return this; return this;
} }
@ -98,21 +103,22 @@ public class BackupableDBOptions extends RocksObject {
* @return boolean value if synchronous backups are configured. * @return boolean value if synchronous backups are configured.
*/ */
public boolean sync() { public boolean sync() {
assert(isInitialized()); assert(isOwningHandle());
return sync(nativeHandle_); return sync(nativeHandle_);
} }
/** /**
* <p>Set if old data will be destroyed.</p> * <p>Set if old data will be destroyed.</p>
* *
* @param destroyOldData If true, it will delete whatever backups there are already. * @param destroyOldData If true, it will delete whatever backups there are
* already.
* *
* <p>Default: false</p> * <p>Default: false</p>
* *
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setDestroyOldData(final boolean destroyOldData) { public BackupableDBOptions setDestroyOldData(final boolean destroyOldData) {
assert(isInitialized()); assert(isOwningHandle());
setDestroyOldData(nativeHandle_, destroyOldData); setDestroyOldData(nativeHandle_, destroyOldData);
return this; return this;
} }
@ -123,23 +129,23 @@ public class BackupableDBOptions extends RocksObject {
* @return boolean value indicating if old data will be destroyed. * @return boolean value indicating if old data will be destroyed.
*/ */
public boolean destroyOldData() { public boolean destroyOldData() {
assert(isInitialized()); assert(isOwningHandle());
return destroyOldData(nativeHandle_); return destroyOldData(nativeHandle_);
} }
/** /**
* <p>Set if log files shall be persisted.</p> * <p>Set if log files shall be persisted.</p>
* *
* @param backupLogFiles If false, we won't backup log files. This option can be * @param backupLogFiles If false, we won't backup log files. This option can
* useful for backing up in-memory databases where log file are persisted,but table * be useful for backing up in-memory databases where log file are
* files are in memory. * persisted, but table files are in memory.
* *
* <p>Default: true</p> * <p>Default: true</p>
* *
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setBackupLogFiles(final boolean backupLogFiles) { public BackupableDBOptions setBackupLogFiles(final boolean backupLogFiles) {
assert(isInitialized()); assert(isOwningHandle());
setBackupLogFiles(nativeHandle_, backupLogFiles); setBackupLogFiles(nativeHandle_, backupLogFiles);
return this; return this;
} }
@ -150,73 +156,76 @@ public class BackupableDBOptions extends RocksObject {
* @return boolean value indicating if log files will be persisted. * @return boolean value indicating if log files will be persisted.
*/ */
public boolean backupLogFiles() { public boolean backupLogFiles() {
assert(isInitialized()); assert(isOwningHandle());
return backupLogFiles(nativeHandle_); return backupLogFiles(nativeHandle_);
} }
/** /**
* <p>Set backup rate limit.</p> * <p>Set backup rate limit.</p>
* *
* @param backupRateLimit Max bytes that can be transferred in a second during backup. * @param backupRateLimit Max bytes that can be transferred in a second during
* If 0 or negative, then go as fast as you can. * backup. If 0 or negative, then go as fast as you can.
* *
* <p>Default: 0</p> * <p>Default: 0</p>
* *
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setBackupRateLimit(long backupRateLimit) { public BackupableDBOptions setBackupRateLimit(long backupRateLimit) {
assert(isInitialized()); assert(isOwningHandle());
backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit; backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit;
setBackupRateLimit(nativeHandle_, backupRateLimit); setBackupRateLimit(nativeHandle_, backupRateLimit);
return this; return this;
} }
/** /**
* <p>Return backup rate limit which described the max bytes that can be transferred in a * <p>Return backup rate limit which described the max bytes that can be
* second during backup.</p> * transferred in a second during backup.</p>
* *
* @return numerical value describing the backup transfer limit in bytes per second. * @return numerical value describing the backup transfer limit in bytes per
* second.
*/ */
public long backupRateLimit() { public long backupRateLimit() {
assert(isInitialized()); assert(isOwningHandle());
return backupRateLimit(nativeHandle_); return backupRateLimit(nativeHandle_);
} }
/** /**
* <p>Set restore rate limit.</p> * <p>Set restore rate limit.</p>
* *
* @param restoreRateLimit Max bytes that can be transferred in a second during restore. * @param restoreRateLimit Max bytes that can be transferred in a second
* If 0 or negative, then go as fast as you can. * during restore. If 0 or negative, then go as fast as you can.
* *
* <p>Default: 0</p> * <p>Default: 0</p>
* *
* @return instance of current BackupableDBOptions. * @return instance of current BackupableDBOptions.
*/ */
public BackupableDBOptions setRestoreRateLimit(long restoreRateLimit) { public BackupableDBOptions setRestoreRateLimit(long restoreRateLimit) {
assert(isInitialized()); assert(isOwningHandle());
restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit; restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit;
setRestoreRateLimit(nativeHandle_, restoreRateLimit); setRestoreRateLimit(nativeHandle_, restoreRateLimit);
return this; return this;
} }
/** /**
* <p>Return restore rate limit which described the max bytes that can be transferred in a * <p>Return restore rate limit which described the max bytes that can be
* second during restore.</p> * transferred in a second during restore.</p>
* *
* @return numerical value describing the restore transfer limit in bytes per second. * @return numerical value describing the restore transfer limit in bytes per
* second.
*/ */
public long restoreRateLimit() { public long restoreRateLimit() {
assert(isInitialized()); assert(isOwningHandle());
return restoreRateLimit(nativeHandle_); return restoreRateLimit(nativeHandle_);
} }
/** /**
* <p>Only used if share_table_files is set to true. If true, will consider that * <p>Only used if share_table_files is set to true. If true, will consider
* backups can come from different databases, hence a sst is not uniquely * that backups can come from different databases, hence a sst is not uniquely
* identified by its name, but by the triple (file name, crc32, file length)</p> * identified by its name, but by the triple (file name, crc32, file length)
* </p>
* *
* @param shareFilesWithChecksum boolean value indicating if SST files are stored * @param shareFilesWithChecksum boolean value indicating if SST files are
* using the triple (file name, crc32, file length) and not its name. * stored using the triple (file name, crc32, file length) and not its name.
* *
* <p>Note: this is an experimental option, and you'll need to set it manually * <p>Note: this is an experimental option, and you'll need to set it manually
* turn it on only if you know what you're doing*</p> * turn it on only if you know what you're doing*</p>
@ -227,7 +236,7 @@ public class BackupableDBOptions extends RocksObject {
*/ */
public BackupableDBOptions setShareFilesWithChecksum( public BackupableDBOptions setShareFilesWithChecksum(
final boolean shareFilesWithChecksum) { final boolean shareFilesWithChecksum) {
assert(isInitialized()); assert(isOwningHandle());
setShareFilesWithChecksum(nativeHandle_, shareFilesWithChecksum); setShareFilesWithChecksum(nativeHandle_, shareFilesWithChecksum);
return this; return this;
} }
@ -239,19 +248,11 @@ public class BackupableDBOptions extends RocksObject {
* is active. * is active.
*/ */
public boolean shareFilesWithChecksum() { public boolean shareFilesWithChecksum() {
assert(isInitialized()); assert(isOwningHandle());
return shareFilesWithChecksum(nativeHandle_); return shareFilesWithChecksum(nativeHandle_);
} }
/** private native static long newBackupableDBOptions(final String path);
* Release the memory allocated for the current instance
* in the c++ side.
*/
@Override protected void disposeInternal() {
disposeInternal(nativeHandle_);
}
private native void newBackupableDBOptions(String path);
private native String backupDir(long handle); private native String backupDir(long handle);
private native void setShareTableFiles(long handle, boolean flag); private native void setShareTableFiles(long handle, boolean flag);
private native boolean shareTableFiles(long handle); private native boolean shareTableFiles(long handle);
@ -267,5 +268,5 @@ public class BackupableDBOptions extends RocksObject {
private native long restoreRateLimit(long handle); private native long restoreRateLimit(long handle);
private native void setShareFilesWithChecksum(long handle, boolean flag); private native void setShareFilesWithChecksum(long handle, boolean flag);
private native boolean shareFilesWithChecksum(long handle); private native boolean shareFilesWithChecksum(long handle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
} }

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

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

@ -12,34 +12,31 @@ package org.rocksdb;
public class ColumnFamilyHandle extends RocksObject { public class ColumnFamilyHandle extends RocksObject {
ColumnFamilyHandle(final RocksDB rocksDB, ColumnFamilyHandle(final RocksDB rocksDB,
final long nativeHandle) { final long nativeHandle) {
super(); super(nativeHandle);
nativeHandle_ = nativeHandle;
// rocksDB must point to a valid RocksDB instance; // rocksDB must point to a valid RocksDB instance;
assert(rocksDB != null); assert(rocksDB != null);
// ColumnFamilyHandle must hold a reference to the related RocksDB instance // ColumnFamilyHandle must hold a reference to the related RocksDB instance
// to guarantee that while a GC cycle starts ColumnFamilyHandle instances // to guarantee that while a GC cycle starts ColumnFamilyHandle instances
// are freed prior to RocksDB instances. // are freed prior to RocksDB instances.
rocksDB_ = rocksDB; this.rocksDB_ = rocksDB;
} }
/** /**
* <p>Deletes underlying C++ iterator pointer.</p> * <p>Deletes underlying C++ iterator pointer.</p>
* *
* <p>Note: the underlying handle can only be safely deleted if the RocksDB * <p>Note: the underlying handle can only be safely deleted if the RocksDB
* instance related to a certain ColumnFamilyHandle is still valid and initialized. * instance related to a certain ColumnFamilyHandle is still valid and
* Therefore {@code disposeInternal()} checks if the RocksDB is initialized * initialized. Therefore {@code disposeInternal()} checks if the RocksDB is
* before freeing the native handle.</p> * initialized before freeing the native handle.</p>
*/ */
@Override protected void disposeInternal() { @Override
synchronized (rocksDB_) { protected void disposeInternal() {
assert (isInitialized()); if(rocksDB_.isOwningHandle()) {
if (rocksDB_.isInitialized()) {
disposeInternal(nativeHandle_); disposeInternal(nativeHandle_);
} }
} }
}
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private final RocksDB rocksDB_; private final RocksDB rocksDB_;
} }

@ -13,8 +13,8 @@ import java.util.Properties;
* ColumnFamilyOptions to control the behavior of a database. It will be used * ColumnFamilyOptions to control the behavior of a database. It will be used
* during the creation of a {@link org.rocksdb.RocksDB} (i.e., RocksDB.open()). * during the creation of a {@link org.rocksdb.RocksDB} (i.e., RocksDB.open()).
* *
* If {@link #dispose()} function is not called, then it will be GC'd automatically * If {@link #dispose()} function is not called, then it will be GC'd
* and native resources will be released as part of the process. * automatically and native resources will be released as part of the process.
*/ */
public class ColumnFamilyOptions extends RocksObject public class ColumnFamilyOptions extends RocksObject
implements ColumnFamilyOptionsInterface { implements ColumnFamilyOptionsInterface {
@ -29,8 +29,7 @@ public class ColumnFamilyOptions extends RocksObject
* an {@code rocksdb::DBOptions} in the c++ side. * an {@code rocksdb::DBOptions} in the c++ side.
*/ */
public ColumnFamilyOptions() { public ColumnFamilyOptions() {
super(); super(newColumnFamilyOptions());
newColumnFamilyOptions();
} }
/** /**
@ -113,8 +112,9 @@ public class ColumnFamilyOptions extends RocksObject
} }
@Override @Override
public ColumnFamilyOptions setComparator(final BuiltinComparator builtinComparator) { public ColumnFamilyOptions setComparator(
assert(isInitialized()); final BuiltinComparator builtinComparator) {
assert(isOwningHandle());
setComparatorHandle(nativeHandle_, builtinComparator.ordinal()); setComparatorHandle(nativeHandle_, builtinComparator.ordinal());
return this; return this;
} }
@ -122,15 +122,15 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setComparator( public ColumnFamilyOptions setComparator(
final AbstractComparator<? extends AbstractSlice<?>> comparator) { final AbstractComparator<? extends AbstractSlice<?>> comparator) {
assert (isInitialized()); assert (isOwningHandle());
setComparatorHandle(nativeHandle_, comparator.nativeHandle_); setComparatorHandle(nativeHandle_, comparator.getNativeHandle());
comparator_ = comparator; comparator_ = comparator;
return this; return this;
} }
@Override @Override
public ColumnFamilyOptions setMergeOperatorName(final String name) { public ColumnFamilyOptions setMergeOperatorName(final String name) {
assert (isInitialized()); assert (isOwningHandle());
if (name == null) { if (name == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Merge operator name must not be null."); "Merge operator name must not be null.");
@ -140,13 +140,15 @@ public class ColumnFamilyOptions extends RocksObject
} }
@Override @Override
public ColumnFamilyOptions setMergeOperator(final MergeOperator mergeOperator) { public ColumnFamilyOptions setMergeOperator(
final MergeOperator mergeOperator) {
setMergeOperator(nativeHandle_, mergeOperator.newMergeOperatorHandle()); setMergeOperator(nativeHandle_, mergeOperator.newMergeOperatorHandle());
return this; return this;
} }
public ColumnFamilyOptions setCompactionFilter( public ColumnFamilyOptions setCompactionFilter(
final AbstractCompactionFilter<? extends AbstractSlice<?>> compactionFilter) { final AbstractCompactionFilter<? extends AbstractSlice<?>>
compactionFilter) {
setCompactionFilterHandle(nativeHandle_, compactionFilter.nativeHandle_); setCompactionFilterHandle(nativeHandle_, compactionFilter.nativeHandle_);
compactionFilter_ = compactionFilter; compactionFilter_ = compactionFilter;
return this; return this;
@ -154,28 +156,28 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setWriteBufferSize(final long writeBufferSize) { public ColumnFamilyOptions setWriteBufferSize(final long writeBufferSize) {
assert(isInitialized()); assert(isOwningHandle());
setWriteBufferSize(nativeHandle_, writeBufferSize); setWriteBufferSize(nativeHandle_, writeBufferSize);
return this; return this;
} }
@Override @Override
public long writeBufferSize() { public long writeBufferSize() {
assert(isInitialized()); assert(isOwningHandle());
return writeBufferSize(nativeHandle_); return writeBufferSize(nativeHandle_);
} }
@Override @Override
public ColumnFamilyOptions setMaxWriteBufferNumber( public ColumnFamilyOptions setMaxWriteBufferNumber(
final int maxWriteBufferNumber) { final int maxWriteBufferNumber) {
assert(isInitialized()); assert(isOwningHandle());
setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber); setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber);
return this; return this;
} }
@Override @Override
public int maxWriteBufferNumber() { public int maxWriteBufferNumber() {
assert(isInitialized()); assert(isOwningHandle());
return maxWriteBufferNumber(nativeHandle_); return maxWriteBufferNumber(nativeHandle_);
} }
@ -193,20 +195,21 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions useFixedLengthPrefixExtractor(final int n) { public ColumnFamilyOptions useFixedLengthPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useFixedLengthPrefixExtractor(nativeHandle_, n); useFixedLengthPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@Override @Override
public ColumnFamilyOptions useCappedPrefixExtractor(final int n) { public ColumnFamilyOptions useCappedPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useCappedPrefixExtractor(nativeHandle_, n); useCappedPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@Override @Override
public ColumnFamilyOptions setCompressionType(final CompressionType compressionType) { public ColumnFamilyOptions setCompressionType(
final CompressionType compressionType) {
setCompressionType(nativeHandle_, compressionType.getValue()); setCompressionType(nativeHandle_, compressionType.getValue());
return this; return this;
} }
@ -219,10 +222,10 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setCompressionPerLevel( public ColumnFamilyOptions setCompressionPerLevel(
final List<CompressionType> compressionLevels) { final List<CompressionType> compressionLevels) {
final List<Byte> byteCompressionTypes = new ArrayList<>( final byte[] byteCompressionTypes = new byte[
compressionLevels.size()); compressionLevels.size()];
for (final CompressionType compressionLevel : compressionLevels) { for (int i = 0; i < compressionLevels.size(); i++) {
byteCompressionTypes.add(compressionLevel.getValue()); byteCompressionTypes[i] = compressionLevels.get(i).getValue();
} }
setCompressionPerLevel(nativeHandle_, byteCompressionTypes); setCompressionPerLevel(nativeHandle_, byteCompressionTypes);
return this; return this;
@ -230,7 +233,7 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public List<CompressionType> compressionPerLevel() { public List<CompressionType> compressionPerLevel() {
final List<Byte> byteCompressionTypes = final byte[] byteCompressionTypes =
compressionPerLevel(nativeHandle_); compressionPerLevel(nativeHandle_);
final List<CompressionType> compressionLevels = new ArrayList<>(); final List<CompressionType> compressionLevels = new ArrayList<>();
for (final Byte byteCompressionType : byteCompressionTypes) { for (final Byte byteCompressionType : byteCompressionTypes) {
@ -485,7 +488,7 @@ public class ColumnFamilyOptions extends RocksObject
public ColumnFamilyOptions setMaxTableFilesSizeFIFO( public ColumnFamilyOptions setMaxTableFilesSizeFIFO(
final long maxTableFilesSize) { final long maxTableFilesSize) {
assert(maxTableFilesSize > 0); // unsigned native type assert(maxTableFilesSize > 0); // unsigned native type
assert(isInitialized()); assert(isOwningHandle());
setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize); setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize);
return this; return this;
} }
@ -523,7 +526,8 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public ColumnFamilyOptions setMaxSequentialSkipInIterations( public ColumnFamilyOptions setMaxSequentialSkipInIterations(
final long maxSequentialSkipInIterations) { final long maxSequentialSkipInIterations) {
setMaxSequentialSkipInIterations(nativeHandle_, maxSequentialSkipInIterations); setMaxSequentialSkipInIterations(nativeHandle_,
maxSequentialSkipInIterations);
return this; return this;
} }
@ -542,7 +546,7 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public String memTableFactoryName() { public String memTableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return memTableFactoryName(nativeHandle_); return memTableFactoryName(nativeHandle_);
} }
@ -556,7 +560,7 @@ public class ColumnFamilyOptions extends RocksObject
@Override @Override
public String tableFactoryName() { public String tableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return tableFactoryName(nativeHandle_); return tableFactoryName(nativeHandle_);
} }
@ -655,15 +659,6 @@ public class ColumnFamilyOptions extends RocksObject
return optimizeFiltersForHits(nativeHandle_); return optimizeFiltersForHits(nativeHandle_);
} }
/**
* Release the memory allocated for the current instance
* in the c++ side.
*/
@Override protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_);
}
/** /**
* <p>Private constructor to be used by * <p>Private constructor to be used by
* {@link #getColumnFamilyOptionsFromProps(java.util.Properties)}</p> * {@link #getColumnFamilyOptionsFromProps(java.util.Properties)}</p>
@ -671,15 +666,14 @@ public class ColumnFamilyOptions extends RocksObject
* @param handle native handle to ColumnFamilyOptions instance. * @param handle native handle to ColumnFamilyOptions instance.
*/ */
private ColumnFamilyOptions(final long handle) { private ColumnFamilyOptions(final long handle) {
super(); super(handle);
nativeHandle_ = handle;
} }
private static native long getColumnFamilyOptionsFromProps( private static native long getColumnFamilyOptionsFromProps(
String optString); String optString);
private native void newColumnFamilyOptions(); private static native long newColumnFamilyOptions();
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native void optimizeForPointLookup(long handle, private native void optimizeForPointLookup(long handle,
long blockCacheSizeMb); long blockCacheSizeMb);
@ -688,12 +682,12 @@ public class ColumnFamilyOptions extends RocksObject
private native void optimizeUniversalStyleCompaction(long handle, private native void optimizeUniversalStyleCompaction(long handle,
long memtableMemoryBudget); long memtableMemoryBudget);
private native void setComparatorHandle(long handle, int builtinComparator); private native void setComparatorHandle(long handle, int builtinComparator);
private native void setComparatorHandle(long optHandle, long comparatorHandle); private native void setComparatorHandle(long optHandle,
private native void setMergeOperatorName( long comparatorHandle);
long handle, String name); private native void setMergeOperatorName(long handle, String name);
private native void setMergeOperator( private native void setMergeOperator(long handle, long mergeOperatorHandle);
long handle, long mergeOperatorHandle); private native void setCompactionFilterHandle(long handle,
private native void setCompactionFilterHandle(long handle, long compactionFilterHandle); long compactionFilterHandle);
private native void setWriteBufferSize(long handle, long writeBufferSize) private native void setWriteBufferSize(long handle, long writeBufferSize)
throws IllegalArgumentException; throws IllegalArgumentException;
private native long writeBufferSize(long handle); private native long writeBufferSize(long handle);
@ -706,8 +700,8 @@ public class ColumnFamilyOptions extends RocksObject
private native void setCompressionType(long handle, byte compressionType); private native void setCompressionType(long handle, byte compressionType);
private native byte compressionType(long handle); private native byte compressionType(long handle);
private native void setCompressionPerLevel(long handle, private native void setCompressionPerLevel(long handle,
List<Byte> compressionLevels); byte[] compressionLevels);
private native List<Byte> compressionPerLevel(long handle); private native byte[] compressionPerLevel(long handle);
private native void useFixedLengthPrefixExtractor( private native void useFixedLengthPrefixExtractor(
long handle, int prefixLength); long handle, int prefixLength);
private native void useCappedPrefixExtractor( private native void useCappedPrefixExtractor(

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

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

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

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

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

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

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

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

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

@ -12,8 +12,8 @@ import java.util.List;
* Options to control the behavior of a database. It will be used * Options to control the behavior of a database. It will be used
* during the creation of a {@link org.rocksdb.RocksDB} (i.e., RocksDB.open()). * during the creation of a {@link org.rocksdb.RocksDB} (i.e., RocksDB.open()).
* *
* If {@link #dispose()} function is not called, then it will be GC'd automatically * If {@link #dispose()} function is not called, then it will be GC'd
* and native resources will be released as part of the process. * automaticallyand native resources will be released as part of the process.
*/ */
public class Options extends RocksObject public class Options extends RocksObject
implements DBOptionsInterface, ColumnFamilyOptionsInterface { implements DBOptionsInterface, ColumnFamilyOptionsInterface {
@ -27,8 +27,7 @@ public class Options extends RocksObject
* an {@code rocksdb::Options} in the c++ side. * an {@code rocksdb::Options} in the c++ side.
*/ */
public Options() { public Options() {
super(); super(newOptions());
newOptions();
env_ = Env.getDefault(); env_ = Env.getDefault();
} }
@ -42,28 +41,28 @@ public class Options extends RocksObject
*/ */
public Options(final DBOptions dbOptions, public Options(final DBOptions dbOptions,
final ColumnFamilyOptions columnFamilyOptions) { final ColumnFamilyOptions columnFamilyOptions) {
super(); super(newOptions(dbOptions.nativeHandle_,
newOptions(dbOptions.nativeHandle_, columnFamilyOptions.nativeHandle_); columnFamilyOptions.nativeHandle_));
env_ = Env.getDefault(); env_ = Env.getDefault();
} }
@Override @Override
public Options setIncreaseParallelism(final int totalThreads) { public Options setIncreaseParallelism(final int totalThreads) {
assert(isInitialized()); assert(isOwningHandle());
setIncreaseParallelism(nativeHandle_, totalThreads); setIncreaseParallelism(nativeHandle_, totalThreads);
return this; return this;
} }
@Override @Override
public Options setCreateIfMissing(final boolean flag) { public Options setCreateIfMissing(final boolean flag) {
assert(isInitialized()); assert(isOwningHandle());
setCreateIfMissing(nativeHandle_, flag); setCreateIfMissing(nativeHandle_, flag);
return this; return this;
} }
@Override @Override
public Options setCreateMissingColumnFamilies(final boolean flag) { public Options setCreateMissingColumnFamilies(final boolean flag) {
assert(isInitialized()); assert(isOwningHandle());
setCreateMissingColumnFamilies(nativeHandle_, flag); setCreateMissingColumnFamilies(nativeHandle_, flag);
return this; return this;
} }
@ -77,7 +76,7 @@ public class Options extends RocksObject
* @return the instance of the current Options. * @return the instance of the current Options.
*/ */
public Options setEnv(final Env env) { public Options setEnv(final Env env) {
assert(isInitialized()); assert(isOwningHandle());
setEnv(nativeHandle_, env.nativeHandle_); setEnv(nativeHandle_, env.nativeHandle_);
env_ = env; env_ = env;
return this; return this;
@ -111,13 +110,13 @@ public class Options extends RocksObject
@Override @Override
public boolean createIfMissing() { public boolean createIfMissing() {
assert(isInitialized()); assert(isOwningHandle());
return createIfMissing(nativeHandle_); return createIfMissing(nativeHandle_);
} }
@Override @Override
public boolean createMissingColumnFamilies() { public boolean createMissingColumnFamilies() {
assert(isInitialized()); assert(isOwningHandle());
return createMissingColumnFamilies(nativeHandle_); return createMissingColumnFamilies(nativeHandle_);
} }
@ -161,7 +160,7 @@ public class Options extends RocksObject
@Override @Override
public Options setComparator(final BuiltinComparator builtinComparator) { public Options setComparator(final BuiltinComparator builtinComparator) {
assert(isInitialized()); assert(isOwningHandle());
setComparatorHandle(nativeHandle_, builtinComparator.ordinal()); setComparatorHandle(nativeHandle_, builtinComparator.ordinal());
return this; return this;
} }
@ -169,15 +168,15 @@ public class Options extends RocksObject
@Override @Override
public Options setComparator( public Options setComparator(
final AbstractComparator<? extends AbstractSlice<?>> comparator) { final AbstractComparator<? extends AbstractSlice<?>> comparator) {
assert (isInitialized()); assert(isOwningHandle());
setComparatorHandle(nativeHandle_, comparator.nativeHandle_); setComparatorHandle(nativeHandle_, comparator.getNativeHandle());
comparator_ = comparator; comparator_ = comparator;
return this; return this;
} }
@Override @Override
public Options setMergeOperatorName(final String name) { public Options setMergeOperatorName(final String name) {
assert (isInitialized()); assert(isOwningHandle());
if (name == null) { if (name == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Merge operator name must not be null."); "Merge operator name must not be null.");
@ -194,164 +193,164 @@ public class Options extends RocksObject
@Override @Override
public Options setWriteBufferSize(final long writeBufferSize) { public Options setWriteBufferSize(final long writeBufferSize) {
assert(isInitialized()); assert(isOwningHandle());
setWriteBufferSize(nativeHandle_, writeBufferSize); setWriteBufferSize(nativeHandle_, writeBufferSize);
return this; return this;
} }
@Override @Override
public long writeBufferSize() { public long writeBufferSize() {
assert(isInitialized()); assert(isOwningHandle());
return writeBufferSize(nativeHandle_); return writeBufferSize(nativeHandle_);
} }
@Override @Override
public Options setMaxWriteBufferNumber(final int maxWriteBufferNumber) { public Options setMaxWriteBufferNumber(final int maxWriteBufferNumber) {
assert(isInitialized()); assert(isOwningHandle());
setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber); setMaxWriteBufferNumber(nativeHandle_, maxWriteBufferNumber);
return this; return this;
} }
@Override @Override
public int maxWriteBufferNumber() { public int maxWriteBufferNumber() {
assert(isInitialized()); assert(isOwningHandle());
return maxWriteBufferNumber(nativeHandle_); return maxWriteBufferNumber(nativeHandle_);
} }
@Override @Override
public boolean errorIfExists() { public boolean errorIfExists() {
assert(isInitialized()); assert(isOwningHandle());
return errorIfExists(nativeHandle_); return errorIfExists(nativeHandle_);
} }
@Override @Override
public Options setErrorIfExists(final boolean errorIfExists) { public Options setErrorIfExists(final boolean errorIfExists) {
assert(isInitialized()); assert(isOwningHandle());
setErrorIfExists(nativeHandle_, errorIfExists); setErrorIfExists(nativeHandle_, errorIfExists);
return this; return this;
} }
@Override @Override
public boolean paranoidChecks() { public boolean paranoidChecks() {
assert(isInitialized()); assert(isOwningHandle());
return paranoidChecks(nativeHandle_); return paranoidChecks(nativeHandle_);
} }
@Override @Override
public Options setParanoidChecks(final boolean paranoidChecks) { public Options setParanoidChecks(final boolean paranoidChecks) {
assert(isInitialized()); assert(isOwningHandle());
setParanoidChecks(nativeHandle_, paranoidChecks); setParanoidChecks(nativeHandle_, paranoidChecks);
return this; return this;
} }
@Override @Override
public int maxOpenFiles() { public int maxOpenFiles() {
assert(isInitialized()); assert(isOwningHandle());
return maxOpenFiles(nativeHandle_); return maxOpenFiles(nativeHandle_);
} }
@Override @Override
public Options setMaxTotalWalSize(final long maxTotalWalSize) { public Options setMaxTotalWalSize(final long maxTotalWalSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxTotalWalSize(nativeHandle_, maxTotalWalSize); setMaxTotalWalSize(nativeHandle_, maxTotalWalSize);
return this; return this;
} }
@Override @Override
public long maxTotalWalSize() { public long maxTotalWalSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxTotalWalSize(nativeHandle_); return maxTotalWalSize(nativeHandle_);
} }
@Override @Override
public Options setMaxOpenFiles(final int maxOpenFiles) { public Options setMaxOpenFiles(final int maxOpenFiles) {
assert(isInitialized()); assert(isOwningHandle());
setMaxOpenFiles(nativeHandle_, maxOpenFiles); setMaxOpenFiles(nativeHandle_, maxOpenFiles);
return this; return this;
} }
@Override @Override
public boolean disableDataSync() { public boolean disableDataSync() {
assert(isInitialized()); assert(isOwningHandle());
return disableDataSync(nativeHandle_); return disableDataSync(nativeHandle_);
} }
@Override @Override
public Options setDisableDataSync(final boolean disableDataSync) { public Options setDisableDataSync(final boolean disableDataSync) {
assert(isInitialized()); assert(isOwningHandle());
setDisableDataSync(nativeHandle_, disableDataSync); setDisableDataSync(nativeHandle_, disableDataSync);
return this; return this;
} }
@Override @Override
public boolean useFsync() { public boolean useFsync() {
assert(isInitialized()); assert(isOwningHandle());
return useFsync(nativeHandle_); return useFsync(nativeHandle_);
} }
@Override @Override
public Options setUseFsync(final boolean useFsync) { public Options setUseFsync(final boolean useFsync) {
assert(isInitialized()); assert(isOwningHandle());
setUseFsync(nativeHandle_, useFsync); setUseFsync(nativeHandle_, useFsync);
return this; return this;
} }
@Override @Override
public String dbLogDir() { public String dbLogDir() {
assert(isInitialized()); assert(isOwningHandle());
return dbLogDir(nativeHandle_); return dbLogDir(nativeHandle_);
} }
@Override @Override
public Options setDbLogDir(final String dbLogDir) { public Options setDbLogDir(final String dbLogDir) {
assert(isInitialized()); assert(isOwningHandle());
setDbLogDir(nativeHandle_, dbLogDir); setDbLogDir(nativeHandle_, dbLogDir);
return this; return this;
} }
@Override @Override
public String walDir() { public String walDir() {
assert(isInitialized()); assert(isOwningHandle());
return walDir(nativeHandle_); return walDir(nativeHandle_);
} }
@Override @Override
public Options setWalDir(final String walDir) { public Options setWalDir(final String walDir) {
assert(isInitialized()); assert(isOwningHandle());
setWalDir(nativeHandle_, walDir); setWalDir(nativeHandle_, walDir);
return this; return this;
} }
@Override @Override
public long deleteObsoleteFilesPeriodMicros() { public long deleteObsoleteFilesPeriodMicros() {
assert(isInitialized()); assert(isOwningHandle());
return deleteObsoleteFilesPeriodMicros(nativeHandle_); return deleteObsoleteFilesPeriodMicros(nativeHandle_);
} }
@Override @Override
public Options setDeleteObsoleteFilesPeriodMicros( public Options setDeleteObsoleteFilesPeriodMicros(
final long micros) { final long micros) {
assert(isInitialized()); assert(isOwningHandle());
setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros); setDeleteObsoleteFilesPeriodMicros(nativeHandle_, micros);
return this; return this;
} }
@Override @Override
public int maxBackgroundCompactions() { public int maxBackgroundCompactions() {
assert(isInitialized()); assert(isOwningHandle());
return maxBackgroundCompactions(nativeHandle_); return maxBackgroundCompactions(nativeHandle_);
} }
@Override @Override
public Options createStatistics() { public Options createStatistics() {
assert(isInitialized()); assert(isOwningHandle());
createStatistics(nativeHandle_); createStatistics(nativeHandle_);
return this; return this;
} }
@Override @Override
public Statistics statisticsPtr() { public Statistics statisticsPtr() {
assert(isInitialized()); assert(isOwningHandle());
long statsPtr = statisticsPtr(nativeHandle_); long statsPtr = statisticsPtr(nativeHandle_);
if(statsPtr == 0) { if(statsPtr == 0) {
@ -365,74 +364,74 @@ public class Options extends RocksObject
@Override @Override
public Options setMaxBackgroundCompactions( public Options setMaxBackgroundCompactions(
final int maxBackgroundCompactions) { final int maxBackgroundCompactions) {
assert(isInitialized()); assert(isOwningHandle());
setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions); setMaxBackgroundCompactions(nativeHandle_, maxBackgroundCompactions);
return this; return this;
} }
@Override @Override
public int maxBackgroundFlushes() { public int maxBackgroundFlushes() {
assert(isInitialized()); assert(isOwningHandle());
return maxBackgroundFlushes(nativeHandle_); return maxBackgroundFlushes(nativeHandle_);
} }
@Override @Override
public Options setMaxBackgroundFlushes( public Options setMaxBackgroundFlushes(
final int maxBackgroundFlushes) { final int maxBackgroundFlushes) {
assert(isInitialized()); assert(isOwningHandle());
setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes); setMaxBackgroundFlushes(nativeHandle_, maxBackgroundFlushes);
return this; return this;
} }
@Override @Override
public long maxLogFileSize() { public long maxLogFileSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxLogFileSize(nativeHandle_); return maxLogFileSize(nativeHandle_);
} }
@Override @Override
public Options setMaxLogFileSize(final long maxLogFileSize) { public Options setMaxLogFileSize(final long maxLogFileSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxLogFileSize(nativeHandle_, maxLogFileSize); setMaxLogFileSize(nativeHandle_, maxLogFileSize);
return this; return this;
} }
@Override @Override
public long logFileTimeToRoll() { public long logFileTimeToRoll() {
assert(isInitialized()); assert(isOwningHandle());
return logFileTimeToRoll(nativeHandle_); return logFileTimeToRoll(nativeHandle_);
} }
@Override @Override
public Options setLogFileTimeToRoll(final long logFileTimeToRoll) { public Options setLogFileTimeToRoll(final long logFileTimeToRoll) {
assert(isInitialized()); assert(isOwningHandle());
setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll); setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll);
return this; return this;
} }
@Override @Override
public long keepLogFileNum() { public long keepLogFileNum() {
assert(isInitialized()); assert(isOwningHandle());
return keepLogFileNum(nativeHandle_); return keepLogFileNum(nativeHandle_);
} }
@Override @Override
public Options setKeepLogFileNum(final long keepLogFileNum) { public Options setKeepLogFileNum(final long keepLogFileNum) {
assert(isInitialized()); assert(isOwningHandle());
setKeepLogFileNum(nativeHandle_, keepLogFileNum); setKeepLogFileNum(nativeHandle_, keepLogFileNum);
return this; return this;
} }
@Override @Override
public long maxManifestFileSize() { public long maxManifestFileSize() {
assert(isInitialized()); assert(isOwningHandle());
return maxManifestFileSize(nativeHandle_); return maxManifestFileSize(nativeHandle_);
} }
@Override @Override
public Options setMaxManifestFileSize( public Options setMaxManifestFileSize(
final long maxManifestFileSize) { final long maxManifestFileSize) {
assert(isInitialized()); assert(isOwningHandle());
setMaxManifestFileSize(nativeHandle_, maxManifestFileSize); setMaxManifestFileSize(nativeHandle_, maxManifestFileSize);
return this; return this;
} }
@ -441,7 +440,7 @@ public class Options extends RocksObject
public Options setMaxTableFilesSizeFIFO( public Options setMaxTableFilesSizeFIFO(
final long maxTableFilesSize) { final long maxTableFilesSize) {
assert(maxTableFilesSize > 0); // unsigned native type assert(maxTableFilesSize > 0); // unsigned native type
assert(isInitialized()); assert(isOwningHandle());
setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize); setMaxTableFilesSizeFIFO(nativeHandle_, maxTableFilesSize);
return this; return this;
} }
@ -453,118 +452,118 @@ public class Options extends RocksObject
@Override @Override
public int tableCacheNumshardbits() { public int tableCacheNumshardbits() {
assert(isInitialized()); assert(isOwningHandle());
return tableCacheNumshardbits(nativeHandle_); return tableCacheNumshardbits(nativeHandle_);
} }
@Override @Override
public Options setTableCacheNumshardbits( public Options setTableCacheNumshardbits(
final int tableCacheNumshardbits) { final int tableCacheNumshardbits) {
assert(isInitialized()); assert(isOwningHandle());
setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits); setTableCacheNumshardbits(nativeHandle_, tableCacheNumshardbits);
return this; return this;
} }
@Override @Override
public long walTtlSeconds() { public long walTtlSeconds() {
assert(isInitialized()); assert(isOwningHandle());
return walTtlSeconds(nativeHandle_); return walTtlSeconds(nativeHandle_);
} }
@Override @Override
public Options setWalTtlSeconds(final long walTtlSeconds) { public Options setWalTtlSeconds(final long walTtlSeconds) {
assert(isInitialized()); assert(isOwningHandle());
setWalTtlSeconds(nativeHandle_, walTtlSeconds); setWalTtlSeconds(nativeHandle_, walTtlSeconds);
return this; return this;
} }
@Override @Override
public long walSizeLimitMB() { public long walSizeLimitMB() {
assert(isInitialized()); assert(isOwningHandle());
return walSizeLimitMB(nativeHandle_); return walSizeLimitMB(nativeHandle_);
} }
@Override @Override
public Options setWalSizeLimitMB(final long sizeLimitMB) { public Options setWalSizeLimitMB(final long sizeLimitMB) {
assert(isInitialized()); assert(isOwningHandle());
setWalSizeLimitMB(nativeHandle_, sizeLimitMB); setWalSizeLimitMB(nativeHandle_, sizeLimitMB);
return this; return this;
} }
@Override @Override
public long manifestPreallocationSize() { public long manifestPreallocationSize() {
assert(isInitialized()); assert(isOwningHandle());
return manifestPreallocationSize(nativeHandle_); return manifestPreallocationSize(nativeHandle_);
} }
@Override @Override
public Options setManifestPreallocationSize(final long size) { public Options setManifestPreallocationSize(final long size) {
assert(isInitialized()); assert(isOwningHandle());
setManifestPreallocationSize(nativeHandle_, size); setManifestPreallocationSize(nativeHandle_, size);
return this; return this;
} }
@Override @Override
public boolean allowOsBuffer() { public boolean allowOsBuffer() {
assert(isInitialized()); assert(isOwningHandle());
return allowOsBuffer(nativeHandle_); return allowOsBuffer(nativeHandle_);
} }
@Override @Override
public Options setAllowOsBuffer(final boolean allowOsBuffer) { public Options setAllowOsBuffer(final boolean allowOsBuffer) {
assert(isInitialized()); assert(isOwningHandle());
setAllowOsBuffer(nativeHandle_, allowOsBuffer); setAllowOsBuffer(nativeHandle_, allowOsBuffer);
return this; return this;
} }
@Override @Override
public boolean allowMmapReads() { public boolean allowMmapReads() {
assert(isInitialized()); assert(isOwningHandle());
return allowMmapReads(nativeHandle_); return allowMmapReads(nativeHandle_);
} }
@Override @Override
public Options setAllowMmapReads(final boolean allowMmapReads) { public Options setAllowMmapReads(final boolean allowMmapReads) {
assert(isInitialized()); assert(isOwningHandle());
setAllowMmapReads(nativeHandle_, allowMmapReads); setAllowMmapReads(nativeHandle_, allowMmapReads);
return this; return this;
} }
@Override @Override
public boolean allowMmapWrites() { public boolean allowMmapWrites() {
assert(isInitialized()); assert(isOwningHandle());
return allowMmapWrites(nativeHandle_); return allowMmapWrites(nativeHandle_);
} }
@Override @Override
public Options setAllowMmapWrites(final boolean allowMmapWrites) { public Options setAllowMmapWrites(final boolean allowMmapWrites) {
assert(isInitialized()); assert(isOwningHandle());
setAllowMmapWrites(nativeHandle_, allowMmapWrites); setAllowMmapWrites(nativeHandle_, allowMmapWrites);
return this; return this;
} }
@Override @Override
public boolean isFdCloseOnExec() { public boolean isFdCloseOnExec() {
assert(isInitialized()); assert(isOwningHandle());
return isFdCloseOnExec(nativeHandle_); return isFdCloseOnExec(nativeHandle_);
} }
@Override @Override
public Options setIsFdCloseOnExec(final boolean isFdCloseOnExec) { public Options setIsFdCloseOnExec(final boolean isFdCloseOnExec) {
assert(isInitialized()); assert(isOwningHandle());
setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec); setIsFdCloseOnExec(nativeHandle_, isFdCloseOnExec);
return this; return this;
} }
@Override @Override
public int statsDumpPeriodSec() { public int statsDumpPeriodSec() {
assert(isInitialized()); assert(isOwningHandle());
return statsDumpPeriodSec(nativeHandle_); return statsDumpPeriodSec(nativeHandle_);
} }
@Override @Override
public Options setStatsDumpPeriodSec(final int statsDumpPeriodSec) { public Options setStatsDumpPeriodSec(final int statsDumpPeriodSec) {
assert(isInitialized()); assert(isOwningHandle());
setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec); setStatsDumpPeriodSec(nativeHandle_, statsDumpPeriodSec);
return this; return this;
} }
@ -576,20 +575,20 @@ public class Options extends RocksObject
@Override @Override
public Options setAdviseRandomOnOpen(final boolean adviseRandomOnOpen) { public Options setAdviseRandomOnOpen(final boolean adviseRandomOnOpen) {
assert(isInitialized()); assert(isOwningHandle());
setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen); setAdviseRandomOnOpen(nativeHandle_, adviseRandomOnOpen);
return this; return this;
} }
@Override @Override
public boolean useAdaptiveMutex() { public boolean useAdaptiveMutex() {
assert(isInitialized()); assert(isOwningHandle());
return useAdaptiveMutex(nativeHandle_); return useAdaptiveMutex(nativeHandle_);
} }
@Override @Override
public Options setUseAdaptiveMutex(final boolean useAdaptiveMutex) { public Options setUseAdaptiveMutex(final boolean useAdaptiveMutex) {
assert(isInitialized()); assert(isOwningHandle());
setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex); setUseAdaptiveMutex(nativeHandle_, useAdaptiveMutex);
return this; return this;
} }
@ -601,7 +600,7 @@ public class Options extends RocksObject
@Override @Override
public Options setBytesPerSync(final long bytesPerSync) { public Options setBytesPerSync(final long bytesPerSync) {
assert(isInitialized()); assert(isOwningHandle());
setBytesPerSync(nativeHandle_, bytesPerSync); setBytesPerSync(nativeHandle_, bytesPerSync);
return this; return this;
} }
@ -622,28 +621,28 @@ public class Options extends RocksObject
@Override @Override
public Options setLogger(final Logger logger) { public Options setLogger(final Logger logger) {
assert(isInitialized()); assert(isOwningHandle());
setLogger(nativeHandle_, logger.nativeHandle_); setLogger(nativeHandle_, logger.nativeHandle_);
return this; return this;
} }
@Override @Override
public Options setInfoLogLevel(final InfoLogLevel infoLogLevel) { public Options setInfoLogLevel(final InfoLogLevel infoLogLevel) {
assert(isInitialized()); assert(isOwningHandle());
setInfoLogLevel(nativeHandle_, infoLogLevel.getValue()); setInfoLogLevel(nativeHandle_, infoLogLevel.getValue());
return this; return this;
} }
@Override @Override
public InfoLogLevel infoLogLevel() { public InfoLogLevel infoLogLevel() {
assert(isInitialized()); assert(isOwningHandle());
return InfoLogLevel.getInfoLogLevel( return InfoLogLevel.getInfoLogLevel(
infoLogLevel(nativeHandle_)); infoLogLevel(nativeHandle_));
} }
@Override @Override
public String memTableFactoryName() { public String memTableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return memTableFactoryName(nativeHandle_); return memTableFactoryName(nativeHandle_);
} }
@ -656,20 +655,20 @@ public class Options extends RocksObject
@Override @Override
public String tableFactoryName() { public String tableFactoryName() {
assert(isInitialized()); assert(isOwningHandle());
return tableFactoryName(nativeHandle_); return tableFactoryName(nativeHandle_);
} }
@Override @Override
public Options useFixedLengthPrefixExtractor(final int n) { public Options useFixedLengthPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useFixedLengthPrefixExtractor(nativeHandle_, n); useFixedLengthPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@Override @Override
public Options useCappedPrefixExtractor(final int n) { public Options useCappedPrefixExtractor(final int n) {
assert(isInitialized()); assert(isOwningHandle());
useCappedPrefixExtractor(nativeHandle_, n); useCappedPrefixExtractor(nativeHandle_, n);
return this; return this;
} }
@ -680,11 +679,12 @@ public class Options extends RocksObject
} }
@Override @Override
public Options setCompressionPerLevel(final List<CompressionType> compressionLevels) { public Options setCompressionPerLevel(
final List<Byte> byteCompressionTypes = new ArrayList<>( final List<CompressionType> compressionLevels) {
compressionLevels.size()); final byte[] byteCompressionTypes = new byte[
for (final CompressionType compressionLevel : compressionLevels) { compressionLevels.size()];
byteCompressionTypes.add(compressionLevel.getValue()); for (int i = 0; i < compressionLevels.size(); i++) {
byteCompressionTypes[i] = compressionLevels.get(i).getValue();
} }
setCompressionPerLevel(nativeHandle_, byteCompressionTypes); setCompressionPerLevel(nativeHandle_, byteCompressionTypes);
return this; return this;
@ -692,7 +692,7 @@ public class Options extends RocksObject
@Override @Override
public List<CompressionType> compressionPerLevel() { public List<CompressionType> compressionPerLevel() {
final List<Byte> byteCompressionTypes = final byte[] byteCompressionTypes =
compressionPerLevel(nativeHandle_); compressionPerLevel(nativeHandle_);
final List<CompressionType> compressionLevels = new ArrayList<>(); final List<CompressionType> compressionLevels = new ArrayList<>();
for (final Byte byteCompressionType : byteCompressionTypes) { for (final Byte byteCompressionType : byteCompressionTypes) {
@ -975,7 +975,8 @@ public class Options extends RocksObject
@Override @Override
public Options setMaxSequentialSkipInIterations( public Options setMaxSequentialSkipInIterations(
final long maxSequentialSkipInIterations) { final long maxSequentialSkipInIterations) {
setMaxSequentialSkipInIterations(nativeHandle_, maxSequentialSkipInIterations); setMaxSequentialSkipInIterations(nativeHandle_,
maxSequentialSkipInIterations);
return this; return this;
} }
@ -1085,19 +1086,10 @@ public class Options extends RocksObject
return optimizeFiltersForHits(nativeHandle_); return optimizeFiltersForHits(nativeHandle_);
} }
/** private native static long newOptions();
* Release the memory allocated for the current instance private native static long newOptions(long dbOptHandle,
* in the c++ side.
*/
@Override protected void disposeInternal() {
assert(isInitialized());
disposeInternal(nativeHandle_);
}
private native void newOptions();
private native void newOptions(long dbOptHandle,
long cfOptHandle); long cfOptHandle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native void setEnv(long optHandle, long envHandle); private native void setEnv(long optHandle, long envHandle);
private native void prepareForBulkLoad(long handle); private native void prepareForBulkLoad(long handle);
@ -1200,7 +1192,8 @@ public class Options extends RocksObject
private native void optimizeUniversalStyleCompaction(long handle, private native void optimizeUniversalStyleCompaction(long handle,
long memtableMemoryBudget); long memtableMemoryBudget);
private native void setComparatorHandle(long handle, int builtinComparator); private native void setComparatorHandle(long handle, int builtinComparator);
private native void setComparatorHandle(long optHandle, long comparatorHandle); private native void setComparatorHandle(long optHandle,
long comparatorHandle);
private native void setMergeOperatorName( private native void setMergeOperatorName(
long handle, String name); long handle, String name);
private native void setMergeOperator( private native void setMergeOperator(
@ -1217,8 +1210,8 @@ public class Options extends RocksObject
private native void setCompressionType(long handle, byte compressionType); private native void setCompressionType(long handle, byte compressionType);
private native byte compressionType(long handle); private native byte compressionType(long handle);
private native void setCompressionPerLevel(long handle, private native void setCompressionPerLevel(long handle,
List<Byte> compressionLevels); byte[] compressionLevels);
private native List<Byte> compressionPerLevel(long handle); private native byte[] compressionPerLevel(long handle);
private native void useFixedLengthPrefixExtractor( private native void useFixedLengthPrefixExtractor(
long handle, int prefixLength); long handle, int prefixLength);
private native void useCappedPrefixExtractor( private native void useCappedPrefixExtractor(

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

@ -8,11 +8,11 @@ package org.rocksdb;
/** /**
* Just a Java wrapper around EmptyValueCompactionFilter implemented in C++ * Just a Java wrapper around EmptyValueCompactionFilter implemented in C++
*/ */
public class RemoveEmptyValueCompactionFilter extends AbstractCompactionFilter<Slice> { public class RemoveEmptyValueCompactionFilter
extends AbstractCompactionFilter<Slice> {
public RemoveEmptyValueCompactionFilter() { public RemoveEmptyValueCompactionFilter() {
super(); super(createNewRemoveEmptyValueCompactionFilter0());
createNewRemoveEmptyValueCompactionFilter0();
} }
private native void createNewRemoveEmptyValueCompactionFilter0(); private native static long createNewRemoveEmptyValueCompactionFilter0();
} }

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

@ -16,26 +16,17 @@ public class RestoreOptions extends RocksObject {
/** /**
* Constructor * Constructor
* *
* @param keepLogFiles If true, restore won't overwrite the existing log files in wal_dir. It * @param keepLogFiles If true, restore won't overwrite the existing log files
* will also move all log files from archive directory to wal_dir. Use this * in wal_dir. It will also move all log files from archive directory to
* option in combination with BackupableDBOptions::backup_log_files = false * wal_dir. Use this option in combination with
* for persisting in-memory databases. * BackupableDBOptions::backup_log_files = false for persisting in-memory
* databases.
* Default: false * Default: false
*/ */
public RestoreOptions(final boolean keepLogFiles) { public RestoreOptions(final boolean keepLogFiles) {
super(); super(newRestoreOptions(keepLogFiles));
nativeHandle_ = newRestoreOptions(keepLogFiles);
} }
/** private native static long newRestoreOptions(boolean keepLogFiles);
* Release the memory allocated for the current instance @Override protected final native void disposeInternal(final long handle);
* in the c++ side.
*/
@Override public synchronized void disposeInternal() {
assert(isInitialized());
dispose(nativeHandle_);
}
private native long newRestoreOptions(boolean keepLogFiles);
private native void dispose(long handle);
} }

@ -48,7 +48,8 @@ public class RocksDB extends RocksObject {
} }
catch (IOException e) catch (IOException e)
{ {
throw new RuntimeException("Unable to load the RocksDB shared library" + e); throw new RuntimeException("Unable to load the RocksDB shared library"
+ e);
} }
} }
@ -78,7 +79,8 @@ public class RocksDB extends RocksObject {
UnsatisfiedLinkError err = null; UnsatisfiedLinkError err = null;
for (String path : paths) { for (String path : paths) {
try { try {
System.load(path + "/" + Environment.getJniLibraryFileName("rocksdbjni")); System.load(path + "/" +
Environment.getJniLibraryFileName("rocksdbjni"));
success = true; success = true;
break; break;
} catch (UnsatisfiedLinkError e) { } catch (UnsatisfiedLinkError e) {
@ -116,8 +118,8 @@ public class RocksDB extends RocksObject {
* the path to the database using the specified options and db path and a list * the path to the database using the specified options and db path and a list
* of column family names. * of column family names.
* <p> * <p>
* If opened in read write mode every existing column family name must be passed * If opened in read write mode every existing column family name must be
* within the list to this method.</p> * passed within the list to this method.</p>
* <p> * <p>
* If opened in read-only mode only a subset of existing column families must * If opened in read-only mode only a subset of existing column families must
* be passed to this method.</p> * be passed to this method.</p>
@ -179,9 +181,7 @@ public class RocksDB extends RocksObject {
// when non-default Options is used, keeping an Options reference // when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of // in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB. // the currently-created RocksDB.
RocksDB db = new RocksDB(); final RocksDB db = new RocksDB(open(options.nativeHandle_, path));
db.open(options.nativeHandle_, path);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
return db; return db;
} }
@ -191,8 +191,8 @@ public class RocksDB extends RocksObject {
* the path to the database using the specified options and db path and a list * the path to the database using the specified options and db path and a list
* of column family names. * of column family names.
* <p> * <p>
* If opened in read write mode every existing column family name must be passed * If opened in read write mode every existing column family name must be
* within the list to this method.</p> * passed within the list to this method.</p>
* <p> * <p>
* If opened in read-only mode only a subset of existing column families must * If opened in read-only mode only a subset of existing column families must
* be passed to this method.</p> * be passed to this method.</p>
@ -206,7 +206,8 @@ public class RocksDB extends RocksObject {
* with new Options instance as underlying native statistics instance does not * with new Options instance as underlying native statistics instance does not
* use any locks to prevent concurrent updates.</p> * use any locks to prevent concurrent updates.</p>
* <p> * <p>
* ColumnFamily handles are disposed when the RocksDB instance is disposed.</p> * ColumnFamily handles are disposed when the RocksDB instance is disposed.
* </p>
* *
* @param options {@link org.rocksdb.DBOptions} instance. * @param options {@link org.rocksdb.DBOptions} instance.
* @param path the path to the rocksdb. * @param path the path to the rocksdb.
@ -225,13 +226,25 @@ public class RocksDB extends RocksObject {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors, final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
final List<ColumnFamilyHandle> columnFamilyHandles) final List<ColumnFamilyHandle> columnFamilyHandles)
throws RocksDBException { throws RocksDBException {
RocksDB db = new RocksDB();
List<Long> cfReferences = db.open(options.nativeHandle_, path, final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
columnFamilyDescriptors, columnFamilyDescriptors.size()); final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) { for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, cfReferences.get(i))); final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors
.get(i);
cfNames[i] = cfDescriptor.columnFamilyName();
cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_;
} }
final long[] handles = open(options.nativeHandle_, path, cfNames,
cfOptionHandles);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
}
return db; return db;
} }
@ -276,7 +289,7 @@ public class RocksDB extends RocksObject {
throws RocksDBException { throws RocksDBException {
// This allows to use the rocksjni default Options instead of // This allows to use the rocksjni default Options instead of
// the c++ one. // the c++ one.
DBOptions options = new DBOptions(); final DBOptions options = new DBOptions();
return openReadOnly(options, path, columnFamilyDescriptors, return openReadOnly(options, path, columnFamilyDescriptors,
columnFamilyHandles); columnFamilyHandles);
} }
@ -303,9 +316,7 @@ public class RocksDB extends RocksObject {
// when non-default Options is used, keeping an Options reference // when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of // in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB. // the currently-created RocksDB.
RocksDB db = new RocksDB(); final RocksDB db = new RocksDB(openROnly(options.nativeHandle_, path));
db.openROnly(options.nativeHandle_, path);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
return db; return db;
} }
@ -339,14 +350,25 @@ public class RocksDB extends RocksObject {
// when non-default Options is used, keeping an Options reference // when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of // in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB. // the currently-created RocksDB.
RocksDB db = new RocksDB();
List<Long> cfReferences = db.openROnly(options.nativeHandle_, path, final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
columnFamilyDescriptors, columnFamilyDescriptors.size()); final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) { for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, cfReferences.get(i))); final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors
.get(i);
cfNames[i] = cfDescriptor.columnFamilyName();
cfOptionHandles[i] = cfDescriptor.columnFamilyOptions().nativeHandle_;
} }
final long[] handles = openROnly(options.nativeHandle_, path, cfNames,
cfOptionHandles);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options); db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
}
return db; return db;
} }
/** /**
@ -362,28 +384,14 @@ public class RocksDB extends RocksObject {
*/ */
public static List<byte[]> listColumnFamilies(final Options options, public static List<byte[]> listColumnFamilies(final Options options,
final String path) throws RocksDBException { final String path) throws RocksDBException {
return RocksDB.listColumnFamilies(options.nativeHandle_, path); return Arrays.asList(RocksDB.listColumnFamilies(options.nativeHandle_,
path));
} }
private void storeOptionsInstance(DBOptionsInterface options) { private void storeOptionsInstance(DBOptionsInterface options) {
options_ = options; options_ = options;
} }
@Override protected void disposeInternal() {
synchronized (this) {
assert (isInitialized());
disposeInternal(nativeHandle_);
}
}
/**
* Close the RocksDB instance.
* This function is equivalent to dispose().
*/
public void close() {
dispose();
}
/** /**
* Set the database entry for "key" to "value". * Set the database entry for "key" to "value".
* *
@ -393,7 +401,8 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying * @throws RocksDBException thrown if error happens in underlying
* native library. * native library.
*/ */
public void put(final byte[] key, final byte[] value) throws RocksDBException { public void put(final byte[] key, final byte[] value)
throws RocksDBException {
put(nativeHandle_, key, key.length, value, value.length); put(nativeHandle_, key, key.length, value, value.length);
} }
@ -452,8 +461,8 @@ public class RocksDB extends RocksObject {
public void put(final ColumnFamilyHandle columnFamilyHandle, public void put(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpts, final byte[] key, final WriteOptions writeOpts, final byte[] key,
final byte[] value) throws RocksDBException { final byte[] value) throws RocksDBException {
put(nativeHandle_, writeOpts.nativeHandle_, key, key.length, value, value.length, put(nativeHandle_, writeOpts.nativeHandle_, key, key.length, value,
columnFamilyHandle.nativeHandle_); value.length, columnFamilyHandle.nativeHandle_);
} }
/** /**
@ -469,7 +478,7 @@ public class RocksDB extends RocksObject {
* @return boolean value indicating if key does not exist or might exist. * @return boolean value indicating if key does not exist or might exist.
*/ */
public boolean keyMayExist(final byte[] key, final StringBuffer value){ public boolean keyMayExist(final byte[] key, final StringBuffer value){
return keyMayExist(key, key.length, value); return keyMayExist(nativeHandle_, key, key.length, value);
} }
/** /**
@ -487,8 +496,8 @@ public class RocksDB extends RocksObject {
*/ */
public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle, public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final StringBuffer value){ final byte[] key, final StringBuffer value){
return keyMayExist(key, key.length, columnFamilyHandle.nativeHandle_, return keyMayExist(nativeHandle_, key, key.length,
value); columnFamilyHandle.nativeHandle_, value);
} }
/** /**
@ -506,7 +515,7 @@ public class RocksDB extends RocksObject {
*/ */
public boolean keyMayExist(final ReadOptions readOptions, public boolean keyMayExist(final ReadOptions readOptions,
final byte[] key, final StringBuffer value){ final byte[] key, final StringBuffer value){
return keyMayExist(readOptions.nativeHandle_, return keyMayExist(nativeHandle_, readOptions.nativeHandle_,
key, key.length, value); key, key.length, value);
} }
@ -527,7 +536,7 @@ public class RocksDB extends RocksObject {
public boolean keyMayExist(final ReadOptions readOptions, public boolean keyMayExist(final ReadOptions readOptions,
final ColumnFamilyHandle columnFamilyHandle, final byte[] key, final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final StringBuffer value){ final StringBuffer value){
return keyMayExist(readOptions.nativeHandle_, return keyMayExist(nativeHandle_, readOptions.nativeHandle_,
key, key.length, columnFamilyHandle.nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_,
value); value);
} }
@ -543,7 +552,7 @@ public class RocksDB extends RocksObject {
*/ */
public void write(final WriteOptions writeOpts, final WriteBatch updates) public void write(final WriteOptions writeOpts, final WriteBatch updates)
throws RocksDBException { throws RocksDBException {
write0(writeOpts.nativeHandle_, updates.nativeHandle_); write0(nativeHandle_, writeOpts.nativeHandle_, updates.nativeHandle_);
} }
/** /**
@ -557,7 +566,7 @@ public class RocksDB extends RocksObject {
*/ */
public void write(final WriteOptions writeOpts, public void write(final WriteOptions writeOpts,
final WriteBatchWithIndex updates) throws RocksDBException { final WriteBatchWithIndex updates) throws RocksDBException {
write1(writeOpts.nativeHandle_, updates.nativeHandle_); write1(nativeHandle_, writeOpts.nativeHandle_, updates.nativeHandle_);
} }
/** /**
@ -570,7 +579,8 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying * @throws RocksDBException thrown if error happens in underlying
* native library. * native library.
*/ */
public void merge(final byte[] key, final byte[] value) throws RocksDBException { public void merge(final byte[] key, final byte[] value)
throws RocksDBException {
merge(nativeHandle_, key, key.length, value, value.length); merge(nativeHandle_, key, key.length, value, value.length);
} }
@ -745,9 +755,10 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying * @throws RocksDBException thrown if error happens in underlying
* native library. * native library.
*/ */
public byte[] get(final ColumnFamilyHandle columnFamilyHandle, final byte[] key) public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
throws RocksDBException { final byte[] key) throws RocksDBException {
return get(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_); return get(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
} }
/** /**
@ -803,16 +814,16 @@ public class RocksDB extends RocksObject {
throws RocksDBException { throws RocksDBException {
assert(keys.size() != 0); assert(keys.size() != 0);
List<byte[]> values = multiGet( final byte[][] values = multiGet(nativeHandle_,
nativeHandle_, keys, keys.size()); keys.toArray(new byte[keys.size()][]));
Map<byte[], byte[]> keyValueMap = new HashMap<>(); Map<byte[], byte[]> keyValueMap = new HashMap<>();
for(int i = 0; i < values.size(); i++) { for(int i = 0; i < values.length; i++) {
if(values.get(i) == null) { if(values[i] == null) {
continue; continue;
} }
keyValueMap.put(keys.get(i), values.get(i)); keyValueMap.put(keys.get(i), values[i]);
} }
return keyValueMap; return keyValueMap;
@ -836,8 +847,10 @@ public class RocksDB extends RocksObject {
* @throws IllegalArgumentException thrown if the size of passed keys is not * @throws IllegalArgumentException thrown if the size of passed keys is not
* equal to the amount of passed column family handles. * equal to the amount of passed column family handles.
*/ */
public Map<byte[], byte[]> multiGet(final List<ColumnFamilyHandle> columnFamilyHandleList, public Map<byte[], byte[]> multiGet(
final List<byte[]> keys) throws RocksDBException, IllegalArgumentException { final List<ColumnFamilyHandle> columnFamilyHandleList,
final List<byte[]> keys) throws RocksDBException,
IllegalArgumentException {
assert(keys.size() != 0); assert(keys.size() != 0);
// Check if key size equals cfList size. If not a exception must be // Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens. // thrown. If not a Segmentation fault happens.
@ -845,15 +858,19 @@ public class RocksDB extends RocksObject {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"For each key there must be a ColumnFamilyHandle."); "For each key there must be a ColumnFamilyHandle.");
} }
List<byte[]> values = multiGet(nativeHandle_, keys, keys.size(), final long[] cfHandles = new long[columnFamilyHandleList.size()];
columnFamilyHandleList); for (int i = 0; i < columnFamilyHandleList.size(); i++) {
cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final byte[][] values = multiGet(nativeHandle_,
keys.toArray(new byte[keys.size()][]), cfHandles);
Map<byte[], byte[]> keyValueMap = new HashMap<>(); Map<byte[], byte[]> keyValueMap = new HashMap<>();
for(int i = 0; i < values.size(); i++) { for(int i = 0; i < values.length; i++) {
if (values.get(i) == null) { if (values[i] == null) {
continue; continue;
} }
keyValueMap.put(keys.get(i), values.get(i)); keyValueMap.put(keys.get(i), values[i]);
} }
return keyValueMap; return keyValueMap;
} }
@ -873,16 +890,16 @@ public class RocksDB extends RocksObject {
final List<byte[]> keys) throws RocksDBException { final List<byte[]> keys) throws RocksDBException {
assert(keys.size() != 0); assert(keys.size() != 0);
List<byte[]> values = multiGet( final byte[][] values = multiGet(nativeHandle_, opt.nativeHandle_,
nativeHandle_, opt.nativeHandle_, keys, keys.size()); keys.toArray(new byte[keys.size()][]));
Map<byte[], byte[]> keyValueMap = new HashMap<>(); Map<byte[], byte[]> keyValueMap = new HashMap<>();
for(int i = 0; i < values.size(); i++) { for(int i = 0; i < values.length; i++) {
if(values.get(i) == null) { if(values[i] == null) {
continue; continue;
} }
keyValueMap.put(keys.get(i), values.get(i)); keyValueMap.put(keys.get(i), values[i]);
} }
return keyValueMap; return keyValueMap;
@ -917,16 +934,19 @@ public class RocksDB extends RocksObject {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"For each key there must be a ColumnFamilyHandle."); "For each key there must be a ColumnFamilyHandle.");
} }
final long[] cfHandles = new long[columnFamilyHandleList.size()];
List<byte[]> values = multiGet(nativeHandle_, opt.nativeHandle_, for (int i = 0; i < columnFamilyHandleList.size(); i++) {
keys, keys.size(), columnFamilyHandleList); cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final byte[][] values = multiGet(nativeHandle_, opt.nativeHandle_,
keys.toArray(new byte[keys.size()][]), cfHandles);
Map<byte[], byte[]> keyValueMap = new HashMap<>(); Map<byte[], byte[]> keyValueMap = new HashMap<>();
for(int i = 0; i < values.size(); i++) { for(int i = 0; i < values.length; i++) {
if(values.get(i) == null) { if(values[i] == null) {
continue; continue;
} }
keyValueMap.put(keys.get(i), values.get(i)); keyValueMap.put(keys.get(i), values[i]);
} }
return keyValueMap; return keyValueMap;
@ -958,8 +978,8 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying * @throws RocksDBException thrown if error happens in underlying
* native library. * native library.
*/ */
public void remove(final ColumnFamilyHandle columnFamilyHandle, final byte[] key) public void remove(final ColumnFamilyHandle columnFamilyHandle,
throws RocksDBException { final byte[] key) throws RocksDBException {
remove(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_); remove(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_);
} }
@ -1009,8 +1029,9 @@ public class RocksDB extends RocksObject {
* *
* <p>Valid property names include: * <p>Valid property names include:
* <ul> * <ul>
* <li>"rocksdb.num-files-at-level&lt;N&gt;" - return the number of files at level &lt;N&gt;, * <li>"rocksdb.num-files-at-level&lt;N&gt;" - return the number of files at
* where &lt;N&gt; is an ASCII representation of a level number (e.g. "0").</li> * level &lt;N&gt;, where &lt;N&gt; is an ASCII representation of a level
* number (e.g. "0").</li>
* <li>"rocksdb.stats" - returns a multi-line string that describes statistics * <li>"rocksdb.stats" - returns a multi-line string that describes statistics
* about the internal operation of the DB.</li> * about the internal operation of the DB.</li>
* <li>"rocksdb.sstables" - returns a multi-line string that describes all * <li>"rocksdb.sstables" - returns a multi-line string that describes all
@ -1027,8 +1048,8 @@ public class RocksDB extends RocksObject {
*/ */
public String getProperty(final ColumnFamilyHandle columnFamilyHandle, public String getProperty(final ColumnFamilyHandle columnFamilyHandle,
final String property) throws RocksDBException { final String property) throws RocksDBException {
return getProperty0(nativeHandle_, columnFamilyHandle.nativeHandle_, property, return getProperty0(nativeHandle_, columnFamilyHandle.nativeHandle_,
property.length()); property, property.length());
} }
/** /**
@ -1039,8 +1060,9 @@ public class RocksDB extends RocksObject {
* *
* <p>Valid property names include: * <p>Valid property names include:
* <ul> * <ul>
* <li>"rocksdb.num-files-at-level&lt;N&gt;" - return the number of files at level &lt;N&gt;, * <li>"rocksdb.num-files-at-level&lt;N&gt;" - return the number of files at
* where &lt;N&gt; is an ASCII representation of a level number (e.g. "0").</li> * level &lt;N&gt;, where &lt;N&gt; is an ASCII representation of a level
* number (e.g. "0").</li>
* <li>"rocksdb.stats" - returns a multi-line string that describes statistics * <li>"rocksdb.stats" - returns a multi-line string that describes statistics
* about the internal operation of the DB.</li> * about the internal operation of the DB.</li>
* <li>"rocksdb.sstables" - returns a multi-line string that describes all * <li>"rocksdb.sstables" - returns a multi-line string that describes all
@ -1058,8 +1080,8 @@ public class RocksDB extends RocksObject {
} }
/** /**
* <p> Similar to GetProperty(), but only works for a subset of properties whose * <p> Similar to GetProperty(), but only works for a subset of properties
* return value is a numerical value. Return the value as long.</p> * whose return value is a numerical value. Return the value as long.</p>
* *
* <p><strong>Note</strong>: As the returned property is of type * <p><strong>Note</strong>: As the returned property is of type
* {@code uint64_t} on C++ side the returning value can be negative * {@code uint64_t} on C++ side the returning value can be negative
@ -1084,8 +1106,8 @@ public class RocksDB extends RocksObject {
} }
/** /**
* <p> Similar to GetProperty(), but only works for a subset of properties whose * <p> Similar to GetProperty(), but only works for a subset of properties
* return value is a numerical value. Return the value as long.</p> * whose return value is a numerical value. Return the value as long.</p>
* *
* <p><strong>Note</strong>: As the returned property is of type * <p><strong>Note</strong>: As the returned property is of type
* {@code uint64_t} on C++ side the returning value can be negative * {@code uint64_t} on C++ side the returning value can be negative
@ -1109,8 +1131,8 @@ public class RocksDB extends RocksObject {
*/ */
public long getLongProperty(final ColumnFamilyHandle columnFamilyHandle, public long getLongProperty(final ColumnFamilyHandle columnFamilyHandle,
final String property) throws RocksDBException { final String property) throws RocksDBException {
return getLongProperty(nativeHandle_, columnFamilyHandle.nativeHandle_, property, return getLongProperty(nativeHandle_, columnFamilyHandle.nativeHandle_,
property.length()); property, property.length());
} }
/** /**
@ -1192,7 +1214,8 @@ public class RocksDB extends RocksObject {
* instance * instance
* @return instance of iterator object. * @return instance of iterator object.
*/ */
public RocksIterator newIterator(final ColumnFamilyHandle columnFamilyHandle) { public RocksIterator newIterator(
final ColumnFamilyHandle columnFamilyHandle) {
return new RocksIterator(this, iteratorCF(nativeHandle_, return new RocksIterator(this, iteratorCF(nativeHandle_,
columnFamilyHandle.nativeHandle_)); columnFamilyHandle.nativeHandle_));
} }
@ -1232,7 +1255,8 @@ public class RocksDB extends RocksObject {
* native library. * native library.
*/ */
public List<RocksIterator> newIterators( public List<RocksIterator> newIterators(
final List<ColumnFamilyHandle> columnFamilyHandleList) throws RocksDBException { final List<ColumnFamilyHandle> columnFamilyHandleList)
throws RocksDBException {
return newIterators(columnFamilyHandleList, new ReadOptions()); return newIterators(columnFamilyHandleList, new ReadOptions());
} }
@ -1253,11 +1277,17 @@ public class RocksDB extends RocksObject {
public List<RocksIterator> newIterators( public List<RocksIterator> newIterators(
final List<ColumnFamilyHandle> columnFamilyHandleList, final List<ColumnFamilyHandle> columnFamilyHandleList,
final ReadOptions readOptions) throws RocksDBException { final ReadOptions readOptions) throws RocksDBException {
List<RocksIterator> iterators =
new ArrayList<>(columnFamilyHandleList.size());
long[] iteratorRefs = iterators(nativeHandle_, columnFamilyHandleList, final long[] columnFamilyHandles = new long[columnFamilyHandleList.size()];
for (int i = 0; i < columnFamilyHandleList.size(); i++) {
columnFamilyHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final long[] iteratorRefs = iterators(nativeHandle_, columnFamilyHandles,
readOptions.nativeHandle_); readOptions.nativeHandle_);
final List<RocksIterator> iterators = new ArrayList<>(
columnFamilyHandleList.size());
for (int i=0; i<columnFamilyHandleList.size(); i++){ for (int i=0; i<columnFamilyHandleList.size(); i++){
iterators.add(new RocksIterator(this, iteratorRefs[i])); iterators.add(new RocksIterator(this, iteratorRefs[i]));
} }
@ -1291,7 +1321,8 @@ public class RocksDB extends RocksObject {
final ColumnFamilyDescriptor columnFamilyDescriptor) final ColumnFamilyDescriptor columnFamilyDescriptor)
throws RocksDBException { throws RocksDBException {
return new ColumnFamilyHandle(this, createColumnFamily(nativeHandle_, return new ColumnFamilyHandle(this, createColumnFamily(nativeHandle_,
columnFamilyDescriptor)); columnFamilyDescriptor.columnFamilyName(),
columnFamilyDescriptor.columnFamilyOptions().nativeHandle_));
} }
/** /**
@ -1310,7 +1341,7 @@ public class RocksDB extends RocksObject {
// throws RocksDBException if something goes wrong // throws RocksDBException if something goes wrong
dropColumnFamily(nativeHandle_, columnFamilyHandle.nativeHandle_); dropColumnFamily(nativeHandle_, columnFamilyHandle.nativeHandle_);
// After the drop the native handle is not valid anymore // After the drop the native handle is not valid anymore
columnFamilyHandle.nativeHandle_ = 0; columnFamilyHandle.disOwnNativeHandle();
} }
/** /**
@ -1672,26 +1703,55 @@ public class RocksDB extends RocksObject {
/** /**
* Private constructor. * Private constructor.
*
* @param nativeHandle The native handle of the C++ RocksDB object
*/ */
protected RocksDB() { protected RocksDB(final long nativeHandle) {
super(); super(nativeHandle);
} }
// native methods // native methods
protected native void open( protected native static long open(final long optionsHandle,
long optionsHandle, String path) throws RocksDBException; final String path) throws RocksDBException;
protected native List<Long> open(long optionsHandle, String path,
List<ColumnFamilyDescriptor> columnFamilyDescriptors, /**
int columnFamilyDescriptorsLength) * @param optionsHandle Native handle pointing to an Options object
throws RocksDBException; * @param path The directory path for the database files
protected native static List<byte[]> listColumnFamilies( * @param columnFamilyNames An array of column family names
long optionsHandle, String path) throws RocksDBException; * @param columnFamilyOptions An array of native handles pointing to
protected native void openROnly( * 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 byte[][] listColumnFamilies(
long optionsHandle, String path) throws RocksDBException; long optionsHandle, String path) throws RocksDBException;
protected native List<Long> openROnly(
long optionsHandle, String path,
List<ColumnFamilyDescriptor> columnFamilyDescriptors,
int columnFamilyDescriptorsLength) throws RocksDBException;
protected native void put( protected native void put(
long handle, byte[] key, int keyLen, long handle, byte[] key, int keyLen,
byte[] value, int valueLen) throws RocksDBException; byte[] value, int valueLen) throws RocksDBException;
@ -1706,18 +1766,20 @@ public class RocksDB extends RocksObject {
long handle, long writeOptHandle, long handle, long writeOptHandle,
byte[] key, int keyLen, byte[] key, int keyLen,
byte[] value, int valueLen, long cfHandle) throws RocksDBException; byte[] value, int valueLen, long cfHandle) throws RocksDBException;
protected native void write0( protected native void write0(final long handle, long writeOptHandle,
long writeOptHandle, long wbHandle) throws RocksDBException; long wbHandle) throws RocksDBException;
protected native void write1( protected native void write1(final long handle, long writeOptHandle,
long writeOptHandle, long wbwiHandle) throws RocksDBException; long wbwiHandle) throws RocksDBException;
protected native boolean keyMayExist(byte[] key, int keyLen, protected native boolean keyMayExist(final long handle, final byte[] key,
StringBuffer stringBuffer); final int keyLen, final StringBuffer stringBuffer);
protected native boolean keyMayExist(byte[] key, int keyLen, protected native boolean keyMayExist(final long handle, final byte[] key,
long cfHandle, StringBuffer stringBuffer); final int keyLen, final long cfHandle, final StringBuffer stringBuffer);
protected native boolean keyMayExist(long optionsHandle, byte[] key, int keyLen, protected native boolean keyMayExist(final long handle,
StringBuffer stringBuffer); final long optionsHandle, final byte[] key, final int keyLen,
protected native boolean keyMayExist(long optionsHandle, byte[] key, int keyLen, final StringBuffer stringBuffer);
long cfHandle, StringBuffer stringBuffer); protected native boolean keyMayExist(final long handle,
final long optionsHandle, final byte[] key, final int keyLen,
final long cfHandle, final StringBuffer stringBuffer);
protected native void merge( protected native void merge(
long handle, byte[] key, int keyLen, long handle, byte[] key, int keyLen,
byte[] value, int valueLen) throws RocksDBException; byte[] value, int valueLen) throws RocksDBException;
@ -1744,20 +1806,18 @@ public class RocksDB extends RocksObject {
protected native int get( protected native int get(
long handle, long readOptHandle, byte[] key, int keyLen, long handle, long readOptHandle, byte[] key, int keyLen,
byte[] value, int valueLen, long cfHandle) throws RocksDBException; byte[] value, int valueLen, long cfHandle) throws RocksDBException;
protected native List<byte[]> multiGet( protected native byte[][] multiGet(final long dbHandle, final byte[][] keys);
long dbHandle, List<byte[]> keys, int keysCount); protected native byte[][] multiGet(final long dbHandle, final byte[][] keys,
protected native List<byte[]> multiGet( final long[] columnFamilyHandles);
long dbHandle, List<byte[]> keys, int keysCount, List<ColumnFamilyHandle> protected native byte[][] multiGet(final long dbHandle, final long rOptHandle,
cfHandles); final byte[][] keys);
protected native List<byte[]> multiGet( protected native byte[][] multiGet(final long dbHandle, final long rOptHandle,
long dbHandle, long rOptHandle, List<byte[]> keys, int keysCount); final byte[][] keys, final long[] columnFamilyHandles);
protected native List<byte[]> multiGet(
long dbHandle, long rOptHandle, List<byte[]> keys, int keysCount,
List<ColumnFamilyHandle> cfHandles);
protected native byte[] get( protected native byte[] get(
long handle, byte[] key, int keyLen) throws RocksDBException; long handle, byte[] key, int keyLen) throws RocksDBException;
protected native byte[] get( protected native byte[] get(
long handle, byte[] key, int keyLen, long cfHandle) throws RocksDBException; long handle, byte[] key, int keyLen, long cfHandle)
throws RocksDBException;
protected native byte[] get( protected native byte[] get(
long handle, long readOptHandle, long handle, long readOptHandle,
byte[] key, int keyLen) throws RocksDBException; byte[] key, int keyLen) throws RocksDBException;
@ -1767,7 +1827,8 @@ public class RocksDB extends RocksObject {
protected native void remove( protected native void remove(
long handle, byte[] key, int keyLen) throws RocksDBException; long handle, byte[] key, int keyLen) throws RocksDBException;
protected native void remove( protected native void remove(
long handle, byte[] key, int keyLen, long cfHandle) throws RocksDBException; long handle, byte[] key, int keyLen, long cfHandle)
throws RocksDBException;
protected native void remove( protected native void remove(
long handle, long writeOptHandle, long handle, long writeOptHandle,
byte[] key, int keyLen) throws RocksDBException; byte[] key, int keyLen) throws RocksDBException;
@ -1787,34 +1848,36 @@ public class RocksDB extends RocksObject {
protected native long iteratorCF(long handle, long cfHandle); protected native long iteratorCF(long handle, long cfHandle);
protected native long iteratorCF(long handle, long cfHandle, protected native long iteratorCF(long handle, long cfHandle,
long readOptHandle); long readOptHandle);
protected native long[] iterators(long handle, protected native long[] iterators(final long handle,
List<ColumnFamilyHandle> columnFamilyNames, long readOptHandle) final long[] columnFamilyHandles, final long readOptHandle)
throws RocksDBException; throws RocksDBException;
protected native long getSnapshot(long nativeHandle); protected native long getSnapshot(long nativeHandle);
protected native void releaseSnapshot( protected native void releaseSnapshot(
long nativeHandle, long snapshotHandle); long nativeHandle, long snapshotHandle);
private native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
private native long getDefaultColumnFamily(long handle); private native long getDefaultColumnFamily(long handle);
private native long createColumnFamily(long handle, private native long createColumnFamily(final long handle,
ColumnFamilyDescriptor columnFamilyDescriptor) throws RocksDBException; final byte[] columnFamilyName, final long columnFamilyOptions)
private native void dropColumnFamily(long handle, long cfHandle) throws RocksDBException; throws RocksDBException;
private native void dropColumnFamily(long handle, long cfHandle)
throws RocksDBException;
private native void flush(long handle, long flushOptHandle) private native void flush(long handle, long flushOptHandle)
throws RocksDBException; throws RocksDBException;
private native void flush(long handle, long flushOptHandle, private native void flush(long handle, long flushOptHandle,
long cfHandle) throws RocksDBException; long cfHandle) throws RocksDBException;
private native void compactRange0(long handle, boolean reduce_level, int target_level, private native void compactRange0(long handle, boolean reduce_level,
int target_level, int target_path_id) throws RocksDBException;
private native void compactRange0(long handle, byte[] begin, int beginLen,
byte[] end, int endLen, boolean reduce_level, int target_level,
int target_path_id) throws RocksDBException; int target_path_id) throws RocksDBException;
private native void compactRange0(long handle, byte[] begin, int beginLen, byte[] end, private native void compactRange(long handle, boolean reduce_level,
int endLen, boolean reduce_level, int target_level, int target_path_id) int target_level, int target_path_id, long cfHandle)
throws RocksDBException; throws RocksDBException;
private native void compactRange(long handle, boolean reduce_level, int target_level, private native void compactRange(long handle, byte[] begin, int beginLen,
byte[] end, int endLen, boolean reduce_level, int target_level,
int target_path_id, long cfHandle) throws RocksDBException; int target_path_id, long cfHandle) throws RocksDBException;
private native void compactRange(long handle, byte[] begin, int beginLen, byte[] end,
int endLen, boolean reduce_level, int target_level, int target_path_id,
long cfHandle) throws RocksDBException;
private native long getLatestSequenceNumber(long handle); private native long getLatestSequenceNumber(long handle);
private native void disableFileDeletions(long handle) private native void disableFileDeletions(long handle) throws RocksDBException;
throws RocksDBException;
private native void enableFileDeletions(long handle, private native void enableFileDeletions(long handle,
boolean force) throws RocksDBException; boolean force) throws RocksDBException;
private native long getUpdatesSince(long handle, long sequenceNumber) private native long getUpdatesSince(long handle, long sequenceNumber)

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

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

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

@ -0,0 +1,69 @@
// Copyright (c) 2016, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb;
/**
* RocksMutableObject is an implementation of {@link AbstractNativeReference}
* whose reference to the underlying native C++ object can change.
*
* <p>The use of {@code RocksMutableObject} should be kept to a minimum, as it
* has synchronization overheads and introduces complexity. Instead it is
* recommended to use {@link RocksObject} where possible.</p>
*/
public abstract class RocksMutableObject extends AbstractNativeReference {
/**
* An mutable reference to the value of the C++ pointer pointing to some
* underlying native RocksDB C++ object.
*/
private long nativeHandle_;
private boolean owningHandle_;
protected RocksMutableObject() {
}
protected RocksMutableObject(final long nativeHandle) {
this.nativeHandle_ = nativeHandle;
this.owningHandle_ = true;
}
public synchronized void setNativeHandle(final long nativeHandle,
final boolean owningNativeHandle) {
this.nativeHandle_ = nativeHandle;
this.owningHandle_ = owningNativeHandle;
}
@Override
protected synchronized boolean isOwningHandle() {
return this.owningHandle_;
}
/**
* Gets the value of the C++ pointer pointing to the underlying
* native C++ object
*
* @return the pointer value for the native object
*/
protected synchronized long getNativeHandle() {
assert (this.nativeHandle_ != 0);
return this.nativeHandle_;
}
@Override
public synchronized final void close() {
if (isOwningHandle()) {
disposeInternal();
this.owningHandle_ = false;
this.nativeHandle_ = 0;
}
}
protected void disposeInternal() {
disposeInternal(nativeHandle_);
}
protected abstract void disposeInternal(final long handle);
}

@ -6,120 +6,36 @@
package org.rocksdb; package org.rocksdb;
/** /**
* RocksObject is the base-class of all RocksDB classes that has a pointer to * RocksObject is an implementation of {@link AbstractNativeReference} which
* some c++ {@code rocksdb} object. * has an immutable and therefore thread-safe reference to the underlying
* * native C++ RocksDB object.
* <p> * <p>
* RocksObject has {@code dispose()} function, which releases its associated c++ * RocksObject is the base-class of almost all RocksDB classes that have a
* resource.</p> * pointer to some underlying native C++ {@code rocksdb} object.</p>
* <p> * <p>
* This function can be either called manually, or being called automatically * The use of {@code RocksObject} should always be preferred over
* during the regular Java GC process. However, since Java may wrongly assume a * {@link RocksMutableObject}.</p>
* RocksObject only contains a long member variable and think it is small in size,
* Java may give {@code RocksObject} low priority in the GC process. For this, it is
* suggested to call {@code dispose()} manually. However, it is safe to let
* {@code RocksObject} go out-of-scope without manually calling {@code dispose()}
* as {@code dispose()} will be called in the finalizer during the
* regular GC process.</p>
*/ */
public abstract class RocksObject { public abstract class RocksObject extends AbstractImmutableNativeReference {
protected RocksObject() {
nativeHandle_ = 0;
owningHandle_ = true;
}
/** /**
* Release the c++ object manually pointed by the native handle. * An immutable reference to the value of the C++ pointer pointing to some
* <p> * underlying native RocksDB C++ object.
* Note that {@code dispose()} will also be called during the GC process
* if it was not called before its {@code RocksObject} went out-of-scope.
* However, since Java may wrongly wrongly assume those objects are
* small in that they seems to only hold a long variable. As a result,
* they might have low priority in the GC process. To prevent this,
* it is suggested to call {@code dispose()} manually.
* </p>
* <p>
* Note that once an instance of {@code RocksObject} has been disposed,
* calling its function will lead undefined behavior.
* </p>
*/ */
public final synchronized void dispose() { protected final long nativeHandle_;
if (isOwningNativeHandle() && isInitialized()) {
disposeInternal();
}
nativeHandle_ = 0;
disOwnNativeHandle();
}
/** protected RocksObject(final long nativeHandle) {
* The helper function of {@code dispose()} which all subclasses of super(true);
* {@code RocksObject} must implement to release their associated this.nativeHandle_ = nativeHandle;
* C++ resource.
*/
protected abstract void disposeInternal();
/**
* Revoke ownership of the native object.
* <p>
* This will prevent the object from attempting to delete the underlying
* native object in its finalizer. This must be used when another object
* takes over ownership of the native object or both will attempt to delete
* the underlying object when garbage collected.
* <p>
* When {@code disOwnNativeHandle()} is called, {@code dispose()} will simply set
* {@code nativeHandle_} to 0 without releasing its associated C++ resource.
* As a result, incorrectly use this function may cause memory leak, and this
* function call will not affect the return value of {@code isInitialized()}.
* </p>
* @see #dispose()
* @see #isInitialized()
*/
protected void disOwnNativeHandle() {
owningHandle_ = false;
} }
/** /**
* Returns true if the current {@code RocksObject} is responsible to release * Deletes underlying C++ object pointer.
* its native handle.
*
* @return true if the current {@code RocksObject} is responsible to release
* its native handle.
*
* @see #disOwnNativeHandle()
* @see #dispose()
*/ */
protected boolean isOwningNativeHandle() { @Override
return owningHandle_; protected void disposeInternal() {
disposeInternal(nativeHandle_);
} }
/** protected abstract void disposeInternal(final long handle);
* 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();
}
/**
* A long variable holding c++ pointer pointing to some RocksDB C++ object.
*/
protected long nativeHandle_;
/**
* A flag indicating whether the current {@code RocksObject} is responsible to
* release the c++ object stored in its {@code nativeHandle_}.
*/
private boolean owningHandle_;
} }

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

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

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

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

@ -5,10 +5,12 @@
package org.rocksdb; package org.rocksdb;
public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex> { public class WBWIRocksIterator
extends AbstractRocksIterator<WriteBatchWithIndex> {
private final WriteEntry entry = new WriteEntry(); private final WriteEntry entry = new WriteEntry();
protected WBWIRocksIterator(final WriteBatchWithIndex wbwi, final long nativeHandle) { protected WBWIRocksIterator(final WriteBatchWithIndex wbwi,
final long nativeHandle) {
super(wbwi, nativeHandle); super(wbwi, nativeHandle);
} }
@ -20,16 +22,24 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
* If you want to keep the WriteEntry across iterator * If you want to keep the WriteEntry across iterator
* movements, you must make a copy of its data! * movements, you must make a copy of its data!
* *
* Note - This method is not thread-safe with respect to the WriteEntry
* as it performs a non-atomic update across the fields of the WriteEntry
*
* @return The WriteEntry of the current entry * @return The WriteEntry of the current entry
*/ */
public WriteEntry entry() { public WriteEntry entry() {
assert(isInitialized()); assert(isOwningHandle());
assert(entry != null); assert(entry != null);
entry1(nativeHandle_, entry); final long ptrs[] = entry1(nativeHandle_);
entry.type = WriteType.fromId((byte)ptrs[0]);
entry.key.setNativeHandle(ptrs[1], true);
entry.value.setNativeHandle(ptrs[2], ptrs[2] != 0);
return entry; return entry;
} }
@Override final native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
@Override final native boolean isValid0(long handle); @Override final native boolean isValid0(long handle);
@Override final native void seekToFirst0(long handle); @Override final native void seekToFirst0(long handle);
@Override final native void seekToLast0(long handle); @Override final native void seekToLast0(long handle);
@ -38,17 +48,31 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
@Override final native void seek0(long handle, byte[] target, int targetLen); @Override final native void seek0(long handle, byte[] target, int targetLen);
@Override final native void status0(long handle) throws RocksDBException; @Override final native void status0(long handle) throws RocksDBException;
private native void entry1(long handle, WriteEntry entry); private native long[] entry1(final long handle);
/** /**
* Enumeration of the Write operation * Enumeration of the Write operation
* that created the record in the Write Batch * that created the record in the Write Batch
*/ */
public enum WriteType { public enum WriteType {
PUT, PUT((byte)0x1),
MERGE, MERGE((byte)0x2),
DELETE, DELETE((byte)0x4),
LOG LOG((byte)0x8);
final byte id;
WriteType(final byte id) {
this.id = id;
}
public static WriteType fromId(final byte id) {
for(final WriteType wt : WriteType.values()) {
if(id == wt.id) {
return wt;
}
}
throw new IllegalArgumentException("No WriteType with id=" + id);
}
} }
/** /**
@ -110,7 +134,7 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
* no value * no value
*/ */
public DirectSlice getValue() { public DirectSlice getValue() {
if(!value.isInitialized()) { if(!value.isOwningHandle()) {
return null; //TODO(AR) migrate to JDK8 java.util.Optional#empty() return null; //TODO(AR) migrate to JDK8 java.util.Optional#empty()
} else { } else {
return value; return value;
@ -139,8 +163,7 @@ public class WBWIRocksIterator extends AbstractRocksIterator<WriteBatchWithIndex
final WriteEntry otherWriteEntry = (WriteEntry)other; final WriteEntry otherWriteEntry = (WriteEntry)other;
return type.equals(otherWriteEntry.type) return type.equals(otherWriteEntry.type)
&& key.equals(otherWriteEntry.key) && key.equals(otherWriteEntry.key)
&& (value.isInitialized() ? value.equals(otherWriteEntry.value) && value.equals(otherWriteEntry.value);
: !otherWriteEntry.value.isInitialized());
} else { } else {
return false; return false;
} }

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

@ -12,10 +12,10 @@ package org.rocksdb;
* Calling put, merge, remove or putLogData calls the same function * Calling put, merge, remove or putLogData calls the same function
* as with {@link org.rocksdb.WriteBatch} whilst also building an index. * as with {@link org.rocksdb.WriteBatch} whilst also building an index.
* *
* A user can call {@link org.rocksdb.WriteBatchWithIndex#newIterator() }to create an iterator * A user can call {@link org.rocksdb.WriteBatchWithIndex#newIterator()} to
* over the write batch or * create an iterator over the write batch or
* {@link org.rocksdb.WriteBatchWithIndex#newIteratorWithBase(org.rocksdb.RocksIterator)} to * {@link org.rocksdb.WriteBatchWithIndex#newIteratorWithBase(org.rocksdb.RocksIterator)}
* get an iterator for the database with Read-Your-Own-Writes like capability * to get an iterator for the database with Read-Your-Own-Writes like capability
*/ */
public class WriteBatchWithIndex extends AbstractWriteBatch { public class WriteBatchWithIndex extends AbstractWriteBatch {
/** /**
@ -25,8 +25,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* and duplicate keys operations are retained * and duplicate keys operations are retained
*/ */
public WriteBatchWithIndex() { public WriteBatchWithIndex() {
super(); super(newWriteBatchWithIndex());
newWriteBatchWithIndex();
} }
@ -41,8 +40,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* show two entries with the same key. * show two entries with the same key.
*/ */
public WriteBatchWithIndex(final boolean overwriteKey) { public WriteBatchWithIndex(final boolean overwriteKey) {
super(); super(newWriteBatchWithIndex(overwriteKey));
newWriteBatchWithIndex(overwriteKey);
} }
/** /**
@ -58,10 +56,12 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* inserting a duplicate key, in this way an iterator will never * inserting a duplicate key, in this way an iterator will never
* show two entries with the same key. * show two entries with the same key.
*/ */
public WriteBatchWithIndex(final AbstractComparator<? extends AbstractSlice<?>> public WriteBatchWithIndex(
fallbackIndexComparator, final int reservedBytes, final boolean overwriteKey) { final AbstractComparator<? extends AbstractSlice<?>>
super(); fallbackIndexComparator, final int reservedBytes,
newWriteBatchWithIndex(fallbackIndexComparator.nativeHandle_, reservedBytes, overwriteKey); final boolean overwriteKey) {
super(newWriteBatchWithIndex(fallbackIndexComparator.getNativeHandle(),
reservedBytes, overwriteKey));
} }
/** /**
@ -73,10 +73,13 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* time. * time.
* *
* @param columnFamilyHandle The column family to iterate over * @param columnFamilyHandle The column family to iterate over
* @return An iterator for the Write Batch contents, restricted to the column family * @return An iterator for the Write Batch contents, restricted to the column
* family
*/ */
public WBWIRocksIterator newIterator(final ColumnFamilyHandle columnFamilyHandle) { public WBWIRocksIterator newIterator(
return new WBWIRocksIterator(this, iterator1(columnFamilyHandle.nativeHandle_)); final ColumnFamilyHandle columnFamilyHandle) {
return new WBWIRocksIterator(this, iterator1(nativeHandle_,
columnFamilyHandle.nativeHandle_));
} }
/** /**
@ -90,7 +93,7 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* @return An iterator for the Write Batch contents * @return An iterator for the Write Batch contents
*/ */
public WBWIRocksIterator newIterator() { public WBWIRocksIterator newIterator() {
return new WBWIRocksIterator(this, iterator0()); return new WBWIRocksIterator(this, iterator0(nativeHandle_));
} }
/** /**
@ -99,15 +102,19 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
* as a delta and baseIterator as a base * as a delta and baseIterator as a base
* *
* @param columnFamilyHandle The column family to iterate over * @param columnFamilyHandle The column family to iterate over
* @param baseIterator The base iterator, e.g. {@link org.rocksdb.RocksDB#newIterator()} * @param baseIterator The base iterator,
* @return An iterator which shows a view comprised of both the database point-in-time * e.g. {@link org.rocksdb.RocksDB#newIterator()}
* from baseIterator and modifications made in this write batch. * @return An iterator which shows a view comprised of both the database
* point-in-time from baseIterator and modifications made in this write batch.
*/ */
public RocksIterator newIteratorWithBase(final ColumnFamilyHandle columnFamilyHandle, public RocksIterator newIteratorWithBase(
final ColumnFamilyHandle columnFamilyHandle,
final RocksIterator baseIterator) { final RocksIterator baseIterator) {
RocksIterator iterator = new RocksIterator( RocksIterator iterator = new RocksIterator(
baseIterator.parent_, baseIterator.parent_,
iteratorWithBase(columnFamilyHandle.nativeHandle_, baseIterator.nativeHandle_)); iteratorWithBase(nativeHandle_,
columnFamilyHandle.nativeHandle_,
baseIterator.nativeHandle_));
//when the iterator is deleted it will also delete the baseIterator //when the iterator is deleted it will also delete the baseIterator
baseIterator.disOwnNativeHandle(); baseIterator.disOwnNativeHandle();
return iterator; return iterator;
@ -116,34 +123,46 @@ public class WriteBatchWithIndex extends AbstractWriteBatch {
/** /**
* Provides Read-Your-Own-Writes like functionality by * Provides Read-Your-Own-Writes like functionality by
* creating a new Iterator that will use {@link org.rocksdb.WBWIRocksIterator} * creating a new Iterator that will use {@link org.rocksdb.WBWIRocksIterator}
* as a delta and baseIterator as a base. Operates on the default column family. * as a delta and baseIterator as a base. Operates on the default column
* family.
* *
* @param baseIterator The base iterator, e.g. {@link org.rocksdb.RocksDB#newIterator()} * @param baseIterator The base iterator,
* @return An iterator which shows a view comprised of both the database point-in-time * e.g. {@link org.rocksdb.RocksDB#newIterator()}
* from baseIterator and modifications made in this write batch. * @return An iterator which shows a view comprised of both the database
* point-in-timefrom baseIterator and modifications made in this write batch.
*/ */
public RocksIterator newIteratorWithBase(final RocksIterator baseIterator) { public RocksIterator newIteratorWithBase(final RocksIterator baseIterator) {
return newIteratorWithBase(baseIterator.parent_.getDefaultColumnFamily(), baseIterator); return newIteratorWithBase(baseIterator.parent_.getDefaultColumnFamily(),
baseIterator);
} }
@Override final native void disposeInternal(long handle); @Override protected final native void disposeInternal(final long handle);
@Override final native int count0(); @Override final native int count0(final long handle);
@Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen); @Override final native void put(final long handle, final byte[] key,
@Override final native void put(byte[] key, int keyLen, byte[] value, int valueLen, final int keyLen, final byte[] value, final int valueLen);
long cfHandle); @Override final native void put(final long handle, final byte[] key,
@Override final native void merge(byte[] key, int keyLen, byte[] value, int valueLen); final int keyLen, final byte[] value, final int valueLen,
@Override final native void merge(byte[] key, int keyLen, byte[] value, int valueLen, final long cfHandle);
long cfHandle); @Override final native void merge(final long handle, final byte[] key,
@Override final native void remove(byte[] key, int keyLen); final int keyLen, final byte[] value, final int valueLen);
@Override final native void remove(byte[] key, int keyLen, long cfHandle); @Override final native void merge(final long handle, final byte[] key,
@Override final native void putLogData(byte[] blob, int blobLen); final int keyLen, final byte[] value, final int valueLen,
@Override final native void clear0(); final long cfHandle);
@Override final native void remove(final long handle, final byte[] key,
final int keyLen);
@Override final native void remove(final long handle, final byte[] key,
final int keyLen, final long cfHandle);
@Override final native void putLogData(final long handle, final byte[] blob,
final int blobLen);
@Override final native void clear0(final long handle);
private native void newWriteBatchWithIndex(); private native static long newWriteBatchWithIndex();
private native void newWriteBatchWithIndex(boolean overwriteKey); private native static long newWriteBatchWithIndex(final boolean overwriteKey);
private native void newWriteBatchWithIndex(long fallbackIndexComparatorHandle, int reservedBytes, private native static long newWriteBatchWithIndex(
boolean overwriteKey); final long fallbackIndexComparatorHandle, final int reservedBytes,
private native long iterator0(); final boolean overwriteKey);
private native long iterator1(long cfHandle); private native long iterator0(final long handle);
private native long iteratorWithBase(long baseIteratorHandle, long cfHandle); private native long iterator1(final long handle, final long cfHandle);
private native long iteratorWithBase(final long handle,
final long baseIteratorHandle, final long cfHandle);
} }

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

@ -8,6 +8,7 @@ package org.rocksdb;
import java.io.IOException; import java.io.IOException;
import java.nio.file.*; import java.nio.file.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@ -39,36 +40,33 @@ public abstract class AbstractComparatorTest {
* *
* @throws java.io.IOException if IO error happens. * @throws java.io.IOException if IO error happens.
*/ */
public void testRoundtrip(final Path db_path) throws IOException, RocksDBException { public void testRoundtrip(final Path db_path) throws IOException,
RocksDBException {
Options opt = null; try (final AbstractComparator comparator = getAscendingIntKeyComparator();
RocksDB db = null; final Options opt = new Options()
.setCreateIfMissing(true)
try { .setComparator(comparator)) {
opt = new Options();
opt.setCreateIfMissing(true);
opt.setComparator(getAscendingIntKeyComparator());
// store 10,000 random integer keys // store 10,000 random integer keys
final int ITERATIONS = 10000; final int ITERATIONS = 10000;
try (final RocksDB db = RocksDB.open(opt, db_path.toString())) {
db = RocksDB.open(opt, db_path.toString());
final Random random = new Random(); final Random random = new Random();
for (int i = 0; i < ITERATIONS; i++) { for (int i = 0; i < ITERATIONS; i++) {
final byte key[] = intToByte(random.nextInt()); final byte key[] = intToByte(random.nextInt());
if (i > 0 && db.get(key) != null) { // does key already exist (avoid duplicates) // does key already exist (avoid duplicates)
if (i > 0 && db.get(key) != null) {
i--; // generate a different key i--; // generate a different key
} else { } else {
db.put(key, "value".getBytes()); db.put(key, "value".getBytes());
} }
} }
db.close(); }
// re-open db and read from start to end // re-open db and read from start to end
// integer keys should be in ascending // integer keys should be in ascending
// order as defined by SimpleIntComparator // order as defined by SimpleIntComparator
db = RocksDB.open(opt, db_path.toString()); try (final RocksDB db = RocksDB.open(opt, db_path.toString());
final RocksIterator it = db.newIterator(); final RocksIterator it = db.newIterator()) {
it.seekToFirst(); it.seekToFirst();
int lastKey = Integer.MIN_VALUE; int lastKey = Integer.MIN_VALUE;
int count = 0; int count = 0;
@ -78,18 +76,7 @@ public abstract class AbstractComparatorTest {
lastKey = thisKey; lastKey = thisKey;
count++; count++;
} }
it.dispose();
db.close();
assertThat(count).isEqualTo(ITERATIONS); assertThat(count).isEqualTo(ITERATIONS);
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -109,25 +96,25 @@ public abstract class AbstractComparatorTest {
public void testRoundtripCf(final Path db_path) throws IOException, public void testRoundtripCf(final Path db_path) throws IOException,
RocksDBException { RocksDBException {
DBOptions opt = null; try(final AbstractComparator comparator = getAscendingIntKeyComparator()) {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
List<ColumnFamilyDescriptor> cfDescriptors = new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ArrayList<>(); new ColumnFamilyDescriptor("new_cf".getBytes(),
cfDescriptors.add(new ColumnFamilyDescriptor( new ColumnFamilyOptions().setComparator(comparator))
RocksDB.DEFAULT_COLUMN_FAMILY)); );
cfDescriptors.add(new ColumnFamilyDescriptor("new_cf".getBytes(),
new ColumnFamilyOptions().setComparator( final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
getAscendingIntKeyComparator())));
List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); try (final DBOptions opt = new DBOptions().
try {
opt = new DBOptions().
setCreateIfMissing(true). setCreateIfMissing(true).
setCreateMissingColumnFamilies(true); setCreateMissingColumnFamilies(true)) {
// store 10,000 random integer keys // store 10,000 random integer keys
final int ITERATIONS = 10000; final int ITERATIONS = 10000;
db = RocksDB.open(opt, db_path.toString(), cfDescriptors, cfHandles); try (final RocksDB db = RocksDB.open(opt, db_path.toString(),
cfDescriptors, cfHandles)) {
try {
assertThat(cfDescriptors.size()).isEqualTo(2); assertThat(cfDescriptors.size()).isEqualTo(2);
assertThat(cfHandles.size()).isEqualTo(2); assertThat(cfHandles.size()).isEqualTo(2);
@ -141,19 +128,24 @@ public abstract class AbstractComparatorTest {
db.put(cfHandles.get(1), key, "value".getBytes()); db.put(cfHandles.get(1), key, "value".getBytes());
} }
} }
for (ColumnFamilyHandle handle : cfHandles) { } finally {
handle.dispose(); for (final ColumnFamilyHandle handle : cfHandles) {
handle.close();
}
} }
cfHandles.clear(); cfHandles.clear();
db.close(); }
// re-open db and read from start to end // re-open db and read from start to end
// integer keys should be in ascending // integer keys should be in ascending
// order as defined by SimpleIntComparator // order as defined by SimpleIntComparator
db = RocksDB.open(opt, db_path.toString(), cfDescriptors, cfHandles); try (final RocksDB db = RocksDB.open(opt, db_path.toString(),
cfDescriptors, cfHandles);
final RocksIterator it = db.newIterator(cfHandles.get(1))) {
try {
assertThat(cfDescriptors.size()).isEqualTo(2); assertThat(cfDescriptors.size()).isEqualTo(2);
assertThat(cfHandles.size()).isEqualTo(2); assertThat(cfHandles.size()).isEqualTo(2);
final RocksIterator it = db.newIterator(cfHandles.get(1));
it.seekToFirst(); it.seekToFirst();
int lastKey = Integer.MIN_VALUE; int lastKey = Integer.MIN_VALUE;
int count = 0; int count = 0;
@ -164,25 +156,15 @@ public abstract class AbstractComparatorTest {
count++; count++;
} }
it.dispose();
for (ColumnFamilyHandle handle : cfHandles) {
handle.dispose();
}
cfHandles.clear();
db.close();
assertThat(count).isEqualTo(ITERATIONS); assertThat(count).isEqualTo(ITERATIONS);
} finally { } finally {
for (ColumnFamilyHandle handle : cfHandles) { for (final ColumnFamilyHandle handle : cfHandles) {
handle.dispose(); handle.close();
} }
if (db != null) {
db.close();
} }
cfHandles.clear();
if (opt != null) { }
opt.dispose();
} }
} }
} }

@ -28,57 +28,37 @@ public class BackupEngineTest {
@Test @Test
public void backupDb() throws RocksDBException { public void backupDb() throws RocksDBException {
Options opt = null;
RocksDB db = null;
try {
opt = new Options().setCreateIfMissing(true);
// Open empty database. // Open empty database.
db = RocksDB.open(opt, try(final Options opt = new Options().setCreateIfMissing(true);
dbFolder.getRoot().getAbsolutePath()); final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(db); prepareDatabase(db);
// Create two backups // Create two backups
BackupableDBOptions bopt = null; try(final BackupableDBOptions bopt = new BackupableDBOptions(
try {
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
try(final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) { final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) {
be.createNewBackup(db, false); be.createNewBackup(db, false);
be.createNewBackup(db, true); be.createNewBackup(db, true);
verifyNumberOfValidBackups(be, 2); verifyNumberOfValidBackups(be, 2);
} }
} finally {
if(bopt != null) {
bopt.dispose();
}
}
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void deleteBackup() throws RocksDBException { public void deleteBackup() throws RocksDBException {
Options opt = null;
RocksDB db = null;
try {
opt = new Options().setCreateIfMissing(true);
// Open empty database. // Open empty database.
db = RocksDB.open(opt, try(final Options opt = new Options().setCreateIfMissing(true);
dbFolder.getRoot().getAbsolutePath()); final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(db); prepareDatabase(db);
// Create two backups // Create two backups
BackupableDBOptions bopt = null; try(final BackupableDBOptions bopt = new BackupableDBOptions(
try {
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
try(final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) { final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) {
be.createNewBackup(db, false); be.createNewBackup(db, false);
be.createNewBackup(db, true); be.createNewBackup(db, true);
final List<BackupInfo> backupInfo = final List<BackupInfo> backupInfo =
@ -92,38 +72,21 @@ public class BackupEngineTest {
assertThat(newBackupInfo.get(0).backupId()). assertThat(newBackupInfo.get(0).backupId()).
isEqualTo(backupInfo.get(1).backupId()); isEqualTo(backupInfo.get(1).backupId());
} }
} finally {
if(bopt != null) {
bopt.dispose();
}
}
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void purgeOldBackups() throws RocksDBException { public void purgeOldBackups() throws RocksDBException {
Options opt = null;
RocksDB db = null;
try {
opt = new Options().setCreateIfMissing(true);
// Open empty database. // Open empty database.
db = RocksDB.open(opt, try(final Options opt = new Options().setCreateIfMissing(true);
dbFolder.getRoot().getAbsolutePath()); final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(db); prepareDatabase(db);
// Create four backups // Create four backups
BackupableDBOptions bopt = null; try(final BackupableDBOptions bopt = new BackupableDBOptions(
try {
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
try(final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) { final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) {
be.createNewBackup(db, false); be.createNewBackup(db, false);
be.createNewBackup(db, true); be.createNewBackup(db, true);
be.createNewBackup(db, true); be.createNewBackup(db, true);
@ -138,38 +101,23 @@ public class BackupEngineTest {
assertThat(newBackupInfo.get(0).backupId()). assertThat(newBackupInfo.get(0).backupId()).
isEqualTo(backupInfo.get(3).backupId()); isEqualTo(backupInfo.get(3).backupId());
} }
} finally {
if(bopt != null) {
bopt.dispose();
}
}
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void restoreLatestBackup() public void restoreLatestBackup() throws RocksDBException {
throws RocksDBException { try(final Options opt = new Options().setCreateIfMissing(true)) {
Options opt = null; // Open empty database.
RocksDB db = null; RocksDB db = null;
try { try {
opt = new Options().setCreateIfMissing(true);
// Open empty database.
db = RocksDB.open(opt, db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath());
// Fill database with some test values // Fill database with some test values
prepareDatabase(db); prepareDatabase(db);
BackupableDBOptions bopt = null;
try { try (final BackupableDBOptions bopt = new BackupableDBOptions(
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
try (final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) { final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) {
be.createNewBackup(db, true); be.createNewBackup(db, true);
verifyNumberOfValidBackups(be, 1); verifyNumberOfValidBackups(be, 1);
db.put("key1".getBytes(), "valueV2".getBytes()); db.put("key1".getBytes(), "valueV2".getBytes());
@ -182,30 +130,26 @@ public class BackupEngineTest {
assertThat(new String(db.get("key2".getBytes()))).endsWith("V3"); assertThat(new String(db.get("key2".getBytes()))).endsWith("V3");
db.close(); db.close();
db = null;
verifyNumberOfValidBackups(be, 2); verifyNumberOfValidBackups(be, 2);
// restore db from latest backup // restore db from latest backup
try(final RestoreOptions ropts = new RestoreOptions(false)) {
be.restoreDbFromLatestBackup(dbFolder.getRoot().getAbsolutePath(), be.restoreDbFromLatestBackup(dbFolder.getRoot().getAbsolutePath(),
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(), ropts);
new RestoreOptions(false)); }
// Open database again. // Open database again.
db = RocksDB.open(opt, db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath());
dbFolder.getRoot().getAbsolutePath());
// Values must have suffix V2 because of restoring latest backup. // Values must have suffix V2 because of restoring latest backup.
assertThat(new String(db.get("key1".getBytes()))).endsWith("V2"); assertThat(new String(db.get("key1".getBytes()))).endsWith("V2");
assertThat(new String(db.get("key2".getBytes()))).endsWith("V2"); assertThat(new String(db.get("key2".getBytes()))).endsWith("V2");
} }
} finally {
if(bopt != null) {
bopt.dispose();
}
}
} finally { } finally {
if(db != null) { if(db != null) {
db.close(); db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -213,20 +157,17 @@ public class BackupEngineTest {
@Test @Test
public void restoreFromBackup() public void restoreFromBackup()
throws RocksDBException { throws RocksDBException {
Options opt = null; try(final Options opt = new Options().setCreateIfMissing(true)) {
RocksDB db = null; RocksDB db = null;
try { try {
opt = new Options().setCreateIfMissing(true);
// Open empty database. // Open empty database.
db = RocksDB.open(opt, db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath());
// Fill database with some test values // Fill database with some test values
prepareDatabase(db); prepareDatabase(db);
BackupableDBOptions bopt = null; try (final BackupableDBOptions bopt = new BackupableDBOptions(
try {
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
try (final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) { final BackupEngine be = BackupEngine.open(opt.getEnv(), bopt)) {
be.createNewBackup(db, true); be.createNewBackup(db, true);
verifyNumberOfValidBackups(be, 1); verifyNumberOfValidBackups(be, 1);
db.put("key1".getBytes(), "valueV2".getBytes()); db.put("key1".getBytes(), "valueV2".getBytes());
@ -240,9 +181,10 @@ public class BackupEngineTest {
//close the database //close the database
db.close(); db.close();
db = null;
//restore the backup //restore the backup
List<BackupInfo> backupInfo = verifyNumberOfValidBackups(be, 2); final List<BackupInfo> backupInfo = verifyNumberOfValidBackups(be, 2);
// restore db from first backup // restore db from first backup
be.restoreDbFromBackup(backupInfo.get(0).backupId(), be.restoreDbFromBackup(backupInfo.get(0).backupId(),
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
@ -255,17 +197,10 @@ public class BackupEngineTest {
assertThat(new String(db.get("key1".getBytes()))).endsWith("V1"); assertThat(new String(db.get("key1".getBytes()))).endsWith("V1");
assertThat(new String(db.get("key2".getBytes()))).endsWith("V1"); assertThat(new String(db.get("key2".getBytes()))).endsWith("V1");
} }
} finally {
if(bopt != null) {
bopt.dispose();
}
}
} finally { } finally {
if(db != null) { if(db != null) {
db.close(); db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }

@ -16,7 +16,8 @@ import org.junit.rules.ExpectedException;
public class BackupableDBOptionsTest { public class BackupableDBOptionsTest {
private final static String ARBITRARY_PATH = System.getProperty("java.io.tmpdir"); private final static String ARBITRARY_PATH =
System.getProperty("java.io.tmpdir");
@ClassRule @ClassRule
public static final RocksMemoryResource rocksMemoryResource = public static final RocksMemoryResource rocksMemoryResource =
@ -30,87 +31,61 @@ public class BackupableDBOptionsTest {
@Test @Test
public void backupDir() { public void backupDir() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH);
assertThat(backupableDBOptions.backupDir()). assertThat(backupableDBOptions.backupDir()).
isEqualTo(ARBITRARY_PATH); isEqualTo(ARBITRARY_PATH);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void shareTableFiles() { public void shareTableFiles() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH); final boolean value = rand.nextBoolean();
boolean value = rand.nextBoolean();
backupableDBOptions.setShareTableFiles(value); backupableDBOptions.setShareTableFiles(value);
assertThat(backupableDBOptions.shareTableFiles()). assertThat(backupableDBOptions.shareTableFiles()).
isEqualTo(value); isEqualTo(value);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void sync() { public void sync() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH); final boolean value = rand.nextBoolean();
boolean value = rand.nextBoolean();
backupableDBOptions.setSync(value); backupableDBOptions.setSync(value);
assertThat(backupableDBOptions.sync()).isEqualTo(value); assertThat(backupableDBOptions.sync()).isEqualTo(value);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void destroyOldData() { public void destroyOldData() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH);) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH); final boolean value = rand.nextBoolean();
boolean value = rand.nextBoolean();
backupableDBOptions.setDestroyOldData(value); backupableDBOptions.setDestroyOldData(value);
assertThat(backupableDBOptions.destroyOldData()). assertThat(backupableDBOptions.destroyOldData()).
isEqualTo(value); isEqualTo(value);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void backupLogFiles() { public void backupLogFiles() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH); final boolean value = rand.nextBoolean();
boolean value = rand.nextBoolean();
backupableDBOptions.setBackupLogFiles(value); backupableDBOptions.setBackupLogFiles(value);
assertThat(backupableDBOptions.backupLogFiles()). assertThat(backupableDBOptions.backupLogFiles()).
isEqualTo(value); isEqualTo(value);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void backupRateLimit() { public void backupRateLimit() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH); final long value = Math.abs(rand.nextLong());
long value = Math.abs(rand.nextLong());
backupableDBOptions.setBackupRateLimit(value); backupableDBOptions.setBackupRateLimit(value);
assertThat(backupableDBOptions.backupRateLimit()). assertThat(backupableDBOptions.backupRateLimit()).
isEqualTo(value); isEqualTo(value);
@ -118,19 +93,14 @@ public class BackupableDBOptionsTest {
backupableDBOptions.setBackupRateLimit(-1); backupableDBOptions.setBackupRateLimit(-1);
assertThat(backupableDBOptions.backupRateLimit()). assertThat(backupableDBOptions.backupRateLimit()).
isEqualTo(0); isEqualTo(0);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void restoreRateLimit() { public void restoreRateLimit() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH); final long value = Math.abs(rand.nextLong());
long value = Math.abs(rand.nextLong());
backupableDBOptions.setRestoreRateLimit(value); backupableDBOptions.setRestoreRateLimit(value);
assertThat(backupableDBOptions.restoreRateLimit()). assertThat(backupableDBOptions.restoreRateLimit()).
isEqualTo(value); isEqualTo(value);
@ -138,145 +108,153 @@ public class BackupableDBOptionsTest {
backupableDBOptions.setRestoreRateLimit(-1); backupableDBOptions.setRestoreRateLimit(-1);
assertThat(backupableDBOptions.restoreRateLimit()). assertThat(backupableDBOptions.restoreRateLimit()).
isEqualTo(0); isEqualTo(0);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void shareFilesWithChecksum() { public void shareFilesWithChecksum() {
BackupableDBOptions backupableDBOptions = null; try (final BackupableDBOptions backupableDBOptions =
try { new BackupableDBOptions(ARBITRARY_PATH)) {
backupableDBOptions = new BackupableDBOptions(ARBITRARY_PATH);
boolean value = rand.nextBoolean(); boolean value = rand.nextBoolean();
backupableDBOptions.setShareFilesWithChecksum(value); backupableDBOptions.setShareFilesWithChecksum(value);
assertThat(backupableDBOptions.shareFilesWithChecksum()). assertThat(backupableDBOptions.shareFilesWithChecksum()).
isEqualTo(value); isEqualTo(value);
} finally {
if (backupableDBOptions != null) {
backupableDBOptions.dispose();
}
} }
} }
@Test @Test
public void failBackupDirIsNull() { public void failBackupDirIsNull() {
exception.expect(IllegalArgumentException.class); exception.expect(IllegalArgumentException.class);
new BackupableDBOptions(null); try (final BackupableDBOptions opts = new BackupableDBOptions(null)) {
//no-op
}
} }
@Test @Test
public void failBackupDirIfDisposed() { public void failBackupDirIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.backupDir(); options.backupDir();
} }
}
@Test @Test
public void failSetShareTableFilesIfDisposed() { public void failSetShareTableFilesIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setShareTableFiles(true); options.setShareTableFiles(true);
} }
}
@Test @Test
public void failShareTableFilesIfDisposed() { public void failShareTableFilesIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.shareTableFiles(); options.shareTableFiles();
} }
}
@Test @Test
public void failSetSyncIfDisposed() { public void failSetSyncIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setSync(true); options.setSync(true);
} }
}
@Test @Test
public void failSyncIfDisposed() { public void failSyncIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.sync(); options.sync();
} }
}
@Test @Test
public void failSetDestroyOldDataIfDisposed() { public void failSetDestroyOldDataIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setDestroyOldData(true); options.setDestroyOldData(true);
} }
}
@Test @Test
public void failDestroyOldDataIfDisposed() { public void failDestroyOldDataIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.destroyOldData(); options.destroyOldData();
} }
}
@Test @Test
public void failSetBackupLogFilesIfDisposed() { public void failSetBackupLogFilesIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setBackupLogFiles(true); options.setBackupLogFiles(true);
} }
}
@Test @Test
public void failBackupLogFilesIfDisposed() { public void failBackupLogFilesIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.backupLogFiles(); options.backupLogFiles();
} }
}
@Test @Test
public void failSetBackupRateLimitIfDisposed() { public void failSetBackupRateLimitIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setBackupRateLimit(1); options.setBackupRateLimit(1);
} }
}
@Test @Test
public void failBackupRateLimitIfDisposed() { public void failBackupRateLimitIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.backupRateLimit(); options.backupRateLimit();
} }
}
@Test @Test
public void failSetRestoreRateLimitIfDisposed() { public void failSetRestoreRateLimitIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setRestoreRateLimit(1); options.setRestoreRateLimit(1);
} }
}
@Test @Test
public void failRestoreRateLimitIfDisposed() { public void failRestoreRateLimitIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.restoreRateLimit(); options.restoreRateLimit();
} }
}
@Test @Test
public void failSetShareFilesWithChecksumIfDisposed() { public void failSetShareFilesWithChecksumIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.setShareFilesWithChecksum(true); options.setShareFilesWithChecksum(true);
} }
}
@Test @Test
public void failShareFilesWithChecksumIfDisposed() { public void failShareFilesWithChecksumIfDisposed() {
BackupableDBOptions options = setupUninitializedBackupableDBOptions( try (final BackupableDBOptions options =
exception); setupUninitializedBackupableDBOptions(exception)) {
options.shareFilesWithChecksum(); options.shareFilesWithChecksum();
} }
}
private BackupableDBOptions setupUninitializedBackupableDBOptions( private BackupableDBOptions setupUninitializedBackupableDBOptions(
ExpectedException exception) { ExpectedException exception) {
BackupableDBOptions backupableDBOptions = final BackupableDBOptions backupableDBOptions =
new BackupableDBOptions(ARBITRARY_PATH); new BackupableDBOptions(ARBITRARY_PATH);
backupableDBOptions.dispose(); backupableDBOptions.close();
exception.expect(AssertionError.class); exception.expect(AssertionError.class);
return backupableDBOptions; return backupableDBOptions;
} }

@ -28,51 +28,34 @@ public class BackupableDBTest {
@Test @Test
public void backupDb() throws RocksDBException { public void backupDb() throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt = new BackupableDBOptions(
BackupableDB bdb = null; backupFolder.getRoot().getAbsolutePath())) {
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
// Create two backups // Create two backups
bdb.createNewBackup(false); bdb.createNewBackup(false);
bdb.createNewBackup(true); bdb.createNewBackup(true);
verifyNumberOfValidBackups(bdb, 2); verifyNumberOfValidBackups(bdb, 2);
} finally {
if (bdb != null) {
bdb.close();
}
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@Test @Test
public void deleteBackup() throws RocksDBException { public void deleteBackup() throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt = new BackupableDBOptions(
BackupableDB bdb = null; backupFolder.getRoot().getAbsolutePath())) {
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
// Create two backups // Create two backups
@ -82,20 +65,11 @@ public class BackupableDBTest {
verifyNumberOfValidBackups(bdb, 2); verifyNumberOfValidBackups(bdb, 2);
// Delete the first backup // Delete the first backup
bdb.deleteBackup(backupInfo.get(0).backupId()); bdb.deleteBackup(backupInfo.get(0).backupId());
List<BackupInfo> newBackupInfo = final List<BackupInfo> newBackupInfo =
verifyNumberOfValidBackups(bdb, 1); verifyNumberOfValidBackups(bdb, 1);
// The second backup must remain. // The second backup must remain.
assertThat(newBackupInfo.get(0).backupId()). assertThat(newBackupInfo.get(0).backupId()).
isEqualTo(backupInfo.get(1).backupId()); isEqualTo(backupInfo.get(1).backupId());
} finally {
if (bdb != null) {
bdb.close();
}
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -103,28 +77,23 @@ public class BackupableDBTest {
@Test @Test
public void deleteBackupWithRestoreBackupableDB() public void deleteBackupWithRestoreBackupableDB()
throws RocksDBException { throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt = new BackupableDBOptions(
BackupableDB bdb = null; backupFolder.getRoot().getAbsolutePath())) {
RestoreBackupableDB rdb = null;
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
// Create two backups // Create two backups
bdb.createNewBackup(false); bdb.createNewBackup(false);
bdb.createNewBackup(true); bdb.createNewBackup(true);
List<BackupInfo> backupInfo = final List<BackupInfo> backupInfo =
verifyNumberOfValidBackups(bdb, 2); verifyNumberOfValidBackups(bdb, 2);
// init RestoreBackupableDB // init RestoreBackupableDB
rdb = new RestoreBackupableDB(bopt); try (final RestoreBackupableDB rdb = new RestoreBackupableDB(bopt)) {
// Delete the first backup // Delete the first backup
rdb.deleteBackup(backupInfo.get(0).backupId()); rdb.deleteBackup(backupInfo.get(0).backupId());
// Fetch backup info using RestoreBackupableDB // Fetch backup info using RestoreBackupableDB
@ -132,36 +101,21 @@ public class BackupableDBTest {
// The second backup must remain. // The second backup must remain.
assertThat(newBackupInfo.get(0).backupId()). assertThat(newBackupInfo.get(0).backupId()).
isEqualTo(backupInfo.get(1).backupId()); isEqualTo(backupInfo.get(1).backupId());
} finally {
if (bdb != null) {
bdb.close();
} }
if (rdb != null) {
rdb.dispose();
}
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@Test @Test
public void purgeOldBackups() throws RocksDBException { public void purgeOldBackups() throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt = new BackupableDBOptions(
BackupableDB bdb = null; backupFolder.getRoot().getAbsolutePath())) {
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
// Create two backups // Create two backups
@ -169,24 +123,15 @@ public class BackupableDBTest {
bdb.createNewBackup(true); bdb.createNewBackup(true);
bdb.createNewBackup(true); bdb.createNewBackup(true);
bdb.createNewBackup(true); bdb.createNewBackup(true);
List<BackupInfo> backupInfo = final List<BackupInfo> backupInfo =
verifyNumberOfValidBackups(bdb, 4); verifyNumberOfValidBackups(bdb, 4);
// Delete everything except the latest backup // Delete everything except the latest backup
bdb.purgeOldBackups(1); bdb.purgeOldBackups(1);
List<BackupInfo> newBackupInfo = final List<BackupInfo> newBackupInfo =
verifyNumberOfValidBackups(bdb, 1); verifyNumberOfValidBackups(bdb, 1);
// The latest backup must remain. // The latest backup must remain.
assertThat(newBackupInfo.get(0).backupId()). assertThat(newBackupInfo.get(0).backupId()).
isEqualTo(backupInfo.get(3).backupId()); isEqualTo(backupInfo.get(3).backupId());
} finally {
if (bdb != null) {
bdb.close();
}
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -194,19 +139,15 @@ public class BackupableDBTest {
@Test @Test
public void purgeOldBackupsWithRestoreBackupableDb() public void purgeOldBackupsWithRestoreBackupableDb()
throws RocksDBException { throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt =
BackupableDB bdb = null; new BackupableDBOptions(backupFolder.getRoot().getAbsolutePath())
RestoreBackupableDB rdb = null; ) {
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
// Create two backups // Create two backups
@ -226,7 +167,7 @@ public class BackupableDBTest {
} }
} }
// init RestoreBackupableDB // init RestoreBackupableDB
rdb = new RestoreBackupableDB(bopt); try (final RestoreBackupableDB rdb = new RestoreBackupableDB(bopt)) {
// the same number of backups must // the same number of backups must
// exist using RestoreBackupableDB. // exist using RestoreBackupableDB.
verifyNumberOfValidBackups(rdb, 4); verifyNumberOfValidBackups(rdb, 4);
@ -234,18 +175,7 @@ public class BackupableDBTest {
infos = verifyNumberOfValidBackups(rdb, 1); infos = verifyNumberOfValidBackups(rdb, 1);
assertThat(infos.get(0).timestamp()). assertThat(infos.get(0).timestamp()).
isEqualTo(maxTimeBeforePurge); isEqualTo(maxTimeBeforePurge);
} finally {
if (bdb != null) {
bdb.close();
}
if (rdb != null) {
rdb.dispose();
} }
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -253,19 +183,15 @@ public class BackupableDBTest {
@Test @Test
public void restoreLatestBackup() public void restoreLatestBackup()
throws RocksDBException { throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt =
BackupableDB bdb = null; new BackupableDBOptions(
RestoreBackupableDB rdb = null; backupFolder.getRoot().getAbsolutePath())) {
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
bdb.createNewBackup(true); bdb.createNewBackup(true);
@ -278,33 +204,23 @@ public class BackupableDBTest {
bdb.put("key2".getBytes(), "valueV3".getBytes()); bdb.put("key2".getBytes(), "valueV3".getBytes());
assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V3"); assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V3");
assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V3"); assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V3");
bdb.close(); }
// init RestoreBackupableDB // init RestoreBackupableDB
rdb = new RestoreBackupableDB(bopt); try (final RestoreBackupableDB rdb = new RestoreBackupableDB(bopt)) {
verifyNumberOfValidBackups(rdb, 2); verifyNumberOfValidBackups(rdb, 2);
// restore db from latest backup // restore db from latest backup
rdb.restoreDBFromLatestBackup(dbFolder.getRoot().getAbsolutePath(), rdb.restoreDBFromLatestBackup(dbFolder.getRoot().getAbsolutePath(),
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
new RestoreOptions(false)); new RestoreOptions(false));
}
// Open database again. // Open database again.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Values must have suffix V2 because of restoring latest backup. // Values must have suffix V2 because of restoring latest backup.
assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V2"); assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V2");
assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V2"); assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V2");
} finally {
if (bdb != null) {
bdb.close();
}
if (rdb != null) {
rdb.dispose();
}
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -312,19 +228,14 @@ public class BackupableDBTest {
@Test @Test
public void restoreFromBackup() public void restoreFromBackup()
throws RocksDBException { throws RocksDBException {
Options opt = null; try (final Options opt = new Options().setCreateIfMissing(true);
BackupableDBOptions bopt = null; final BackupableDBOptions bopt = new BackupableDBOptions(
BackupableDB bdb = null; backupFolder.getRoot().getAbsolutePath())) {
RestoreBackupableDB rdb = null;
try {
opt = new Options().setCreateIfMissing(true);
bopt = new BackupableDBOptions(
backupFolder.getRoot().getAbsolutePath());
assertThat(bopt.backupDir()).isEqualTo( assertThat(bopt.backupDir()).isEqualTo(
backupFolder.getRoot().getAbsolutePath()); backupFolder.getRoot().getAbsolutePath());
// Open empty database. // Open empty database.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Fill database with some test values // Fill database with some test values
prepareDatabase(bdb); prepareDatabase(bdb);
bdb.createNewBackup(true); bdb.createNewBackup(true);
@ -337,34 +248,24 @@ public class BackupableDBTest {
bdb.put("key2".getBytes(), "valueV3".getBytes()); bdb.put("key2".getBytes(), "valueV3".getBytes());
assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V3"); assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V3");
assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V3"); assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V3");
bdb.close(); }
// init RestoreBackupableDB // init RestoreBackupableDB
rdb = new RestoreBackupableDB(bopt); try (final RestoreBackupableDB rdb = new RestoreBackupableDB(bopt)) {
List<BackupInfo> backupInfo = verifyNumberOfValidBackups(rdb, 2); final List<BackupInfo> backupInfo = verifyNumberOfValidBackups(rdb, 2);
// restore db from first backup // restore db from first backup
rdb.restoreDBFromBackup(backupInfo.get(0).backupId(), rdb.restoreDBFromBackup(backupInfo.get(0).backupId(),
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
new RestoreOptions(false)); new RestoreOptions(false));
}
// Open database again. // Open database again.
bdb = BackupableDB.open(opt, bopt, try (final BackupableDB bdb = BackupableDB.open(opt, bopt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
// Values must have suffix V2 because of restoring latest backup. // Values must have suffix V2 because of restoring latest backup.
assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V1"); assertThat(new String(bdb.get("key1".getBytes()))).endsWith("V1");
assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V1"); assertThat(new String(bdb.get("key2".getBytes()))).endsWith("V1");
} finally {
if (bdb != null) {
bdb.close();
}
if (rdb != null) {
rdb.dispose();
}
if (bopt != null) {
bopt.dispose();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -377,8 +278,8 @@ public class BackupableDBTest {
* @throws RocksDBException thrown if an error occurs within the native * @throws RocksDBException thrown if an error occurs within the native
* part of the library. * part of the library.
*/ */
private List<BackupInfo> verifyNumberOfValidBackups(BackupableDB bdb, private List<BackupInfo> verifyNumberOfValidBackups(final BackupableDB bdb,
int expectedNumberOfBackups) throws RocksDBException { final int expectedNumberOfBackups) throws RocksDBException {
// Verify that backups exist // Verify that backups exist
assertThat(bdb.getCorruptedBackups().length). assertThat(bdb.getCorruptedBackups().length).
isEqualTo(0); isEqualTo(0);
@ -398,7 +299,7 @@ public class BackupableDBTest {
* part of the library. * part of the library.
*/ */
private List<BackupInfo> verifyNumberOfValidBackups( private List<BackupInfo> verifyNumberOfValidBackups(
RestoreBackupableDB rdb, int expectedNumberOfBackups) final RestoreBackupableDB rdb, final int expectedNumberOfBackups)
throws RocksDBException { throws RocksDBException {
// Verify that backups exist // Verify that backups exist
assertThat(rdb.getCorruptedBackups().length). assertThat(rdb.getCorruptedBackups().length).
@ -417,7 +318,7 @@ public class BackupableDBTest {
* @throws RocksDBException thrown if an error occurs within the native * @throws RocksDBException thrown if an error occurs within the native
* part of the library. * part of the library.
*/ */
private void prepareDatabase(RocksDB db) private void prepareDatabase(final RocksDB db)
throws RocksDBException { throws RocksDBException {
db.put("key1".getBytes(), "valueV1".getBytes()); db.put("key1".getBytes(), "valueV1".getBytes());
db.put("key2".getBytes(), "valueV1".getBytes()); db.put("key2".getBytes(), "valueV1".getBytes());

@ -131,34 +131,20 @@ public class BlockBasedTableConfigTest {
@Test @Test
public void blockBasedTableWithFilter() { public void blockBasedTableWithFilter() {
Options options = null; try(final Options options = new Options()
try { .setTableFormatConfig(new BlockBasedTableConfig()
options = new Options(); .setFilter(new BloomFilter(10)))) {
options.setTableFormatConfig(
new BlockBasedTableConfig().setFilter(
new BloomFilter(10)));
assertThat(options.tableFactoryName()). assertThat(options.tableFactoryName()).
isEqualTo("BlockBasedTable"); isEqualTo("BlockBasedTable");
} finally {
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void blockBasedTableWithoutFilter() { public void blockBasedTableWithoutFilter() {
Options options = null; try(final Options options = new Options().setTableFormatConfig(
try { new BlockBasedTableConfig().setFilter(null))) {
options = new Options();
options.setTableFormatConfig(
new BlockBasedTableConfig().setFilter(null));
assertThat(options.tableFactoryName()). assertThat(options.tableFactoryName()).
isEqualTo("BlockBasedTable"); isEqualTo("BlockBasedTable");
} finally {
if (options != null) {
options.dispose();
}
} }
} }

@ -22,76 +22,61 @@ public class CheckPointTest {
@Test @Test
public void checkPoint() throws RocksDBException { public void checkPoint() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().
Options options = null; setCreateIfMissing(true)) {
Checkpoint checkpoint = null;
try { try (final RocksDB db = RocksDB.open(options,
options = new Options(). dbFolder.getRoot().getAbsolutePath())) {
setCreateIfMissing(true);
db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
checkpoint = Checkpoint.create(db); try (final Checkpoint checkpoint = Checkpoint.create(db)) {
checkpoint.createCheckpoint(checkpointFolder. checkpoint.createCheckpoint(checkpointFolder.
getRoot().getAbsolutePath() + "/snapshot1"); getRoot().getAbsolutePath() + "/snapshot1");
db.put("key2".getBytes(), "value2".getBytes()); db.put("key2".getBytes(), "value2".getBytes());
checkpoint.createCheckpoint(checkpointFolder. checkpoint.createCheckpoint(checkpointFolder.
getRoot().getAbsolutePath() + "/snapshot2"); getRoot().getAbsolutePath() + "/snapshot2");
db.close(); }
db = RocksDB.open(options, }
try (final RocksDB db = RocksDB.open(options,
checkpointFolder.getRoot().getAbsolutePath() + checkpointFolder.getRoot().getAbsolutePath() +
"/snapshot1"); "/snapshot1")) {
assertThat(new String(db.get("key".getBytes()))). assertThat(new String(db.get("key".getBytes()))).
isEqualTo("value"); isEqualTo("value");
assertThat(db.get("key2".getBytes())).isNull(); assertThat(db.get("key2".getBytes())).isNull();
db.close(); }
db = RocksDB.open(options,
try (final RocksDB db = RocksDB.open(options,
checkpointFolder.getRoot().getAbsolutePath() + checkpointFolder.getRoot().getAbsolutePath() +
"/snapshot2"); "/snapshot2")) {
assertThat(new String(db.get("key".getBytes()))). assertThat(new String(db.get("key".getBytes()))).
isEqualTo("value"); isEqualTo("value");
assertThat(new String(db.get("key2".getBytes()))). assertThat(new String(db.get("key2".getBytes()))).
isEqualTo("value2"); isEqualTo("value2");
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
if (checkpoint != null) {
checkpoint.dispose();
} }
} }
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void failIfDbIsNull() { public void failIfDbIsNull() {
Checkpoint.create(null); try (final Checkpoint checkpoint = Checkpoint.create(null)) {
}
} }
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void failIfDbNotInitialized() throws RocksDBException { public void failIfDbNotInitialized() throws RocksDBException {
RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath()); try (final RocksDB db = RocksDB.open(
db.dispose(); dbFolder.getRoot().getAbsolutePath())) {
db.close();
Checkpoint.create(db); Checkpoint.create(db);
} }
}
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failWithIllegalPath() throws RocksDBException { public void failWithIllegalPath() throws RocksDBException {
RocksDB db = null; try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
Checkpoint checkpoint = null; final Checkpoint checkpoint = Checkpoint.create(db)) {
try {
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
checkpoint = Checkpoint.create(db);
checkpoint.createCheckpoint("/Z:///:\\C:\\TZ/-"); checkpoint.createCheckpoint("/Z:///:\\C:\\TZ/-");
} finally {
if (db != null) {
db.close();
}
if (checkpoint != null) {
checkpoint.dispose();
}
} }
} }
} }

@ -26,616 +26,386 @@ public class ColumnFamilyOptionsTest {
@Test @Test
public void getColumnFamilyOptionsFromProps() { public void getColumnFamilyOptionsFromProps() {
ColumnFamilyOptions opt = null;
try {
// setup sample properties
Properties properties = new Properties(); Properties properties = new Properties();
properties.put("write_buffer_size", "112"); properties.put("write_buffer_size", "112");
properties.put("max_write_buffer_number", "13"); properties.put("max_write_buffer_number", "13");
opt = ColumnFamilyOptions.
getColumnFamilyOptionsFromProps(properties); try (final ColumnFamilyOptions opt = ColumnFamilyOptions.
getColumnFamilyOptionsFromProps(properties)) {
// setup sample properties
assertThat(opt).isNotNull(); assertThat(opt).isNotNull();
assertThat(String.valueOf(opt.writeBufferSize())). assertThat(String.valueOf(opt.writeBufferSize())).
isEqualTo(properties.get("write_buffer_size")); isEqualTo(properties.get("write_buffer_size"));
assertThat(String.valueOf(opt.maxWriteBufferNumber())). assertThat(String.valueOf(opt.maxWriteBufferNumber())).
isEqualTo(properties.get("max_write_buffer_number")); isEqualTo(properties.get("max_write_buffer_number"));
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void failColumnFamilyOptionsFromPropsWithIllegalValue() { public void failColumnFamilyOptionsFromPropsWithIllegalValue() {
ColumnFamilyOptions opt = null;
try {
// setup sample properties // setup sample properties
Properties properties = new Properties(); final Properties properties = new Properties();
properties.put("tomato", "1024"); properties.put("tomato", "1024");
properties.put("burger", "2"); properties.put("burger", "2");
opt = ColumnFamilyOptions.
getColumnFamilyOptionsFromProps(properties); try (final ColumnFamilyOptions opt =
ColumnFamilyOptions.getColumnFamilyOptionsFromProps(properties)) {
assertThat(opt).isNull(); assertThat(opt).isNull();
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void failColumnFamilyOptionsFromPropsWithNullValue() { public void failColumnFamilyOptionsFromPropsWithNullValue() {
ColumnFamilyOptions.getColumnFamilyOptionsFromProps(null); try (final ColumnFamilyOptions opt =
ColumnFamilyOptions.getColumnFamilyOptionsFromProps(null)) {
}
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void failColumnFamilyOptionsFromPropsWithEmptyProps() { public void failColumnFamilyOptionsFromPropsWithEmptyProps() {
try (final ColumnFamilyOptions opt =
ColumnFamilyOptions.getColumnFamilyOptionsFromProps( ColumnFamilyOptions.getColumnFamilyOptionsFromProps(
new Properties()); new Properties())) {
}
} }
@Test @Test
public void writeBufferSize() throws RocksDBException { public void writeBufferSize() throws RocksDBException {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong();
opt.setWriteBufferSize(longValue); opt.setWriteBufferSize(longValue);
assertThat(opt.writeBufferSize()).isEqualTo(longValue); assertThat(opt.writeBufferSize()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxWriteBufferNumber() { public void maxWriteBufferNumber() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setMaxWriteBufferNumber(intValue); opt.setMaxWriteBufferNumber(intValue);
assertThat(opt.maxWriteBufferNumber()).isEqualTo(intValue); assertThat(opt.maxWriteBufferNumber()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void minWriteBufferNumberToMerge() { public void minWriteBufferNumberToMerge() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setMinWriteBufferNumberToMerge(intValue); opt.setMinWriteBufferNumberToMerge(intValue);
assertThat(opt.minWriteBufferNumberToMerge()).isEqualTo(intValue); assertThat(opt.minWriteBufferNumberToMerge()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void numLevels() { public void numLevels() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setNumLevels(intValue); opt.setNumLevels(intValue);
assertThat(opt.numLevels()).isEqualTo(intValue); assertThat(opt.numLevels()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void levelZeroFileNumCompactionTrigger() { public void levelZeroFileNumCompactionTrigger() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setLevelZeroFileNumCompactionTrigger(intValue); opt.setLevelZeroFileNumCompactionTrigger(intValue);
assertThat(opt.levelZeroFileNumCompactionTrigger()).isEqualTo(intValue); assertThat(opt.levelZeroFileNumCompactionTrigger()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void levelZeroSlowdownWritesTrigger() { public void levelZeroSlowdownWritesTrigger() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setLevelZeroSlowdownWritesTrigger(intValue); opt.setLevelZeroSlowdownWritesTrigger(intValue);
assertThat(opt.levelZeroSlowdownWritesTrigger()).isEqualTo(intValue); assertThat(opt.levelZeroSlowdownWritesTrigger()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void levelZeroStopWritesTrigger() { public void levelZeroStopWritesTrigger() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setLevelZeroStopWritesTrigger(intValue); opt.setLevelZeroStopWritesTrigger(intValue);
assertThat(opt.levelZeroStopWritesTrigger()).isEqualTo(intValue); assertThat(opt.levelZeroStopWritesTrigger()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void targetFileSizeBase() { public void targetFileSizeBase() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong();
opt.setTargetFileSizeBase(longValue); opt.setTargetFileSizeBase(longValue);
assertThat(opt.targetFileSizeBase()).isEqualTo(longValue); assertThat(opt.targetFileSizeBase()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void targetFileSizeMultiplier() { public void targetFileSizeMultiplier() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setTargetFileSizeMultiplier(intValue); opt.setTargetFileSizeMultiplier(intValue);
assertThat(opt.targetFileSizeMultiplier()).isEqualTo(intValue); assertThat(opt.targetFileSizeMultiplier()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxBytesForLevelBase() { public void maxBytesForLevelBase() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong();
opt.setMaxBytesForLevelBase(longValue); opt.setMaxBytesForLevelBase(longValue);
assertThat(opt.maxBytesForLevelBase()).isEqualTo(longValue); assertThat(opt.maxBytesForLevelBase()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void levelCompactionDynamicLevelBytes() { public void levelCompactionDynamicLevelBytes() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try {
opt = new ColumnFamilyOptions();
final boolean boolValue = rand.nextBoolean(); final boolean boolValue = rand.nextBoolean();
opt.setLevelCompactionDynamicLevelBytes(boolValue); opt.setLevelCompactionDynamicLevelBytes(boolValue);
assertThat(opt.levelCompactionDynamicLevelBytes()) assertThat(opt.levelCompactionDynamicLevelBytes())
.isEqualTo(boolValue); .isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxBytesForLevelMultiplier() { public void maxBytesForLevelMultiplier() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setMaxBytesForLevelMultiplier(intValue); opt.setMaxBytesForLevelMultiplier(intValue);
assertThat(opt.maxBytesForLevelMultiplier()).isEqualTo(intValue); assertThat(opt.maxBytesForLevelMultiplier()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void expandedCompactionFactor() { public void expandedCompactionFactor() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setExpandedCompactionFactor(intValue); opt.setExpandedCompactionFactor(intValue);
assertThat(opt.expandedCompactionFactor()).isEqualTo(intValue); assertThat(opt.expandedCompactionFactor()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void sourceCompactionFactor() { public void sourceCompactionFactor() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setSourceCompactionFactor(intValue); opt.setSourceCompactionFactor(intValue);
assertThat(opt.sourceCompactionFactor()).isEqualTo(intValue); assertThat(opt.sourceCompactionFactor()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxGrandparentOverlapFactor() { public void maxGrandparentOverlapFactor() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setMaxGrandparentOverlapFactor(intValue); opt.setMaxGrandparentOverlapFactor(intValue);
assertThat(opt.maxGrandparentOverlapFactor()).isEqualTo(intValue); assertThat(opt.maxGrandparentOverlapFactor()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void softRateLimit() { public void softRateLimit() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final double doubleValue = rand.nextDouble();
opt = new ColumnFamilyOptions();
double doubleValue = rand.nextDouble();
opt.setSoftRateLimit(doubleValue); opt.setSoftRateLimit(doubleValue);
assertThat(opt.softRateLimit()).isEqualTo(doubleValue); assertThat(opt.softRateLimit()).isEqualTo(doubleValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void hardRateLimit() { public void hardRateLimit() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final double doubleValue = rand.nextDouble();
opt = new ColumnFamilyOptions();
double doubleValue = rand.nextDouble();
opt.setHardRateLimit(doubleValue); opt.setHardRateLimit(doubleValue);
assertThat(opt.hardRateLimit()).isEqualTo(doubleValue); assertThat(opt.hardRateLimit()).isEqualTo(doubleValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void rateLimitDelayMaxMilliseconds() { public void rateLimitDelayMaxMilliseconds() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setRateLimitDelayMaxMilliseconds(intValue); opt.setRateLimitDelayMaxMilliseconds(intValue);
assertThat(opt.rateLimitDelayMaxMilliseconds()).isEqualTo(intValue); assertThat(opt.rateLimitDelayMaxMilliseconds()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void arenaBlockSize() throws RocksDBException { public void arenaBlockSize() throws RocksDBException {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong();
opt.setArenaBlockSize(longValue); opt.setArenaBlockSize(longValue);
assertThat(opt.arenaBlockSize()).isEqualTo(longValue); assertThat(opt.arenaBlockSize()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void disableAutoCompactions() { public void disableAutoCompactions() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new ColumnFamilyOptions();
boolean boolValue = rand.nextBoolean();
opt.setDisableAutoCompactions(boolValue); opt.setDisableAutoCompactions(boolValue);
assertThat(opt.disableAutoCompactions()).isEqualTo(boolValue); assertThat(opt.disableAutoCompactions()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void purgeRedundantKvsWhileFlush() { public void purgeRedundantKvsWhileFlush() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new ColumnFamilyOptions();
boolean boolValue = rand.nextBoolean();
opt.setPurgeRedundantKvsWhileFlush(boolValue); opt.setPurgeRedundantKvsWhileFlush(boolValue);
assertThat(opt.purgeRedundantKvsWhileFlush()).isEqualTo(boolValue); assertThat(opt.purgeRedundantKvsWhileFlush()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void verifyChecksumsInCompaction() { public void verifyChecksumsInCompaction() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new ColumnFamilyOptions();
boolean boolValue = rand.nextBoolean();
opt.setVerifyChecksumsInCompaction(boolValue); opt.setVerifyChecksumsInCompaction(boolValue);
assertThat(opt.verifyChecksumsInCompaction()).isEqualTo(boolValue); assertThat(opt.verifyChecksumsInCompaction()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void filterDeletes() { public void filterDeletes() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new ColumnFamilyOptions();
boolean boolValue = rand.nextBoolean();
opt.setFilterDeletes(boolValue); opt.setFilterDeletes(boolValue);
assertThat(opt.filterDeletes()).isEqualTo(boolValue); assertThat(opt.filterDeletes()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxSequentialSkipInIterations() { public void maxSequentialSkipInIterations() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong();
opt.setMaxSequentialSkipInIterations(longValue); opt.setMaxSequentialSkipInIterations(longValue);
assertThat(opt.maxSequentialSkipInIterations()).isEqualTo(longValue); assertThat(opt.maxSequentialSkipInIterations()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void inplaceUpdateSupport() { public void inplaceUpdateSupport() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new ColumnFamilyOptions();
boolean boolValue = rand.nextBoolean();
opt.setInplaceUpdateSupport(boolValue); opt.setInplaceUpdateSupport(boolValue);
assertThat(opt.inplaceUpdateSupport()).isEqualTo(boolValue); assertThat(opt.inplaceUpdateSupport()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void inplaceUpdateNumLocks() throws RocksDBException { public void inplaceUpdateNumLocks() throws RocksDBException {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong();
opt.setInplaceUpdateNumLocks(longValue); opt.setInplaceUpdateNumLocks(longValue);
assertThat(opt.inplaceUpdateNumLocks()).isEqualTo(longValue); assertThat(opt.inplaceUpdateNumLocks()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void memtablePrefixBloomBits() { public void memtablePrefixBloomBits() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
int intValue = rand.nextInt();
opt.setMemtablePrefixBloomBits(intValue); opt.setMemtablePrefixBloomBits(intValue);
assertThat(opt.memtablePrefixBloomBits()).isEqualTo(intValue); assertThat(opt.memtablePrefixBloomBits()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void memtablePrefixBloomProbes() { public void memtablePrefixBloomProbes() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
opt.setMemtablePrefixBloomProbes(intValue); opt.setMemtablePrefixBloomProbes(intValue);
assertThat(opt.memtablePrefixBloomProbes()).isEqualTo(intValue); assertThat(opt.memtablePrefixBloomProbes()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void bloomLocality() { public void bloomLocality() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
opt.setBloomLocality(intValue); opt.setBloomLocality(intValue);
assertThat(opt.bloomLocality()).isEqualTo(intValue); assertThat(opt.bloomLocality()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxSuccessiveMerges() throws RocksDBException { public void maxSuccessiveMerges() throws RocksDBException {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final long longValue = rand.nextLong();
long longValue = rand.nextLong();
opt = new ColumnFamilyOptions();
opt.setMaxSuccessiveMerges(longValue); opt.setMaxSuccessiveMerges(longValue);
assertThat(opt.maxSuccessiveMerges()).isEqualTo(longValue); assertThat(opt.maxSuccessiveMerges()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void minPartialMergeOperands() { public void minPartialMergeOperands() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final int intValue = rand.nextInt();
int intValue = rand.nextInt();
opt = new ColumnFamilyOptions();
opt.setMinPartialMergeOperands(intValue); opt.setMinPartialMergeOperands(intValue);
assertThat(opt.minPartialMergeOperands()).isEqualTo(intValue); assertThat(opt.minPartialMergeOperands()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void optimizeFiltersForHits() { public void optimizeFiltersForHits() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try { final boolean aBoolean = rand.nextBoolean();
boolean aBoolean = rand.nextBoolean();
opt = new ColumnFamilyOptions();
opt.setOptimizeFiltersForHits(aBoolean); opt.setOptimizeFiltersForHits(aBoolean);
assertThat(opt.optimizeFiltersForHits()).isEqualTo(aBoolean); assertThat(opt.optimizeFiltersForHits()).isEqualTo(aBoolean);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void memTable() throws RocksDBException { public void memTable() throws RocksDBException {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try {
opt = new ColumnFamilyOptions();
opt.setMemTableConfig(new HashLinkedListMemTableConfig()); opt.setMemTableConfig(new HashLinkedListMemTableConfig());
assertThat(opt.memTableFactoryName()). assertThat(opt.memTableFactoryName()).
isEqualTo("HashLinkedListRepFactory"); isEqualTo("HashLinkedListRepFactory");
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void comparator() throws RocksDBException { public void comparator() throws RocksDBException {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try {
opt = new ColumnFamilyOptions();
opt.setComparator(BuiltinComparator.BYTEWISE_COMPARATOR); opt.setComparator(BuiltinComparator.BYTEWISE_COMPARATOR);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void linkageOfPrepMethods() { public void linkageOfPrepMethods() {
ColumnFamilyOptions options = null; try (final ColumnFamilyOptions options = new ColumnFamilyOptions()) {
try {
options = new ColumnFamilyOptions();
options.optimizeUniversalStyleCompaction(); options.optimizeUniversalStyleCompaction();
options.optimizeUniversalStyleCompaction(4000); options.optimizeUniversalStyleCompaction(4000);
options.optimizeLevelStyleCompaction(); options.optimizeLevelStyleCompaction();
options.optimizeLevelStyleCompaction(3000); options.optimizeLevelStyleCompaction(3000);
options.optimizeForPointLookup(10); options.optimizeForPointLookup(10);
} finally {
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void shouldSetTestPrefixExtractor() { public void shouldSetTestPrefixExtractor() {
ColumnFamilyOptions options = null; try (final ColumnFamilyOptions options = new ColumnFamilyOptions()) {
try {
options = new ColumnFamilyOptions();
options.useFixedLengthPrefixExtractor(100); options.useFixedLengthPrefixExtractor(100);
options.useFixedLengthPrefixExtractor(10); options.useFixedLengthPrefixExtractor(10);
} finally {
if (options != null) {
options.dispose();
} }
} }
}
@Test @Test
public void shouldSetTestCappedPrefixExtractor() { public void shouldSetTestCappedPrefixExtractor() {
ColumnFamilyOptions options = null; try (final ColumnFamilyOptions options = new ColumnFamilyOptions()) {
try {
options = new ColumnFamilyOptions();
options.useCappedPrefixExtractor(100); options.useCappedPrefixExtractor(100);
options.useCappedPrefixExtractor(10); options.useCappedPrefixExtractor(10);
} finally {
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void compressionTypes() { public void compressionTypes() {
ColumnFamilyOptions columnFamilyOptions = null; try (final ColumnFamilyOptions columnFamilyOptions
try { = new ColumnFamilyOptions()) {
columnFamilyOptions = new ColumnFamilyOptions(); for (final CompressionType compressionType :
for (CompressionType compressionType :
CompressionType.values()) { CompressionType.values()) {
columnFamilyOptions.setCompressionType(compressionType); columnFamilyOptions.setCompressionType(compressionType);
assertThat(columnFamilyOptions.compressionType()). assertThat(columnFamilyOptions.compressionType()).
@ -643,18 +413,13 @@ public class ColumnFamilyOptionsTest {
assertThat(CompressionType.valueOf("NO_COMPRESSION")). assertThat(CompressionType.valueOf("NO_COMPRESSION")).
isEqualTo(CompressionType.NO_COMPRESSION); isEqualTo(CompressionType.NO_COMPRESSION);
} }
} finally {
if (columnFamilyOptions != null) {
columnFamilyOptions.dispose();
}
} }
} }
@Test @Test
public void compressionPerLevel() { public void compressionPerLevel() {
ColumnFamilyOptions columnFamilyOptions = null; try (final ColumnFamilyOptions columnFamilyOptions
try { = new ColumnFamilyOptions()) {
columnFamilyOptions = new ColumnFamilyOptions();
assertThat(columnFamilyOptions.compressionPerLevel()).isEmpty(); assertThat(columnFamilyOptions.compressionPerLevel()).isEmpty();
List<CompressionType> compressionTypeList = new ArrayList<>(); List<CompressionType> compressionTypeList = new ArrayList<>();
for (int i = 0; i < columnFamilyOptions.numLevels(); i++) { for (int i = 0; i < columnFamilyOptions.numLevels(); i++) {
@ -666,18 +431,13 @@ public class ColumnFamilyOptionsTest {
assertThat(compressionType).isEqualTo( assertThat(compressionType).isEqualTo(
CompressionType.NO_COMPRESSION); CompressionType.NO_COMPRESSION);
} }
} finally {
if (columnFamilyOptions != null) {
columnFamilyOptions.dispose();
}
} }
} }
@Test @Test
public void differentCompressionsPerLevel() { public void differentCompressionsPerLevel() {
ColumnFamilyOptions columnFamilyOptions = null; try (final ColumnFamilyOptions columnFamilyOptions
try { = new ColumnFamilyOptions()) {
columnFamilyOptions = new ColumnFamilyOptions();
columnFamilyOptions.setNumLevels(3); columnFamilyOptions.setNumLevels(3);
assertThat(columnFamilyOptions.compressionPerLevel()).isEmpty(); assertThat(columnFamilyOptions.compressionPerLevel()).isEmpty();
@ -697,38 +457,27 @@ public class ColumnFamilyOptionsTest {
CompressionType.SNAPPY_COMPRESSION, CompressionType.SNAPPY_COMPRESSION,
CompressionType.LZ4_COMPRESSION); CompressionType.LZ4_COMPRESSION);
} finally {
if (columnFamilyOptions != null) {
columnFamilyOptions.dispose();
}
} }
} }
@Test @Test
public void compactionStyles() { public void compactionStyles() {
ColumnFamilyOptions ColumnFamilyOptions = null; try (final ColumnFamilyOptions columnFamilyOptions
try { = new ColumnFamilyOptions()) {
ColumnFamilyOptions = new ColumnFamilyOptions(); for (final CompactionStyle compactionStyle :
for (CompactionStyle compactionStyle :
CompactionStyle.values()) { CompactionStyle.values()) {
ColumnFamilyOptions.setCompactionStyle(compactionStyle); columnFamilyOptions.setCompactionStyle(compactionStyle);
assertThat(ColumnFamilyOptions.compactionStyle()). assertThat(columnFamilyOptions.compactionStyle()).
isEqualTo(compactionStyle); isEqualTo(compactionStyle);
assertThat(CompactionStyle.valueOf("FIFO")). assertThat(CompactionStyle.valueOf("FIFO")).
isEqualTo(CompactionStyle.FIFO); isEqualTo(CompactionStyle.FIFO);
} }
} finally {
if (ColumnFamilyOptions != null) {
ColumnFamilyOptions.dispose();
}
} }
} }
@Test @Test
public void maxTableFilesSizeFIFO() { public void maxTableFilesSizeFIFO() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try {
opt = new ColumnFamilyOptions();
long longValue = rand.nextLong(); long longValue = rand.nextLong();
// Size has to be positive // Size has to be positive
longValue = (longValue < 0) ? -longValue : longValue; longValue = (longValue < 0) ? -longValue : longValue;
@ -736,10 +485,6 @@ public class ColumnFamilyOptionsTest {
opt.setMaxTableFilesSizeFIFO(longValue); opt.setMaxTableFilesSizeFIFO(longValue);
assertThat(opt.maxTableFilesSizeFIFO()). assertThat(opt.maxTableFilesSizeFIFO()).
isEqualTo(longValue); isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
} }

@ -25,43 +25,26 @@ public class ColumnFamilyTest {
@Test @Test
public void listColumnFamilies() throws RocksDBException { public void listColumnFamilies() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
try { dbFolder.getRoot().getAbsolutePath())) {
options = new Options();
options.setCreateIfMissing(true);
DBOptions dbOptions = new DBOptions();
dbOptions.setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
// Test listColumnFamilies // Test listColumnFamilies
List<byte[]> columnFamilyNames; final List<byte[]> columnFamilyNames = RocksDB.listColumnFamilies(options,
columnFamilyNames = RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath());
assertThat(columnFamilyNames).isNotNull(); assertThat(columnFamilyNames).isNotNull();
assertThat(columnFamilyNames.size()).isGreaterThan(0); assertThat(columnFamilyNames.size()).isGreaterThan(0);
assertThat(columnFamilyNames.size()).isEqualTo(1); assertThat(columnFamilyNames.size()).isEqualTo(1);
assertThat(new String(columnFamilyNames.get(0))).isEqualTo("default"); assertThat(new String(columnFamilyNames.get(0))).isEqualTo("default");
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void defaultColumnFamily() throws RocksDBException { public void defaultColumnFamily() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
ColumnFamilyHandle cfh; dbFolder.getRoot().getAbsolutePath())) {
final ColumnFamilyHandle cfh = db.getDefaultColumnFamily();
try { try {
options = new Options().setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
cfh = db.getDefaultColumnFamily();
assertThat(cfh).isNotNull(); assertThat(cfh).isNotNull();
final byte[] key = "key".getBytes(); final byte[] key = "key".getBytes();
@ -74,66 +57,52 @@ public class ColumnFamilyTest {
assertThat(cfh).isNotNull(); assertThat(cfh).isNotNull();
assertThat(actualValue).isEqualTo(value); assertThat(actualValue).isEqualTo(value);
} finally { } finally {
if (db != null) { cfh.close();
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void createColumnFamily() throws RocksDBException { public void createColumnFamily() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
ColumnFamilyHandle columnFamilyHandle = null; dbFolder.getRoot().getAbsolutePath())) {
final ColumnFamilyHandle columnFamilyHandle = db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf".getBytes(),
new ColumnFamilyOptions()));
try { try {
options = new Options(); final List<byte[]> columnFamilyNames = RocksDB.listColumnFamilies(
options.setCreateIfMissing(true); options, dbFolder.getRoot().getAbsolutePath());
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
columnFamilyHandle = db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf".getBytes(), new ColumnFamilyOptions()));
List<byte[]> columnFamilyNames;
columnFamilyNames = RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath());
assertThat(columnFamilyNames).isNotNull(); assertThat(columnFamilyNames).isNotNull();
assertThat(columnFamilyNames.size()).isGreaterThan(0); assertThat(columnFamilyNames.size()).isGreaterThan(0);
assertThat(columnFamilyNames.size()).isEqualTo(2); assertThat(columnFamilyNames.size()).isEqualTo(2);
assertThat(new String(columnFamilyNames.get(0))).isEqualTo("default"); assertThat(new String(columnFamilyNames.get(0))).isEqualTo("default");
assertThat(new String(columnFamilyNames.get(1))).isEqualTo("new_cf"); assertThat(new String(columnFamilyNames.get(1))).isEqualTo("new_cf");
} finally { } finally {
if (columnFamilyHandle != null) { columnFamilyHandle.close();
columnFamilyHandle.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void openWithColumnFamilies() throws RocksDBException { public void openWithColumnFamilies() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfNames = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes())
new ArrayList<>(); );
List<ColumnFamilyHandle> columnFamilyHandleList =
final List<ColumnFamilyHandle> columnFamilyHandleList =
new ArrayList<>(); new ArrayList<>();
try {
options = new DBOptions();
options.setCreateIfMissing(true);
options.setCreateMissingColumnFamilies(true);
// Test open database with column family names // Test open database with column family names
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)); try (final DBOptions options = new DBOptions()
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes())); .setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), cfNames,
columnFamilyHandleList)) {
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(), try {
cfNames, columnFamilyHandleList);
assertThat(columnFamilyHandleList.size()).isEqualTo(2); assertThat(columnFamilyHandleList.size()).isEqualTo(2);
db.put("dfkey1".getBytes(), "dfvalue".getBytes()); db.put("dfkey1".getBytes(), "dfvalue".getBytes());
db.put(columnFamilyHandleList.get(0), "dfkey2".getBytes(), db.put(columnFamilyHandleList.get(0), "dfkey2".getBytes(),
@ -154,43 +123,38 @@ public class ColumnFamilyTest {
assertThat(db.get(columnFamilyHandleList.get(0), new ReadOptions(), assertThat(db.get(columnFamilyHandleList.get(0), new ReadOptions(),
"dfkey2".getBytes())).isNull(); "dfkey2".getBytes())).isNull();
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void getWithOutValueAndCf() throws RocksDBException { public void getWithOutValueAndCf() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
List<ColumnFamilyDescriptor> cfDescriptors = final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList =
new ArrayList<>();
try {
options = new DBOptions();
options.setCreateIfMissing(true);
options.setCreateMissingColumnFamilies(true);
// Test open database with column family names // Test open database with column family names
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)); try (final DBOptions options = new DBOptions()
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(), .setCreateIfMissing(true)
cfDescriptors, columnFamilyHandleList); .setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)) {
try {
db.put(columnFamilyHandleList.get(0), new WriteOptions(), db.put(columnFamilyHandleList.get(0), new WriteOptions(),
"key1".getBytes(), "value".getBytes()); "key1".getBytes(), "value".getBytes());
db.put("key2".getBytes(), "12345678".getBytes()); db.put("key2".getBytes(), "12345678".getBytes());
byte[] outValue = new byte[5]; final byte[] outValue = new byte[5];
// not found value // not found value
int getResult = db.get("keyNotFound".getBytes(), outValue); int getResult = db.get("keyNotFound".getBytes(), outValue);
assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND); assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
// found value which fits in outValue // found value which fits in outValue
getResult = db.get(columnFamilyHandleList.get(0), "key1".getBytes(), outValue); getResult = db.get(columnFamilyHandleList.get(0), "key1".getBytes(),
outValue);
assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
assertThat(outValue).isEqualTo("value".getBytes()); assertThat(outValue).isEqualTo("value".getBytes());
// found value which fits partially // found value which fits partially
@ -199,79 +163,62 @@ public class ColumnFamilyTest {
assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
assertThat(outValue).isEqualTo("12345".getBytes()); assertThat(outValue).isEqualTo("12345".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void createWriteDropColumnFamily() throws RocksDBException { public void createWriteDropColumnFamily() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions opt = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ColumnFamilyDescriptor("new_cf".getBytes()));
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
try (final DBOptions options = new DBOptions()
.setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)) {
ColumnFamilyHandle tmpColumnFamilyHandle = null; ColumnFamilyHandle tmpColumnFamilyHandle = null;
List<ColumnFamilyDescriptor> cfNames =
new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList =
new ArrayList<>();
try { try {
opt = new DBOptions();
opt.setCreateIfMissing(true);
opt.setCreateMissingColumnFamilies(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
tmpColumnFamilyHandle = db.createColumnFamily( tmpColumnFamilyHandle = db.createColumnFamily(
new ColumnFamilyDescriptor("tmpCF".getBytes(), new ColumnFamilyOptions())); new ColumnFamilyDescriptor("tmpCF".getBytes(),
new ColumnFamilyOptions()));
db.put(tmpColumnFamilyHandle, "key".getBytes(), "value".getBytes()); db.put(tmpColumnFamilyHandle, "key".getBytes(), "value".getBytes());
db.dropColumnFamily(tmpColumnFamilyHandle); db.dropColumnFamily(tmpColumnFamilyHandle);
tmpColumnFamilyHandle.dispose();
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
columnFamilyHandle.dispose();
}
if (tmpColumnFamilyHandle != null) { if (tmpColumnFamilyHandle != null) {
tmpColumnFamilyHandle.dispose(); tmpColumnFamilyHandle.close();
} }
if (db != null) { for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
db.close(); columnFamilyHandle.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@Test @Test
public void writeBatch() throws RocksDBException { public void writeBatch() throws RocksDBException {
RocksDB db = null; try (final ColumnFamilyOptions defaultCfOptions = new ColumnFamilyOptions()
DBOptions opt = null; .setMergeOperator(new StringAppendOperator())) {
List<ColumnFamilyDescriptor> cfNames = final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
new ArrayList<>(); new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
List<ColumnFamilyHandle> columnFamilyHandleList = defaultCfOptions),
new ArrayList<>(); new ColumnFamilyDescriptor("new_cf".getBytes()));
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
try (final DBOptions options = new DBOptions()
.setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList);
final WriteBatch writeBatch = new WriteBatch();
final WriteOptions writeOpt = new WriteOptions()) {
try { try {
opt = new DBOptions();
opt.setCreateIfMissing(true);
opt.setCreateMissingColumnFamilies(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions().setMergeOperator(new StringAppendOperator())));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
WriteBatch writeBatch = new WriteBatch();
WriteOptions writeOpt = new WriteOptions();
writeBatch.put("key".getBytes(), "value".getBytes()); writeBatch.put("key".getBytes(), "value".getBytes());
writeBatch.put(db.getDefaultColumnFamily(), writeBatch.put(db.getDefaultColumnFamily(),
"mergeKey".getBytes(), "merge".getBytes()); "mergeKey".getBytes(), "merge".getBytes());
@ -284,7 +231,7 @@ public class ColumnFamilyTest {
writeBatch.remove("xyz".getBytes()); writeBatch.remove("xyz".getBytes());
writeBatch.remove(columnFamilyHandleList.get(1), "xyz".getBytes()); writeBatch.remove(columnFamilyHandleList.get(1), "xyz".getBytes());
db.write(writeOpt, writeBatch); db.write(writeOpt, writeBatch);
writeBatch.dispose();
assertThat(db.get(columnFamilyHandleList.get(1), assertThat(db.get(columnFamilyHandleList.get(1),
"xyz".getBytes()) == null); "xyz".getBytes()) == null);
assertThat(new String(db.get(columnFamilyHandleList.get(1), assertThat(new String(db.get(columnFamilyHandleList.get(1),
@ -296,43 +243,35 @@ public class ColumnFamilyTest {
assertThat(new String(db.get(db.getDefaultColumnFamily(), assertThat(new String(db.get(db.getDefaultColumnFamily(),
"mergeKey".getBytes()))).isEqualTo("merge,merge"); "mergeKey".getBytes()))).isEqualTo("merge,merge");
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@Test @Test
public void iteratorOnColumnFamily() throws RocksDBException { public void iteratorOnColumnFamily() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
RocksIterator rocksIterator = null; new ColumnFamilyDescriptor("new_cf".getBytes()));
List<ColumnFamilyDescriptor> cfNames = final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
new ArrayList<>(); try (final DBOptions options = new DBOptions()
List<ColumnFamilyHandle> columnFamilyHandleList = .setCreateIfMissing(true)
new ArrayList<>(); .setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList)) {
try { try {
options = new DBOptions();
options.setCreateIfMissing(true);
options.setCreateMissingColumnFamilies(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(), db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
"value".getBytes()); "value".getBytes());
db.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(), db.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(),
"value2".getBytes()); "value2".getBytes());
rocksIterator = db.newIterator( try (final RocksIterator rocksIterator =
columnFamilyHandleList.get(1)); db.newIterator(columnFamilyHandleList.get(1))) {
rocksIterator.seekToFirst(); rocksIterator.seekToFirst();
Map<String, String> refMap = new HashMap<>(); Map<String, String> refMap = new HashMap<>();
refMap.put("newcfkey", "value"); refMap.put("newcfkey", "value");
@ -345,90 +284,73 @@ public class ColumnFamilyTest {
rocksIterator.next(); rocksIterator.next();
} }
assertThat(i).isEqualTo(2); assertThat(i).isEqualTo(2);
rocksIterator.dispose();
} finally {
if (rocksIterator != null) {
rocksIterator.dispose();
} }
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { } finally {
columnFamilyHandle.dispose(); for (final ColumnFamilyHandle columnFamilyHandle :
} columnFamilyHandleList) {
if (db != null) { columnFamilyHandle.close();
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void multiGet() throws RocksDBException { public void multiGet() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfDescriptors = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList)) {
try { try {
options = new DBOptions(); db.put(columnFamilyHandleList.get(0), "key".getBytes(),
options.setCreateIfMissing(true); "value".getBytes());
options.setCreateMissingColumnFamilies(true); db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
"value".getBytes());
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfDescriptors.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList);
db.put(columnFamilyHandleList.get(0), "key".getBytes(), "value".getBytes());
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(), "value".getBytes());
List<byte[]> keys = new ArrayList<>(); final List<byte[]> keys = Arrays.asList(new byte[][]{
keys.add("key".getBytes()); "key".getBytes(), "newcfkey".getBytes()
keys.add("newcfkey".getBytes()); });
Map<byte[], byte[]> retValues = db.multiGet(columnFamilyHandleList, keys); Map<byte[], byte[]> retValues = db.multiGet(columnFamilyHandleList,
keys);
assertThat(retValues.size()).isEqualTo(2); assertThat(retValues.size()).isEqualTo(2);
assertThat(new String(retValues.get(keys.get(0)))) assertThat(new String(retValues.get(keys.get(0))))
.isEqualTo("value"); .isEqualTo("value");
assertThat(new String(retValues.get(keys.get(1)))) assertThat(new String(retValues.get(keys.get(1))))
.isEqualTo("value"); .isEqualTo("value");
retValues = db.multiGet(new ReadOptions(), columnFamilyHandleList, keys); retValues = db.multiGet(new ReadOptions(), columnFamilyHandleList,
keys);
assertThat(retValues.size()).isEqualTo(2); assertThat(retValues.size()).isEqualTo(2);
assertThat(new String(retValues.get(keys.get(0)))) assertThat(new String(retValues.get(keys.get(0))))
.isEqualTo("value"); .isEqualTo("value");
assertThat(new String(retValues.get(keys.get(1)))) assertThat(new String(retValues.get(keys.get(1))))
.isEqualTo("value"); .isEqualTo("value");
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void properties() throws RocksDBException { public void properties() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList)) {
try { try {
options = new DBOptions();
options.setCreateIfMissing(true);
options.setCreateMissingColumnFamilies(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
assertThat(db.getProperty("rocksdb.estimate-num-keys")). assertThat(db.getProperty("rocksdb.estimate-num-keys")).
isNotNull(); isNotNull();
assertThat(db.getLongProperty(columnFamilyHandleList.get(0), assertThat(db.getLongProperty(columnFamilyHandleList.get(0),
@ -443,14 +365,10 @@ public class ColumnFamilyTest {
assertThat(db.getProperty(columnFamilyHandleList.get(1), assertThat(db.getProperty(columnFamilyHandleList.get(1),
"rocksdb.sstables")).isNotNull(); "rocksdb.sstables")).isNotNull();
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@ -458,28 +376,23 @@ public class ColumnFamilyTest {
@Test @Test
public void iterators() throws RocksDBException { public void iterators() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)) {
List<RocksIterator> iterators = null; List<RocksIterator> iterators = null;
try { try {
options = new DBOptions();
options.setCreateIfMissing(true);
options.setCreateMissingColumnFamilies(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
iterators = db.newIterators(columnFamilyHandleList); iterators = db.newIterators(columnFamilyHandleList);
assertThat(iterators.size()).isEqualTo(2); assertThat(iterators.size()).isEqualTo(2);
RocksIterator iter = iterators.get(0); RocksIterator iter = iterators.get(0);
iter.seekToFirst(); iter.seekToFirst();
Map<String, String> defRefMap = new HashMap<>(); final Map<String, String> defRefMap = new HashMap<>();
defRefMap.put("dfkey1", "dfvalue"); defRefMap.put("dfkey1", "dfvalue");
defRefMap.put("key", "value"); defRefMap.put("key", "value");
while (iter.isValid()) { while (iter.isValid()) {
@ -488,7 +401,7 @@ public class ColumnFamilyTest {
iter.next(); iter.next();
} }
// iterate over new_cf key/value pairs // iterate over new_cf key/value pairs
Map<String, String> cfRefMap = new HashMap<>(); final Map<String, String> cfRefMap = new HashMap<>();
cfRefMap.put("newcfkey", "value"); cfRefMap.put("newcfkey", "value");
cfRefMap.put("newcfkey2", "value2"); cfRefMap.put("newcfkey2", "value2");
iter = iterators.get(1); iter = iterators.get(1);
@ -500,247 +413,193 @@ public class ColumnFamilyTest {
} }
} finally { } finally {
if (iterators != null) { if (iterators != null) {
for (RocksIterator rocksIterator : iterators) { for (final RocksIterator rocksIterator : iterators) {
rocksIterator.dispose(); rocksIterator.close();
}
} }
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
columnFamilyHandle.dispose();
} }
if (db != null) { for (final ColumnFamilyHandle columnFamilyHandle :
db.close(); columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failPutDisposedCF() throws RocksDBException { public void failPutDisposedCF() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList)) {
try { try {
options = new DBOptions();
options.setCreateIfMissing(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
db.dropColumnFamily(columnFamilyHandleList.get(1)); db.dropColumnFamily(columnFamilyHandleList.get(1));
db.put(columnFamilyHandleList.get(1), "key".getBytes(), "value".getBytes()); db.put(columnFamilyHandleList.get(1), "key".getBytes(),
"value".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
columnFamilyHandle.dispose(); columnFamilyHandle.close();
}
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failRemoveDisposedCF() throws RocksDBException { public void failRemoveDisposedCF() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList)) {
try { try {
options = new DBOptions();
options.setCreateIfMissing(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
db.dropColumnFamily(columnFamilyHandleList.get(1)); db.dropColumnFamily(columnFamilyHandleList.get(1));
db.remove(columnFamilyHandleList.get(1), "key".getBytes()); db.remove(columnFamilyHandleList.get(1), "key".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failGetDisposedCF() throws RocksDBException { public void failGetDisposedCF() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)) {
try { try {
options = new DBOptions();
options.setCreateIfMissing(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
db.dropColumnFamily(columnFamilyHandleList.get(1)); db.dropColumnFamily(columnFamilyHandleList.get(1));
db.get(columnFamilyHandleList.get(1), "key".getBytes()); db.get(columnFamilyHandleList.get(1), "key".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failMultiGetWithoutCorrectNumberOfCF() throws RocksDBException { public void failMultiGetWithoutCorrectNumberOfCF() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor("new_cf".getBytes()));
new ArrayList<>(); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<ColumnFamilyHandle> columnFamilyHandleList = try (final DBOptions options = new DBOptions()
new ArrayList<>(); .setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)) {
try { try {
options = new DBOptions(); final List<byte[]> keys = new ArrayList<>();
options.setCreateIfMissing(true);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes()));
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList);
List<byte[]> keys = new ArrayList<>();
keys.add("key".getBytes()); keys.add("key".getBytes());
keys.add("newcfkey".getBytes()); keys.add("newcfkey".getBytes());
List<ColumnFamilyHandle> cfCustomList = new ArrayList<>(); final List<ColumnFamilyHandle> cfCustomList = new ArrayList<>();
db.multiGet(cfCustomList, keys); db.multiGet(cfCustomList, keys);
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void testByteCreateFolumnFamily() throws RocksDBException { public void testByteCreateFolumnFamily() throws RocksDBException {
RocksDB db = null;
Options options = null; try (final Options options = new Options().setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath())
) {
final byte[] b0 = new byte[]{(byte) 0x00};
final byte[] b1 = new byte[]{(byte) 0x01};
final byte[] b2 = new byte[]{(byte) 0x02};
ColumnFamilyHandle cf1 = null, cf2 = null, cf3 = null; ColumnFamilyHandle cf1 = null, cf2 = null, cf3 = null;
try { try {
options = new Options().setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
byte[] b0 = new byte[] { (byte)0x00 };
byte[] b1 = new byte[] { (byte)0x01 };
byte[] b2 = new byte[] { (byte)0x02 };
cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0)); cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0));
cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1)); cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1));
List<byte[]> families = RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath()); final List<byte[]> families = RocksDB.listColumnFamilies(options,
dbFolder.getRoot().getAbsolutePath());
assertThat(families).contains("default".getBytes(), b0, b1); assertThat(families).contains("default".getBytes(), b0, b1);
cf3 = db.createColumnFamily(new ColumnFamilyDescriptor(b2)); cf3 = db.createColumnFamily(new ColumnFamilyDescriptor(b2));
} finally { } finally {
if (cf1 != null) { if (cf1 != null) {
cf1.dispose(); cf1.close();
} }
if (cf2 != null) { if (cf2 != null) {
cf2.dispose(); cf2.close();
} }
if (cf3 != null) { if (cf3 != null) {
cf3.dispose(); cf3.close();
} }
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void testCFNamesWithZeroBytes() throws RocksDBException { public void testCFNamesWithZeroBytes() throws RocksDBException {
RocksDB db = null;
Options options = null;
ColumnFamilyHandle cf1 = null, cf2 = null; ColumnFamilyHandle cf1 = null, cf2 = null;
try (final Options options = new Options().setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath());
) {
try { try {
options = new Options().setCreateIfMissing(true); final byte[] b0 = new byte[]{0, 0};
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); final byte[] b1 = new byte[]{0, 1};
byte[] b0 = new byte[] { 0, 0 };
byte[] b1 = new byte[] { 0, 1 };
cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0)); cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0));
cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1)); cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1));
List<byte[]> families = RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath()); final List<byte[]> families = RocksDB.listColumnFamilies(options,
dbFolder.getRoot().getAbsolutePath());
assertThat(families).contains("default".getBytes(), b0, b1); assertThat(families).contains("default".getBytes(), b0, b1);
} finally { } finally {
if (cf1 != null) { if (cf1 != null) {
cf1.dispose(); cf1.close();
} }
if (cf2 != null) { if (cf2 != null) {
cf2.dispose(); cf2.close();
}
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void testCFNameSimplifiedChinese() throws RocksDBException { public void testCFNameSimplifiedChinese() throws RocksDBException {
RocksDB db = null;
Options options = null;
ColumnFamilyHandle columnFamilyHandle = null; ColumnFamilyHandle columnFamilyHandle = null;
try (final Options options = new Options().setCreateIfMissing(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath());
) {
try { try {
options = new Options().setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
final String simplifiedChinese = "\u7b80\u4f53\u5b57"; final String simplifiedChinese = "\u7b80\u4f53\u5b57";
columnFamilyHandle = db.createColumnFamily( columnFamilyHandle = db.createColumnFamily(
new ColumnFamilyDescriptor(simplifiedChinese.getBytes())); new ColumnFamilyDescriptor(simplifiedChinese.getBytes()));
List<byte[]> families = RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath()); final List<byte[]> families = RocksDB.listColumnFamilies(options,
assertThat(families).contains("default".getBytes(), simplifiedChinese.getBytes()); dbFolder.getRoot().getAbsolutePath());
assertThat(families).contains("default".getBytes(),
simplifiedChinese.getBytes());
} finally { } finally {
if (columnFamilyHandle != null) { if (columnFamilyHandle != null) {
columnFamilyHandle.dispose(); columnFamilyHandle.close();
} }
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
}
} }

@ -18,18 +18,15 @@ public class ComparatorOptionsTest {
@Test @Test
public void comparatorOptions() { public void comparatorOptions() {
final ComparatorOptions copt = new ComparatorOptions(); try(final ComparatorOptions copt = new ComparatorOptions()) {
assertThat(copt).isNotNull(); assertThat(copt).isNotNull();
// UseAdaptiveMutex test
{ // UseAdaptiveMutex test
copt.setUseAdaptiveMutex(true); copt.setUseAdaptiveMutex(true);
assertThat(copt.useAdaptiveMutex()).isTrue(); assertThat(copt.useAdaptiveMutex()).isTrue();
copt.setUseAdaptiveMutex(false); copt.setUseAdaptiveMutex(false);
assertThat(copt.useAdaptiveMutex()).isFalse(); assertThat(copt.useAdaptiveMutex()).isFalse();
} }
copt.dispose();
} }
} }

@ -79,21 +79,17 @@ public class ComparatorTest {
@Test @Test
public void builtinForwardComparator() public void builtinForwardComparator()
throws RocksDBException { throws RocksDBException {
Options options = null; try (final Options options = new Options()
RocksDB rocksDB = null; .setCreateIfMissing(true)
RocksIterator rocksIterator = null; .setComparator(BuiltinComparator.BYTEWISE_COMPARATOR);
try { final RocksDB rocksDb = RocksDB.open(options,
options = new Options(); dbFolder.getRoot().getAbsolutePath())
options.setCreateIfMissing(true); ) {
options.setComparator(BuiltinComparator.BYTEWISE_COMPARATOR); rocksDb.put("abc1".getBytes(), "abc1".getBytes());
rocksDB = RocksDB.open(options, rocksDb.put("abc2".getBytes(), "abc2".getBytes());
dbFolder.getRoot().getAbsolutePath()); rocksDb.put("abc3".getBytes(), "abc3".getBytes());
rocksDB.put("abc1".getBytes(), "abc1".getBytes()); try(final RocksIterator rocksIterator = rocksDb.newIterator()) {
rocksDB.put("abc2".getBytes(), "abc2".getBytes());
rocksDB.put("abc3".getBytes(), "abc3".getBytes());
rocksIterator = rocksDB.newIterator();
// Iterate over keys using a iterator // Iterate over keys using a iterator
rocksIterator.seekToFirst(); rocksIterator.seekToFirst();
assertThat(rocksIterator.isValid()).isTrue(); assertThat(rocksIterator.isValid()).isTrue();
@ -129,16 +125,6 @@ public class ComparatorTest {
"abc1".getBytes()); "abc1".getBytes());
assertThat(rocksIterator.value()).isEqualTo( assertThat(rocksIterator.value()).isEqualTo(
"abc1".getBytes()); "abc1".getBytes());
} finally {
if (rocksIterator != null) {
rocksIterator.dispose();
}
if (rocksDB != null) {
rocksDB.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@ -146,22 +132,18 @@ public class ComparatorTest {
@Test @Test
public void builtinReverseComparator() public void builtinReverseComparator()
throws RocksDBException { throws RocksDBException {
Options options = null; try (final Options options = new Options()
RocksDB rocksDB = null; .setCreateIfMissing(true)
RocksIterator rocksIterator = null; .setComparator(BuiltinComparator.REVERSE_BYTEWISE_COMPARATOR);
try { final RocksDB rocksDb = RocksDB.open(options,
options = new Options(); dbFolder.getRoot().getAbsolutePath())
options.setCreateIfMissing(true); ) {
options.setComparator(
BuiltinComparator.REVERSE_BYTEWISE_COMPARATOR); rocksDb.put("abc1".getBytes(), "abc1".getBytes());
rocksDB = RocksDB.open(options, rocksDb.put("abc2".getBytes(), "abc2".getBytes());
dbFolder.getRoot().getAbsolutePath()); rocksDb.put("abc3".getBytes(), "abc3".getBytes());
rocksDB.put("abc1".getBytes(), "abc1".getBytes()); try (final RocksIterator rocksIterator = rocksDb.newIterator()) {
rocksDB.put("abc2".getBytes(), "abc2".getBytes());
rocksDB.put("abc3".getBytes(), "abc3".getBytes());
rocksIterator = rocksDB.newIterator();
// Iterate over keys using a iterator // Iterate over keys using a iterator
rocksIterator.seekToFirst(); rocksIterator.seekToFirst();
assertThat(rocksIterator.isValid()).isTrue(); assertThat(rocksIterator.isValid()).isTrue();
@ -200,15 +182,6 @@ public class ComparatorTest {
"abc3".getBytes()); "abc3".getBytes());
assertThat(rocksIterator.value()).isEqualTo( assertThat(rocksIterator.value()).isEqualTo(
"abc3".getBytes()); "abc3".getBytes());
} finally {
if (rocksIterator != null) {
rocksIterator.dispose();
}
if (rocksDB != null) {
rocksDB.close();
}
if (options != null) {
options.dispose();
} }
} }
} }

@ -8,11 +8,10 @@ package org.rocksdb;
import org.junit.Test; import org.junit.Test;
public class CompressionOptionsTest public class CompressionOptionsTest {
{
@Test @Test
public void getCompressionType() { public void getCompressionType() {
for (CompressionType compressionType : CompressionType.values()) { for (final CompressionType compressionType : CompressionType.values()) {
String libraryName = compressionType.getLibraryName(); String libraryName = compressionType.getLibraryName();
compressionType.equals(CompressionType.getCompressionType( compressionType.equals(CompressionType.getCompressionType(
libraryName)); libraryName));

@ -24,547 +24,339 @@ public class DBOptionsTest {
@Test @Test
public void getDBOptionsFromProps() { public void getDBOptionsFromProps() {
DBOptions opt = null;
try {
// setup sample properties // setup sample properties
Properties properties = new Properties(); final Properties properties = new Properties();
properties.put("allow_mmap_reads", "true"); properties.put("allow_mmap_reads", "true");
properties.put("bytes_per_sync", "13"); properties.put("bytes_per_sync", "13");
opt = DBOptions.getDBOptionsFromProps(properties); try(final DBOptions opt = DBOptions.getDBOptionsFromProps(properties)) {
assertThat(opt).isNotNull(); assertThat(opt).isNotNull();
assertThat(String.valueOf(opt.allowMmapReads())). assertThat(String.valueOf(opt.allowMmapReads())).
isEqualTo(properties.get("allow_mmap_reads")); isEqualTo(properties.get("allow_mmap_reads"));
assertThat(String.valueOf(opt.bytesPerSync())). assertThat(String.valueOf(opt.bytesPerSync())).
isEqualTo(properties.get("bytes_per_sync")); isEqualTo(properties.get("bytes_per_sync"));
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void failDBOptionsFromPropsWithIllegalValue() { public void failDBOptionsFromPropsWithIllegalValue() {
DBOptions opt = null;
try {
// setup sample properties // setup sample properties
Properties properties = new Properties(); final Properties properties = new Properties();
properties.put("tomato", "1024"); properties.put("tomato", "1024");
properties.put("burger", "2"); properties.put("burger", "2");
opt = DBOptions. try(final DBOptions opt = DBOptions.getDBOptionsFromProps(properties)) {
getDBOptionsFromProps(properties);
assertThat(opt).isNull(); assertThat(opt).isNull();
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void failDBOptionsFromPropsWithNullValue() { public void failDBOptionsFromPropsWithNullValue() {
DBOptions.getDBOptionsFromProps(null); try(final DBOptions opt = DBOptions.getDBOptionsFromProps(null)) {
//no-op
}
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void failDBOptionsFromPropsWithEmptyProps() { public void failDBOptionsFromPropsWithEmptyProps() {
DBOptions.getDBOptionsFromProps( try(final DBOptions opt = DBOptions.getDBOptionsFromProps(
new Properties()); new Properties())) {
//no-op
}
} }
@Test @Test
public void setIncreaseParallelism() { public void setIncreaseParallelism() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try {
opt = new DBOptions();
final int threads = Runtime.getRuntime().availableProcessors() * 2; final int threads = Runtime.getRuntime().availableProcessors() * 2;
opt.setIncreaseParallelism(threads); opt.setIncreaseParallelism(threads);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void createIfMissing() { public void createIfMissing() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setCreateIfMissing(boolValue); opt.setCreateIfMissing(boolValue);
assertThat(opt.createIfMissing()). assertThat(opt.createIfMissing()).isEqualTo(boolValue);
isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void createMissingColumnFamilies() { public void createMissingColumnFamilies() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setCreateMissingColumnFamilies(boolValue); opt.setCreateMissingColumnFamilies(boolValue);
assertThat(opt.createMissingColumnFamilies()). assertThat(opt.createMissingColumnFamilies()).isEqualTo(boolValue);
isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void errorIfExists() { public void errorIfExists() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setErrorIfExists(boolValue); opt.setErrorIfExists(boolValue);
assertThat(opt.errorIfExists()).isEqualTo(boolValue); assertThat(opt.errorIfExists()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void paranoidChecks() { public void paranoidChecks() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setParanoidChecks(boolValue); opt.setParanoidChecks(boolValue);
assertThat(opt.paranoidChecks()). assertThat(opt.paranoidChecks()).isEqualTo(boolValue);
isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxTotalWalSize() { public void maxTotalWalSize() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setMaxTotalWalSize(longValue); opt.setMaxTotalWalSize(longValue);
assertThat(opt.maxTotalWalSize()). assertThat(opt.maxTotalWalSize()).isEqualTo(longValue);
isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxOpenFiles() { public void maxOpenFiles() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final int intValue = rand.nextInt();
opt = new DBOptions();
int intValue = rand.nextInt();
opt.setMaxOpenFiles(intValue); opt.setMaxOpenFiles(intValue);
assertThat(opt.maxOpenFiles()).isEqualTo(intValue); assertThat(opt.maxOpenFiles()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void disableDataSync() { public void disableDataSync() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setDisableDataSync(boolValue); opt.setDisableDataSync(boolValue);
assertThat(opt.disableDataSync()). assertThat(opt.disableDataSync()).isEqualTo(boolValue);
isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void useFsync() { public void useFsync() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setUseFsync(boolValue); opt.setUseFsync(boolValue);
assertThat(opt.useFsync()).isEqualTo(boolValue); assertThat(opt.useFsync()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void dbLogDir() { public void dbLogDir() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final String str = "path/to/DbLogDir";
opt = new DBOptions();
String str = "path/to/DbLogDir";
opt.setDbLogDir(str); opt.setDbLogDir(str);
assertThat(opt.dbLogDir()).isEqualTo(str); assertThat(opt.dbLogDir()).isEqualTo(str);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void walDir() { public void walDir() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final String str = "path/to/WalDir";
opt = new DBOptions();
String str = "path/to/WalDir";
opt.setWalDir(str); opt.setWalDir(str);
assertThat(opt.walDir()).isEqualTo(str); assertThat(opt.walDir()).isEqualTo(str);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void deleteObsoleteFilesPeriodMicros() { public void deleteObsoleteFilesPeriodMicros() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setDeleteObsoleteFilesPeriodMicros(longValue); opt.setDeleteObsoleteFilesPeriodMicros(longValue);
assertThat(opt.deleteObsoleteFilesPeriodMicros()). assertThat(opt.deleteObsoleteFilesPeriodMicros()).isEqualTo(longValue);
isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxBackgroundCompactions() { public void maxBackgroundCompactions() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final int intValue = rand.nextInt();
opt = new DBOptions();
int intValue = rand.nextInt();
opt.setMaxBackgroundCompactions(intValue); opt.setMaxBackgroundCompactions(intValue);
assertThat(opt.maxBackgroundCompactions()). assertThat(opt.maxBackgroundCompactions()).isEqualTo(intValue);
isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxBackgroundFlushes() { public void maxBackgroundFlushes() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final int intValue = rand.nextInt();
opt = new DBOptions();
int intValue = rand.nextInt();
opt.setMaxBackgroundFlushes(intValue); opt.setMaxBackgroundFlushes(intValue);
assertThat(opt.maxBackgroundFlushes()). assertThat(opt.maxBackgroundFlushes()).isEqualTo(intValue);
isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxLogFileSize() throws RocksDBException { public void maxLogFileSize() throws RocksDBException {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setMaxLogFileSize(longValue); opt.setMaxLogFileSize(longValue);
assertThat(opt.maxLogFileSize()).isEqualTo(longValue); assertThat(opt.maxLogFileSize()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void logFileTimeToRoll() throws RocksDBException { public void logFileTimeToRoll() throws RocksDBException {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setLogFileTimeToRoll(longValue); opt.setLogFileTimeToRoll(longValue);
assertThat(opt.logFileTimeToRoll()). assertThat(opt.logFileTimeToRoll()).isEqualTo(longValue);
isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void keepLogFileNum() throws RocksDBException { public void keepLogFileNum() throws RocksDBException {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setKeepLogFileNum(longValue); opt.setKeepLogFileNum(longValue);
assertThat(opt.keepLogFileNum()).isEqualTo(longValue); assertThat(opt.keepLogFileNum()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void maxManifestFileSize() { public void maxManifestFileSize() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setMaxManifestFileSize(longValue); opt.setMaxManifestFileSize(longValue);
assertThat(opt.maxManifestFileSize()). assertThat(opt.maxManifestFileSize()).isEqualTo(longValue);
isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void tableCacheNumshardbits() { public void tableCacheNumshardbits() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final int intValue = rand.nextInt();
opt = new DBOptions();
int intValue = rand.nextInt();
opt.setTableCacheNumshardbits(intValue); opt.setTableCacheNumshardbits(intValue);
assertThat(opt.tableCacheNumshardbits()). assertThat(opt.tableCacheNumshardbits()).isEqualTo(intValue);
isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void walSizeLimitMB() { public void walSizeLimitMB() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setWalSizeLimitMB(longValue); opt.setWalSizeLimitMB(longValue);
assertThat(opt.walSizeLimitMB()).isEqualTo(longValue); assertThat(opt.walSizeLimitMB()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void walTtlSeconds() { public void walTtlSeconds() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setWalTtlSeconds(longValue); opt.setWalTtlSeconds(longValue);
assertThat(opt.walTtlSeconds()).isEqualTo(longValue); assertThat(opt.walTtlSeconds()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void manifestPreallocationSize() throws RocksDBException { public void manifestPreallocationSize() throws RocksDBException {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setManifestPreallocationSize(longValue); opt.setManifestPreallocationSize(longValue);
assertThat(opt.manifestPreallocationSize()). assertThat(opt.manifestPreallocationSize()).isEqualTo(longValue);
isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void allowOsBuffer() { public void allowOsBuffer() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setAllowOsBuffer(boolValue); opt.setAllowOsBuffer(boolValue);
assertThat(opt.allowOsBuffer()).isEqualTo(boolValue); assertThat(opt.allowOsBuffer()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void allowMmapReads() { public void allowMmapReads() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setAllowMmapReads(boolValue); opt.setAllowMmapReads(boolValue);
assertThat(opt.allowMmapReads()).isEqualTo(boolValue); assertThat(opt.allowMmapReads()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void allowMmapWrites() { public void allowMmapWrites() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setAllowMmapWrites(boolValue); opt.setAllowMmapWrites(boolValue);
assertThat(opt.allowMmapWrites()).isEqualTo(boolValue); assertThat(opt.allowMmapWrites()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void isFdCloseOnExec() { public void isFdCloseOnExec() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setIsFdCloseOnExec(boolValue); opt.setIsFdCloseOnExec(boolValue);
assertThat(opt.isFdCloseOnExec()).isEqualTo(boolValue); assertThat(opt.isFdCloseOnExec()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void statsDumpPeriodSec() { public void statsDumpPeriodSec() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final int intValue = rand.nextInt();
opt = new DBOptions();
int intValue = rand.nextInt();
opt.setStatsDumpPeriodSec(intValue); opt.setStatsDumpPeriodSec(intValue);
assertThat(opt.statsDumpPeriodSec()).isEqualTo(intValue); assertThat(opt.statsDumpPeriodSec()).isEqualTo(intValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void adviseRandomOnOpen() { public void adviseRandomOnOpen() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setAdviseRandomOnOpen(boolValue); opt.setAdviseRandomOnOpen(boolValue);
assertThat(opt.adviseRandomOnOpen()).isEqualTo(boolValue); assertThat(opt.adviseRandomOnOpen()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void useAdaptiveMutex() { public void useAdaptiveMutex() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final boolean boolValue = rand.nextBoolean();
opt = new DBOptions();
boolean boolValue = rand.nextBoolean();
opt.setUseAdaptiveMutex(boolValue); opt.setUseAdaptiveMutex(boolValue);
assertThat(opt.useAdaptiveMutex()).isEqualTo(boolValue); assertThat(opt.useAdaptiveMutex()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void bytesPerSync() { public void bytesPerSync() {
DBOptions opt = null; try(final DBOptions opt = new DBOptions()) {
try { final long longValue = rand.nextLong();
opt = new DBOptions();
long longValue = rand.nextLong();
opt.setBytesPerSync(longValue); opt.setBytesPerSync(longValue);
assertThat(opt.bytesPerSync()).isEqualTo(longValue); assertThat(opt.bytesPerSync()).isEqualTo(longValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void rateLimiterConfig() { public void rateLimiterConfig() {
DBOptions options = null; try(final DBOptions options = new DBOptions();
DBOptions anotherOptions = null; final DBOptions anotherOptions = new DBOptions()) {
try { final RateLimiterConfig rateLimiterConfig =
options = new DBOptions();
RateLimiterConfig rateLimiterConfig =
new GenericRateLimiterConfig(1000, 100 * 1000, 1); new GenericRateLimiterConfig(1000, 100 * 1000, 1);
options.setRateLimiterConfig(rateLimiterConfig); options.setRateLimiterConfig(rateLimiterConfig);
// Test with parameter initialization // Test with parameter initialization
anotherOptions = new DBOptions();
anotherOptions.setRateLimiterConfig( anotherOptions.setRateLimiterConfig(
new GenericRateLimiterConfig(1000)); new GenericRateLimiterConfig(1000));
} finally {
if (options != null) {
options.dispose();
}
if (anotherOptions != null) {
anotherOptions.dispose();
}
} }
} }
@Test @Test
public void statistics() { public void statistics() {
DBOptions options = new DBOptions(); try(final DBOptions options = new DBOptions()) {
Statistics statistics = options.createStatistics(). Statistics statistics = options.createStatistics().
statisticsPtr(); statisticsPtr();
assertThat(statistics).isNotNull(); assertThat(statistics).isNotNull();
DBOptions anotherOptions = new DBOptions(); try(final DBOptions anotherOptions = new DBOptions()) {
statistics = anotherOptions.statisticsPtr(); statistics = anotherOptions.statisticsPtr();
assertThat(statistics).isNotNull(); assertThat(statistics).isNotNull();
} }
} }
}
}

@ -18,11 +18,8 @@ public class DirectSliceTest {
@Test @Test
public void directSlice() { public void directSlice() {
DirectSlice directSlice = null; try(final DirectSlice directSlice = new DirectSlice("abc");
DirectSlice otherSlice = null; final DirectSlice otherSlice = new DirectSlice("abc")) {
try {
directSlice = new DirectSlice("abc");
otherSlice = new DirectSlice("abc");
assertThat(directSlice.toString()).isEqualTo("abc"); assertThat(directSlice.toString()).isEqualTo("abc");
// clear first slice // clear first slice
directSlice.clear(); directSlice.clear();
@ -32,75 +29,46 @@ public class DirectSliceTest {
// remove prefix // remove prefix
otherSlice.removePrefix(1); otherSlice.removePrefix(1);
assertThat(otherSlice.toString()).isEqualTo("bc"); assertThat(otherSlice.toString()).isEqualTo("bc");
} finally {
if (directSlice != null) {
directSlice.dispose();
}
if (otherSlice != null) {
otherSlice.dispose();
}
} }
} }
@Test @Test
public void directSliceWithByteBuffer() { public void directSliceWithByteBuffer() {
DirectSlice directSlice = null; final byte[] data = "Some text".getBytes();
try { final ByteBuffer buffer = ByteBuffer.allocateDirect(data.length + 1);
byte[] data = "Some text".getBytes();
ByteBuffer buffer = ByteBuffer.allocateDirect(data.length + 1);
buffer.put(data); buffer.put(data);
buffer.put(data.length, (byte)0); buffer.put(data.length, (byte)0);
directSlice = new DirectSlice(buffer); try(final DirectSlice directSlice = new DirectSlice(buffer)) {
assertThat(directSlice.toString()).isEqualTo("Some text"); assertThat(directSlice.toString()).isEqualTo("Some text");
} finally {
if (directSlice != null) {
directSlice.dispose();
}
} }
} }
@Test @Test
public void directSliceWithByteBufferAndLength() { public void directSliceWithByteBufferAndLength() {
DirectSlice directSlice = null; final byte[] data = "Some text".getBytes();
try { final ByteBuffer buffer = ByteBuffer.allocateDirect(data.length);
byte[] data = "Some text".getBytes();
ByteBuffer buffer = ByteBuffer.allocateDirect(data.length);
buffer.put(data); buffer.put(data);
directSlice = new DirectSlice(buffer, 4); try(final DirectSlice directSlice = new DirectSlice(buffer, 4)) {
assertThat(directSlice.toString()).isEqualTo("Some"); assertThat(directSlice.toString()).isEqualTo("Some");
} finally {
if (directSlice != null) {
directSlice.dispose();
}
} }
} }
@Test(expected = AssertionError.class) @Test(expected = AssertionError.class)
public void directSliceInitWithoutDirectAllocation() { public void directSliceInitWithoutDirectAllocation() {
DirectSlice directSlice = null; final byte[] data = "Some text".getBytes();
try { final ByteBuffer buffer = ByteBuffer.wrap(data);
byte[] data = "Some text".getBytes(); try(final DirectSlice directSlice = new DirectSlice(buffer)) {
ByteBuffer buffer = ByteBuffer.wrap(data); //no-op
directSlice = new DirectSlice(buffer);
} finally {
if (directSlice != null) {
directSlice.dispose();
}
} }
} }
@Test(expected = AssertionError.class) @Test(expected = AssertionError.class)
public void directSlicePrefixInitWithoutDirectAllocation() { public void directSlicePrefixInitWithoutDirectAllocation() {
DirectSlice directSlice = null; final byte[] data = "Some text".getBytes();
try { final ByteBuffer buffer = ByteBuffer.wrap(data);
byte[] data = "Some text".getBytes(); try(final DirectSlice directSlice = new DirectSlice(buffer, 4)) {
ByteBuffer buffer = ByteBuffer.wrap(data); //no-op
directSlice = new DirectSlice(buffer, 4);
} finally {
if (directSlice != null) {
directSlice.dispose();
}
} }
} }
} }

@ -16,31 +16,23 @@ public class FilterTest {
@Test @Test
public void filter() { public void filter() {
Options options = null;
try {
options = new Options();
// test table config
options.setTableFormatConfig(new BlockBasedTableConfig().
setFilter(new BloomFilter()));
options.dispose();
System.gc();
System.runFinalization();
// new Bloom filter // new Bloom filter
options = new Options(); final BlockBasedTableConfig blockConfig = new BlockBasedTableConfig();
BlockBasedTableConfig blockConfig = new BlockBasedTableConfig(); try(final Options options = new Options()) {
blockConfig.setFilter(new BloomFilter());
options.setTableFormatConfig(blockConfig); try(final Filter bloomFilter = new BloomFilter()) {
BloomFilter bloomFilter = new BloomFilter(10);
blockConfig.setFilter(bloomFilter); blockConfig.setFilter(bloomFilter);
options.setTableFormatConfig(blockConfig); options.setTableFormatConfig(blockConfig);
System.gc(); }
System.runFinalization();
blockConfig.setFilter(new BloomFilter(10, false)); try(final Filter bloomFilter = new BloomFilter(10)) {
blockConfig.setFilter(bloomFilter);
options.setTableFormatConfig(blockConfig); options.setTableFormatConfig(blockConfig);
}
} finally { try(final Filter bloomFilter = new BloomFilter(10, false)) {
if (options != null) { blockConfig.setFilter(bloomFilter);
options.dispose(); options.setTableFormatConfig(blockConfig);
} }
} }
} }

@ -22,44 +22,28 @@ public class FlushTest {
@Test @Test
public void flush() throws RocksDBException { public void flush() throws RocksDBException {
RocksDB db = null; try(final Options options = new Options()
Options options = null; .setCreateIfMissing(true)
WriteOptions wOpt = null; .setMaxWriteBufferNumber(10)
FlushOptions flushOptions = null; .setMinWriteBufferNumberToMerge(10);
try { final WriteOptions wOpt = new WriteOptions()
options = new Options(); .setDisableWAL(true);
// Setup options final FlushOptions flushOptions = new FlushOptions()
options.setCreateIfMissing(true); .setWaitForFlush(true)) {
options.setMaxWriteBufferNumber(10);
options.setMinWriteBufferNumberToMerge(10);
wOpt = new WriteOptions();
flushOptions = new FlushOptions();
flushOptions.setWaitForFlush(true);
assertThat(flushOptions.waitForFlush()).isTrue(); assertThat(flushOptions.waitForFlush()).isTrue();
wOpt.setDisableWAL(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); try(final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath())) {
db.put(wOpt, "key1".getBytes(), "value1".getBytes()); db.put(wOpt, "key1".getBytes(), "value1".getBytes());
db.put(wOpt, "key2".getBytes(), "value2".getBytes()); db.put(wOpt, "key2".getBytes(), "value2".getBytes());
db.put(wOpt, "key3".getBytes(), "value3".getBytes()); db.put(wOpt, "key3".getBytes(), "value3".getBytes());
db.put(wOpt, "key4".getBytes(), "value4".getBytes()); db.put(wOpt, "key4".getBytes(), "value4".getBytes());
assertThat(db.getProperty("rocksdb.num-entries-active-mem-table")).isEqualTo("4"); assertThat(db.getProperty("rocksdb.num-entries-active-mem-table"))
.isEqualTo("4");
db.flush(flushOptions); db.flush(flushOptions);
assertThat(db.getProperty("rocksdb.num-entries-active-mem-table")). assertThat(db.getProperty("rocksdb.num-entries-active-mem-table"))
isEqualTo("0"); .isEqualTo("0");
} finally {
if (flushOptions != null) {
flushOptions.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
if (wOpt != null) {
wOpt.dispose();
}
} }
} }
} }

@ -24,75 +24,46 @@ public class InfoLogLevelTest {
@Test @Test
public void testInfoLogLevel() throws RocksDBException, public void testInfoLogLevel() throws RocksDBException,
IOException { IOException {
RocksDB db = null; try (final RocksDB db =
try { RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
assertThat(getLogContentsWithoutHeader()).isNotEmpty(); assertThat(getLogContentsWithoutHeader()).isNotEmpty();
} finally {
if (db != null) {
db.close();
}
} }
} }
@Test @Test
public void testFatalLogLevel() throws RocksDBException, public void testFatalLogLevel() throws RocksDBException,
IOException { IOException {
RocksDB db = null; try (final Options options = new Options().
Options options = null;
try {
options = new Options().
setCreateIfMissing(true). setCreateIfMissing(true).
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL); setInfoLogLevel(InfoLogLevel.FATAL_LEVEL);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath())) {
assertThat(options.infoLogLevel()). assertThat(options.infoLogLevel()).
isEqualTo(InfoLogLevel.FATAL_LEVEL); isEqualTo(InfoLogLevel.FATAL_LEVEL);
db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
// As InfoLogLevel is set to FATAL_LEVEL, here we expect the log // As InfoLogLevel is set to FATAL_LEVEL, here we expect the log
// content to be empty. // content to be empty.
assertThat(getLogContentsWithoutHeader()).isEmpty(); assertThat(getLogContentsWithoutHeader()).isEmpty();
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void testFatalLogLevelWithDBOptions() public void testFatalLogLevelWithDBOptions()
throws RocksDBException, IOException { throws RocksDBException, IOException {
RocksDB db = null; try (final DBOptions dbOptions = new DBOptions().
Options options = null;
DBOptions dbOptions = null;
try {
dbOptions = new DBOptions().
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL); setInfoLogLevel(InfoLogLevel.FATAL_LEVEL);
options = new Options(dbOptions, final Options options = new Options(dbOptions,
new ColumnFamilyOptions()). new ColumnFamilyOptions()).
setCreateIfMissing(true); setCreateIfMissing(true);
final RocksDB db =
RocksDB.open(options, dbFolder.getRoot().getAbsolutePath())) {
assertThat(dbOptions.infoLogLevel()). assertThat(dbOptions.infoLogLevel()).
isEqualTo(InfoLogLevel.FATAL_LEVEL); isEqualTo(InfoLogLevel.FATAL_LEVEL);
assertThat(options.infoLogLevel()). assertThat(options.infoLogLevel()).
isEqualTo(InfoLogLevel.FATAL_LEVEL); isEqualTo(InfoLogLevel.FATAL_LEVEL);
db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
assertThat(getLogContentsWithoutHeader()).isEmpty(); assertThat(getLogContentsWithoutHeader()).isEmpty();
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
if (dbOptions != null) {
dbOptions.dispose();
}
} }
} }
@ -114,7 +85,8 @@ public class InfoLogLevelTest {
* @throws IOException if file is not found. * @throws IOException if file is not found.
*/ */
private String getLogContentsWithoutHeader() throws IOException { private String getLogContentsWithoutHeader() throws IOException {
final String separator = Environment.isWindows() ? "\n" : System.getProperty("line.separator"); final String separator = Environment.isWindows() ?
"\n" : System.getProperty("line.separator");
final String[] lines = new String(readAllBytes(get( final String[] lines = new String(readAllBytes(get(
dbFolder.getRoot().getAbsolutePath() + "/LOG"))).split(separator); dbFolder.getRoot().getAbsolutePath() + "/LOG"))).split(separator);

@ -10,6 +10,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -25,23 +26,19 @@ public class KeyMayExistTest {
@Test @Test
public void keyMayExist() throws RocksDBException { public void keyMayExist() throws RocksDBException {
RocksDB db = null; final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
DBOptions options = null; new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
List<ColumnFamilyDescriptor> cfDescriptors = new ColumnFamilyDescriptor("new_cf".getBytes())
new ArrayList<>(); );
List<ColumnFamilyHandle> columnFamilyHandleList =
new ArrayList<>();
try {
options = new DBOptions();
options.setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
// open database using cf names
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
cfDescriptors.add(new ColumnFamilyDescriptor("new_cf".getBytes())); try (final DBOptions options = new DBOptions()
db = RocksDB.open(options, .setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList); cfDescriptors, columnFamilyHandleList)) {
try {
assertThat(columnFamilyHandleList.size()). assertThat(columnFamilyHandleList.size()).
isEqualTo(2); isEqualTo(2);
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
@ -49,46 +46,41 @@ public class KeyMayExistTest {
StringBuffer retValue = new StringBuffer(); StringBuffer retValue = new StringBuffer();
boolean exists = db.keyMayExist("key".getBytes(), retValue); boolean exists = db.keyMayExist("key".getBytes(), retValue);
assertThat(exists).isTrue(); assertThat(exists).isTrue();
assertThat(retValue.toString()). assertThat(retValue.toString()).isEqualTo("value");
isEqualTo("value");
// Test without column family but with readOptions // Test without column family but with readOptions
try (final ReadOptions readOptions = new ReadOptions()) {
retValue = new StringBuffer(); retValue = new StringBuffer();
exists = db.keyMayExist(new ReadOptions(), "key".getBytes(), exists = db.keyMayExist(readOptions, "key".getBytes(), retValue);
retValue);
assertThat(exists).isTrue(); assertThat(exists).isTrue();
assertThat(retValue.toString()). assertThat(retValue.toString()).isEqualTo("value");
isEqualTo("value"); }
// Test with column family // Test with column family
retValue = new StringBuffer(); retValue = new StringBuffer();
exists = db.keyMayExist(columnFamilyHandleList.get(0), "key".getBytes(), exists = db.keyMayExist(columnFamilyHandleList.get(0), "key".getBytes(),
retValue); retValue);
assertThat(exists).isTrue(); assertThat(exists).isTrue();
assertThat(retValue.toString()). assertThat(retValue.toString()).isEqualTo("value");
isEqualTo("value");
// Test with column family and readOptions // Test with column family and readOptions
try (final ReadOptions readOptions = new ReadOptions()) {
retValue = new StringBuffer(); retValue = new StringBuffer();
exists = db.keyMayExist(new ReadOptions(), exists = db.keyMayExist(readOptions,
columnFamilyHandleList.get(0), "key".getBytes(), columnFamilyHandleList.get(0), "key".getBytes(),
retValue); retValue);
assertThat(exists).isTrue(); assertThat(exists).isTrue();
assertThat(retValue.toString()). assertThat(retValue.toString()).isEqualTo("value");
isEqualTo("value"); }
// KeyMayExist in CF1 must return false // KeyMayExist in CF1 must return false
assertThat(db.keyMayExist(columnFamilyHandleList.get(1), assertThat(db.keyMayExist(columnFamilyHandleList.get(1),
"key".getBytes(), retValue)).isFalse(); "key".getBytes(), retValue)).isFalse();
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); columnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }

@ -6,6 +6,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -19,183 +20,151 @@ public class LoggerTest {
@Rule @Rule
public TemporaryFolder dbFolder = new TemporaryFolder(); public TemporaryFolder dbFolder = new TemporaryFolder();
private AtomicInteger logMessageCounter = new AtomicInteger();
@Test @Test
public void customLogger() throws RocksDBException { public void customLogger() throws RocksDBException {
RocksDB db = null; final AtomicInteger logMessageCounter = new AtomicInteger();
logMessageCounter.set(0); try (final Options options = new Options().
try {
// Setup options
final Options options = new Options().
setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL). setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL).
setCreateIfMissing(true); setCreateIfMissing(true);
final Logger logger = new Logger(options) {
// Create new logger with max log level passed by options // Create new logger with max log level passed by options
Logger logger = new Logger(options) {
@Override @Override
protected void log(InfoLogLevel infoLogLevel, String logMsg) { protected void log(InfoLogLevel infoLogLevel, String logMsg) {
assertThat(logMsg).isNotNull(); assertThat(logMsg).isNotNull();
assertThat(logMsg.length()).isGreaterThan(0); assertThat(logMsg.length()).isGreaterThan(0);
logMessageCounter.incrementAndGet(); logMessageCounter.incrementAndGet();
} }
}; }
) {
// Set custom logger to options // Set custom logger to options
options.setLogger(logger); options.setLogger(logger);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); try (final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath())) {
// there should be more than zero received log messages in // there should be more than zero received log messages in
// debug level. // debug level.
assertThat(logMessageCounter.get()).isGreaterThan(0); assertThat(logMessageCounter.get()).isGreaterThan(0);
} finally {
if (db != null) {
db.close();
} }
} }
logMessageCounter.set(0);
} }
@Test @Test
public void fatalLogger() throws RocksDBException { public void fatalLogger() throws RocksDBException {
RocksDB db = null; final AtomicInteger logMessageCounter = new AtomicInteger();
logMessageCounter.set(0); try (final Options options = new Options().
try {
// Setup options
final Options options = new Options().
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). setInfoLogLevel(InfoLogLevel.FATAL_LEVEL).
setCreateIfMissing(true); setCreateIfMissing(true);
final Logger logger = new Logger(options) {
// Create new logger with max log level passed by options // Create new logger with max log level passed by options
Logger logger = new Logger(options) {
@Override @Override
protected void log(InfoLogLevel infoLogLevel, String logMsg) { protected void log(InfoLogLevel infoLogLevel, String logMsg) {
assertThat(logMsg).isNotNull(); assertThat(logMsg).isNotNull();
assertThat(logMsg.length()).isGreaterThan(0); assertThat(logMsg.length()).isGreaterThan(0);
logMessageCounter.incrementAndGet(); logMessageCounter.incrementAndGet();
} }
}; }
) {
// Set custom logger to options // Set custom logger to options
options.setLogger(logger); options.setLogger(logger);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); try (final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath())) {
// there should be zero messages // there should be zero messages
// using fatal level as log level. // using fatal level as log level.
assertThat(logMessageCounter.get()).isEqualTo(0); assertThat(logMessageCounter.get()).isEqualTo(0);
} finally {
if (db != null) {
db.close();
} }
} }
logMessageCounter.set(0);
} }
@Test @Test
public void dbOptionsLogger() throws RocksDBException { public void dbOptionsLogger() throws RocksDBException {
RocksDB db = null; final AtomicInteger logMessageCounter = new AtomicInteger();
Logger logger = null; try (final DBOptions options = new DBOptions().
List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>();
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
logMessageCounter.set(0);
try {
// Setup options
final DBOptions options = new DBOptions().
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). setInfoLogLevel(InfoLogLevel.FATAL_LEVEL).
setCreateIfMissing(true); setCreateIfMissing(true);
final Logger logger = new Logger(options) {
// Create new logger with max log level passed by options // Create new logger with max log level passed by options
logger = new Logger(options) {
@Override @Override
protected void log(InfoLogLevel infoLogLevel, String logMsg) { protected void log(InfoLogLevel infoLogLevel, String logMsg) {
assertThat(logMsg).isNotNull(); assertThat(logMsg).isNotNull();
assertThat(logMsg.length()).isGreaterThan(0); assertThat(logMsg.length()).isGreaterThan(0);
logMessageCounter.incrementAndGet(); logMessageCounter.incrementAndGet();
} }
}; }
) {
// Set custom logger to options // Set custom logger to options
options.setLogger(logger); options.setLogger(logger);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, cfHandles); final List<ColumnFamilyDescriptor> cfDescriptors =
Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
try (final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, cfHandles)) {
try {
// there should be zero messages // there should be zero messages
// using fatal level as log level. // using fatal level as log level.
assertThat(logMessageCounter.get()).isEqualTo(0); assertThat(logMessageCounter.get()).isEqualTo(0);
logMessageCounter.set(0);
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : cfHandles) { for (final ColumnFamilyHandle columnFamilyHandle : cfHandles) {
columnFamilyHandle.dispose(); columnFamilyHandle.close();
} }
if (db != null) {
db.close();
} }
if (logger != null) {
logger.dispose();
} }
} }
} }
@Test @Test
public void setInfoLogLevel() { public void setInfoLogLevel() {
Logger logger = null; final AtomicInteger logMessageCounter = new AtomicInteger();
try { try (final Options options = new Options().
// Setup options
final Options options = new Options().
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). setInfoLogLevel(InfoLogLevel.FATAL_LEVEL).
setCreateIfMissing(true); setCreateIfMissing(true);
final Logger logger = new Logger(options) {
// Create new logger with max log level passed by options // Create new logger with max log level passed by options
logger = new Logger(options) {
@Override @Override
protected void log(InfoLogLevel infoLogLevel, String logMsg) { protected void log(InfoLogLevel infoLogLevel, String logMsg) {
assertThat(logMsg).isNotNull(); assertThat(logMsg).isNotNull();
assertThat(logMsg.length()).isGreaterThan(0); assertThat(logMsg.length()).isGreaterThan(0);
logMessageCounter.incrementAndGet(); logMessageCounter.incrementAndGet();
} }
}; }
) {
assertThat(logger.infoLogLevel()). assertThat(logger.infoLogLevel()).
isEqualTo(InfoLogLevel.FATAL_LEVEL); isEqualTo(InfoLogLevel.FATAL_LEVEL);
logger.setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL); logger.setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL);
assertThat(logger.infoLogLevel()). assertThat(logger.infoLogLevel()).
isEqualTo(InfoLogLevel.DEBUG_LEVEL); isEqualTo(InfoLogLevel.DEBUG_LEVEL);
} finally {
if (logger != null) {
logger.dispose();
}
} }
} }
@Test @Test
public void changeLogLevelAtRuntime() throws RocksDBException { public void changeLogLevelAtRuntime() throws RocksDBException {
RocksDB db = null; final AtomicInteger logMessageCounter = new AtomicInteger();
logMessageCounter.set(0); try (final Options options = new Options().
try {
// Setup options
final Options options = new Options().
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). setInfoLogLevel(InfoLogLevel.FATAL_LEVEL).
setCreateIfMissing(true); setCreateIfMissing(true);
// Create new logger with max log level passed by options // Create new logger with max log level passed by options
Logger logger = new Logger(options) { final Logger logger = new Logger(options) {
@Override @Override
protected void log(InfoLogLevel infoLogLevel, String logMsg) { protected void log(InfoLogLevel infoLogLevel, String logMsg) {
assertThat(logMsg).isNotNull(); assertThat(logMsg).isNotNull();
assertThat(logMsg.length()).isGreaterThan(0); assertThat(logMsg.length()).isGreaterThan(0);
logMessageCounter.incrementAndGet(); logMessageCounter.incrementAndGet();
} }
}; }
) {
// Set custom logger to options // Set custom logger to options
options.setLogger(logger); options.setLogger(logger);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
try (final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath())) {
// there should be zero messages // there should be zero messages
// using fatal level as log level. // using fatal level as log level.
@ -209,12 +178,7 @@ public class LoggerTest {
// messages shall be received due to previous actions. // messages shall be received due to previous actions.
assertThat(logMessageCounter.get()).isNotEqualTo(0); assertThat(logMessageCounter.get()).isNotEqualTo(0);
} finally {
if (db != null) {
db.close();
} }
} }
logMessageCounter.set(0);
} }
} }

@ -18,9 +18,7 @@ public class MemTableTest {
@Test @Test
public void hashSkipListMemTable() throws RocksDBException { public void hashSkipListMemTable() throws RocksDBException {
Options options = null; try(final Options options = new Options()) {
try {
options = new Options();
// Test HashSkipListMemTableConfig // Test HashSkipListMemTableConfig
HashSkipListMemTableConfig memTableConfig = HashSkipListMemTableConfig memTableConfig =
new HashSkipListMemTableConfig(); new HashSkipListMemTableConfig();
@ -40,18 +38,12 @@ public class MemTableTest {
assertThat(memTableConfig.branchingFactor()). assertThat(memTableConfig.branchingFactor()).
isEqualTo(6); isEqualTo(6);
options.setMemTableConfig(memTableConfig); options.setMemTableConfig(memTableConfig);
} finally {
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void skipListMemTable() throws RocksDBException { public void skipListMemTable() throws RocksDBException {
Options options = null; try(final Options options = new Options()) {
try {
options = new Options();
SkipListMemTableConfig skipMemTableConfig = SkipListMemTableConfig skipMemTableConfig =
new SkipListMemTableConfig(); new SkipListMemTableConfig();
assertThat(skipMemTableConfig.lookahead()). assertThat(skipMemTableConfig.lookahead()).
@ -60,19 +52,12 @@ public class MemTableTest {
assertThat(skipMemTableConfig.lookahead()). assertThat(skipMemTableConfig.lookahead()).
isEqualTo(20); isEqualTo(20);
options.setMemTableConfig(skipMemTableConfig); options.setMemTableConfig(skipMemTableConfig);
options.dispose();
} finally {
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void hashLinkedListMemTable() throws RocksDBException { public void hashLinkedListMemTable() throws RocksDBException {
Options options = null; try(final Options options = new Options()) {
try {
options = new Options();
HashLinkedListMemTableConfig hashLinkedListMemTableConfig = HashLinkedListMemTableConfig hashLinkedListMemTableConfig =
new HashLinkedListMemTableConfig(); new HashLinkedListMemTableConfig();
assertThat(hashLinkedListMemTableConfig.bucketCount()). assertThat(hashLinkedListMemTableConfig.bucketCount()).
@ -107,18 +92,12 @@ public class MemTableTest {
thresholdUseSkiplist()). thresholdUseSkiplist()).
isEqualTo(29); isEqualTo(29);
options.setMemTableConfig(hashLinkedListMemTableConfig); options.setMemTableConfig(hashLinkedListMemTableConfig);
} finally {
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void vectorMemTable() throws RocksDBException { public void vectorMemTable() throws RocksDBException {
Options options = null; try(final Options options = new Options()) {
try {
options = new Options();
VectorMemTableConfig vectorMemTableConfig = VectorMemTableConfig vectorMemTableConfig =
new VectorMemTableConfig(); new VectorMemTableConfig();
assertThat(vectorMemTableConfig.reservedSize()). assertThat(vectorMemTableConfig.reservedSize()).
@ -127,11 +106,6 @@ public class MemTableTest {
assertThat(vectorMemTableConfig.reservedSize()). assertThat(vectorMemTableConfig.reservedSize()).
isEqualTo(123); isEqualTo(123);
options.setMemTableConfig(vectorMemTableConfig); options.setMemTableConfig(vectorMemTableConfig);
options.dispose();
} finally {
if (options != null) {
options.dispose();
}
} }
} }
} }

@ -5,6 +5,7 @@
package org.rocksdb; package org.rocksdb;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
@ -27,59 +28,44 @@ public class MergeTest {
@Test @Test
public void stringOption() public void stringOption()
throws InterruptedException, RocksDBException { throws InterruptedException, RocksDBException {
RocksDB db = null; try (final Options opt = new Options()
Options opt = null; .setCreateIfMissing(true)
try { .setMergeOperatorName("stringappend");
String db_path_string = final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(); dbFolder.getRoot().getAbsolutePath())) {
opt = new Options();
opt.setCreateIfMissing(true);
opt.setMergeOperatorName("stringappend");
db = RocksDB.open(opt, db_path_string);
// writing aa under key // writing aa under key
db.put("key".getBytes(), "aa".getBytes()); db.put("key".getBytes(), "aa".getBytes());
// merge bb under key // merge bb under key
db.merge("key".getBytes(), "bb".getBytes()); db.merge("key".getBytes(), "bb".getBytes());
byte[] value = db.get("key".getBytes()); final byte[] value = db.get("key".getBytes());
String strValue = new String(value); final String strValue = new String(value);
assertThat(strValue).isEqualTo("aa,bb"); assertThat(strValue).isEqualTo("aa,bb");
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void cFStringOption() public void cFStringOption()
throws InterruptedException, RocksDBException { throws InterruptedException, RocksDBException {
RocksDB db = null;
DBOptions opt = null;
List<ColumnFamilyHandle> columnFamilyHandleList =
new ArrayList<>();
try {
String db_path_string =
dbFolder.getRoot().getAbsolutePath();
opt = new DBOptions();
opt.setCreateIfMissing(true);
opt.setCreateMissingColumnFamilies(true);
List<ColumnFamilyDescriptor> cfDescriptors =
new ArrayList<>();
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions().setMergeOperatorName(
"stringappend")));
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions().setMergeOperatorName(
"stringappend")));
db = RocksDB.open(opt, db_path_string,
cfDescriptors, columnFamilyHandleList);
try (final ColumnFamilyOptions cfOpt1 = new ColumnFamilyOptions()
.setMergeOperatorName("stringappend");
final ColumnFamilyOptions cfOpt2 = new ColumnFamilyOptions()
.setMergeOperatorName("stringappend")
) {
final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpt1),
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpt2)
);
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
try (final DBOptions opt = new DBOptions()
.setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)) {
try {
// writing aa under key // writing aa under key
db.put(columnFamilyHandleList.get(1), db.put(columnFamilyHandleList.get(1),
"cfkey".getBytes(), "aa".getBytes()); "cfkey".getBytes(), "aa".getBytes());
@ -87,18 +73,15 @@ public class MergeTest {
db.merge(columnFamilyHandleList.get(1), db.merge(columnFamilyHandleList.get(1),
"cfkey".getBytes(), "bb".getBytes()); "cfkey".getBytes(), "bb".getBytes());
byte[] value = db.get(columnFamilyHandleList.get(1), "cfkey".getBytes()); byte[] value = db.get(columnFamilyHandleList.get(1),
"cfkey".getBytes());
String strValue = new String(value); String strValue = new String(value);
assertThat(strValue).isEqualTo("aa,bb"); assertThat(strValue).isEqualTo("aa,bb");
} finally { } finally {
for (ColumnFamilyHandle handle : columnFamilyHandleList) { for (final ColumnFamilyHandle handle : columnFamilyHandleList) {
handle.dispose(); handle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -106,99 +89,85 @@ public class MergeTest {
@Test @Test
public void operatorOption() public void operatorOption()
throws InterruptedException, RocksDBException { throws InterruptedException, RocksDBException {
RocksDB db = null; final StringAppendOperator stringAppendOperator =
Options opt = null; new StringAppendOperator();
try { try (final Options opt = new Options()
String db_path_string = .setCreateIfMissing(true)
dbFolder.getRoot().getAbsolutePath(); .setMergeOperator(stringAppendOperator);
opt = new Options(); final RocksDB db = RocksDB.open(opt,
opt.setCreateIfMissing(true); dbFolder.getRoot().getAbsolutePath())) {
StringAppendOperator stringAppendOperator = new StringAppendOperator();
opt.setMergeOperator(stringAppendOperator);
db = RocksDB.open(opt, db_path_string);
// Writing aa under key // Writing aa under key
db.put("key".getBytes(), "aa".getBytes()); db.put("key".getBytes(), "aa".getBytes());
// Writing bb under key // Writing bb under key
db.merge("key".getBytes(), "bb".getBytes()); db.merge("key".getBytes(), "bb".getBytes());
byte[] value = db.get("key".getBytes()); final byte[] value = db.get("key".getBytes());
String strValue = new String(value); final String strValue = new String(value);
assertThat(strValue).isEqualTo("aa,bb"); assertThat(strValue).isEqualTo("aa,bb");
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void cFOperatorOption() public void cFOperatorOption()
throws InterruptedException, RocksDBException { throws InterruptedException, RocksDBException {
RocksDB db = null; final StringAppendOperator stringAppendOperator =
DBOptions opt = null; new StringAppendOperator();
ColumnFamilyHandle cfHandle = null; try (final ColumnFamilyOptions cfOpt1 = new ColumnFamilyOptions()
List<ColumnFamilyDescriptor> cfDescriptors = .setMergeOperator(stringAppendOperator);
new ArrayList<>(); final ColumnFamilyOptions cfOpt2 = new ColumnFamilyOptions()
List<ColumnFamilyHandle> columnFamilyHandleList = .setMergeOperator(stringAppendOperator)
new ArrayList<>(); ) {
final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpt1),
new ColumnFamilyDescriptor("new_cf".getBytes(), cfOpt2)
);
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
try (final DBOptions opt = new DBOptions()
.setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true);
final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
columnFamilyHandleList)
) {
try { try {
String db_path_string =
dbFolder.getRoot().getAbsolutePath();
opt = new DBOptions();
opt.setCreateIfMissing(true);
opt.setCreateMissingColumnFamilies(true);
StringAppendOperator stringAppendOperator = new StringAppendOperator();
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions().setMergeOperator(
stringAppendOperator)));
cfDescriptors.add(new ColumnFamilyDescriptor("new_cf".getBytes(),
new ColumnFamilyOptions().setMergeOperator(
stringAppendOperator)));
db = RocksDB.open(opt, db_path_string,
cfDescriptors, columnFamilyHandleList);
// writing aa under key // writing aa under key
db.put(columnFamilyHandleList.get(1), db.put(columnFamilyHandleList.get(1),
"cfkey".getBytes(), "aa".getBytes()); "cfkey".getBytes(), "aa".getBytes());
// merge bb under key // merge bb under key
db.merge(columnFamilyHandleList.get(1), db.merge(columnFamilyHandleList.get(1),
"cfkey".getBytes(), "bb".getBytes()); "cfkey".getBytes(), "bb".getBytes());
byte[] value = db.get(columnFamilyHandleList.get(1), "cfkey".getBytes()); byte[] value = db.get(columnFamilyHandleList.get(1),
"cfkey".getBytes());
String strValue = new String(value); String strValue = new String(value);
// Test also with createColumnFamily // Test also with createColumnFamily
cfHandle = db.createColumnFamily( try (final ColumnFamilyOptions cfHandleOpts =
new ColumnFamilyOptions()
.setMergeOperator(stringAppendOperator);
final ColumnFamilyHandle cfHandle =
db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf2".getBytes(), new ColumnFamilyDescriptor("new_cf2".getBytes(),
new ColumnFamilyOptions().setMergeOperator(stringAppendOperator))); cfHandleOpts))
) {
// writing xx under cfkey2 // writing xx under cfkey2
db.put(cfHandle, "cfkey2".getBytes(), "xx".getBytes()); db.put(cfHandle, "cfkey2".getBytes(), "xx".getBytes());
// merge yy under cfkey2 // merge yy under cfkey2
db.merge(cfHandle, new WriteOptions(), "cfkey2".getBytes(), "yy".getBytes()); db.merge(cfHandle, new WriteOptions(), "cfkey2".getBytes(),
"yy".getBytes());
value = db.get(cfHandle, "cfkey2".getBytes()); value = db.get(cfHandle, "cfkey2".getBytes());
String strValueTmpCf = new String(value); String strValueTmpCf = new String(value);
assertThat(strValue).isEqualTo("aa,bb"); assertThat(strValue).isEqualTo("aa,bb");
assertThat(strValueTmpCf).isEqualTo("xx,yy"); assertThat(strValueTmpCf).isEqualTo("xx,yy");
} finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
columnFamilyHandle.dispose();
} }
if (cfHandle != null) { } finally {
cfHandle.dispose(); for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandleList) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -206,97 +175,67 @@ public class MergeTest {
@Test @Test
public void operatorGcBehaviour() public void operatorGcBehaviour()
throws RocksDBException { throws RocksDBException {
Options opt = null; final StringAppendOperator stringAppendOperator
RocksDB db = null; = new StringAppendOperator();
try { try (final Options opt = new Options()
String db_path_string = .setCreateIfMissing(true)
dbFolder.getRoot().getAbsolutePath(); .setMergeOperator(stringAppendOperator);
opt = new Options(); final RocksDB db = RocksDB.open(opt,
opt.setCreateIfMissing(true); dbFolder.getRoot().getAbsolutePath())) {
StringAppendOperator stringAppendOperator = new StringAppendOperator(); //no-op
opt.setMergeOperator(stringAppendOperator); }
db = RocksDB.open(opt, db_path_string);
db.close();
opt.dispose();
System.gc();
System.runFinalization();
// test reuse // test reuse
opt = new Options(); try (final Options opt = new Options()
opt.setMergeOperator(stringAppendOperator); .setMergeOperator(stringAppendOperator);
db = RocksDB.open(opt, db_path_string); final RocksDB db = RocksDB.open(opt,
db.close(); dbFolder.getRoot().getAbsolutePath())) {
opt.dispose(); //no-op
System.gc(); }
System.runFinalization();
// test param init // test param init
opt = new Options(); try (final Options opt = new Options()
opt.setMergeOperator(new StringAppendOperator()); .setMergeOperator(new StringAppendOperator());
db = RocksDB.open(opt, db_path_string); final RocksDB db = RocksDB.open(opt,
db.close(); dbFolder.getRoot().getAbsolutePath())) {
opt.dispose(); //no-op
System.gc(); }
System.runFinalization();
// test replace one with another merge operator instance // test replace one with another merge operator instance
opt = new Options(); try (final Options opt = new Options()
opt.setMergeOperator(stringAppendOperator); .setMergeOperator(stringAppendOperator)) {
StringAppendOperator newStringAppendOperator = new StringAppendOperator(); final StringAppendOperator newStringAppendOperator
= new StringAppendOperator();
opt.setMergeOperator(newStringAppendOperator); opt.setMergeOperator(newStringAppendOperator);
db = RocksDB.open(opt, db_path_string); try (final RocksDB db = RocksDB.open(opt,
db.close(); dbFolder.getRoot().getAbsolutePath())) {
opt.dispose(); //no-op
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
} }
} }
} }
@Test @Test
public void emptyStringInSetMergeOperatorByName() { public void emptyStringInSetMergeOperatorByName() {
Options opt = null; try (final Options opt = new Options()
ColumnFamilyOptions cOpt = null; .setMergeOperatorName("");
try { final ColumnFamilyOptions cOpt = new ColumnFamilyOptions()
opt = new Options(); .setMergeOperatorName("")) {
cOpt = new ColumnFamilyOptions(); //no-op
opt.setMergeOperatorName("");
cOpt.setMergeOperatorName("");
} finally {
if (opt != null) {
opt.dispose();
}
if (cOpt != null) {
cOpt.dispose();
}
} }
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void nullStringInSetMergeOperatorByNameOptions() { public void nullStringInSetMergeOperatorByNameOptions() {
Options opt = null; try (final Options opt = new Options()) {
try {
opt = new Options();
opt.setMergeOperatorName(null); opt.setMergeOperatorName(null);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void public void
nullStringInSetMergeOperatorByNameColumnFamilyOptions() { nullStringInSetMergeOperatorByNameColumnFamilyOptions() {
ColumnFamilyOptions opt = null; try (final ColumnFamilyOptions opt = new ColumnFamilyOptions()) {
try {
opt = new ColumnFamilyOptions();
opt.setMergeOperatorName(null); opt.setMergeOperatorName(null);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
} }

@ -19,33 +19,30 @@ public class MixedOptionsTest {
@Test @Test
public void mixedOptionsTest(){ public void mixedOptionsTest(){
// Set a table factory and check the names // Set a table factory and check the names
ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(); try(final Filter bloomFilter = new BloomFilter();
cfOptions.setTableFormatConfig(new BlockBasedTableConfig(). final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions()
setFilter(new BloomFilter())); .setTableFormatConfig(
new BlockBasedTableConfig().setFilter(bloomFilter))
) {
assertThat(cfOptions.tableFactoryName()).isEqualTo( assertThat(cfOptions.tableFactoryName()).isEqualTo(
"BlockBasedTable"); "BlockBasedTable");
cfOptions.setTableFormatConfig(new PlainTableConfig()); cfOptions.setTableFormatConfig(new PlainTableConfig());
assertThat(cfOptions.tableFactoryName()).isEqualTo("PlainTable"); assertThat(cfOptions.tableFactoryName()).isEqualTo("PlainTable");
// Initialize a dbOptions object from cf options and // Initialize a dbOptions object from cf options and
// db options // db options
DBOptions dbOptions = new DBOptions(); try (final DBOptions dbOptions = new DBOptions();
Options options = new Options(dbOptions, cfOptions); final Options options = new Options(dbOptions, cfOptions)) {
assertThat(options.tableFactoryName()).isEqualTo("PlainTable"); assertThat(options.tableFactoryName()).isEqualTo("PlainTable");
// Free instances // Free instances
options.dispose(); }
options = null; }
cfOptions.dispose();
cfOptions = null;
dbOptions.dispose();
dbOptions = null;
System.gc();
System.runFinalization();
// Test Optimize for statements // Test Optimize for statements
cfOptions = new ColumnFamilyOptions(); try(final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions()) {
cfOptions.optimizeUniversalStyleCompaction(); cfOptions.optimizeUniversalStyleCompaction();
cfOptions.optimizeLevelStyleCompaction(); cfOptions.optimizeLevelStyleCompaction();
cfOptions.optimizeForPointLookup(1024); cfOptions.optimizeForPointLookup(1024);
options = new Options(); try(final Options options = new Options()) {
options.optimizeLevelStyleCompaction(); options.optimizeLevelStyleCompaction();
options.optimizeLevelStyleCompaction(400); options.optimizeLevelStyleCompaction(400);
options.optimizeUniversalStyleCompaction(); options.optimizeUniversalStyleCompaction();
@ -54,3 +51,5 @@ public class MixedOptionsTest {
options.prepareForBulkLoad(); options.prepareForBulkLoad();
} }
} }
}
}

@ -23,7 +23,7 @@ public class NativeLibraryLoaderTest {
public void tempFolder() throws IOException { public void tempFolder() throws IOException {
NativeLibraryLoader.getInstance().loadLibraryFromJarToTemp( NativeLibraryLoader.getInstance().loadLibraryFromJarToTemp(
temporaryFolder.getRoot().getAbsolutePath()); temporaryFolder.getRoot().getAbsolutePath());
Path path = Paths.get(temporaryFolder.getRoot().getAbsolutePath(), final Path path = Paths.get(temporaryFolder.getRoot().getAbsolutePath(),
Environment.getJniLibraryFileName("rocksdb")); Environment.getJniLibraryFileName("rocksdb"));
assertThat(Files.exists(path)).isTrue(); assertThat(Files.exists(path)).isTrue();
assertThat(Files.isReadable(path)).isTrue(); assertThat(Files.isReadable(path)).isTrue();

File diff suppressed because it is too large Load Diff

@ -80,16 +80,10 @@ public class PlainTableConfigTest {
@Test @Test
public void plainTableConfig() { public void plainTableConfig() {
Options opt = null; try(final Options opt = new Options()) {
try { final PlainTableConfig plainTableConfig = new PlainTableConfig();
opt = new Options();
PlainTableConfig plainTableConfig = new PlainTableConfig();
opt.setTableFormatConfig(plainTableConfig); opt.setTableFormatConfig(plainTableConfig);
assertThat(opt.tableFactoryName()).isEqualTo("PlainTable"); assertThat(opt.tableFactoryName()).isEqualTo("PlainTable");
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
} }

@ -18,7 +18,7 @@ public class PlatformRandomHelper {
* @return boolean value indicating if operating system is 64 Bit. * @return boolean value indicating if operating system is 64 Bit.
*/ */
public static boolean isOs64Bit(){ public static boolean isOs64Bit(){
boolean is64Bit; final boolean is64Bit;
if (System.getProperty("os.name").contains("Windows")) { if (System.getProperty("os.name").contains("Windows")) {
is64Bit = (System.getenv("ProgramFiles(x86)") != null); is64Bit = (System.getenv("ProgramFiles(x86)") != null);
} else { } else {

@ -10,6 +10,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -25,340 +26,279 @@ public class ReadOnlyTest {
@Test @Test
public void readOnlyOpen() throws RocksDBException { public void readOnlyOpen() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options()
RocksDB db2 = null; .setCreateIfMissing(true);
RocksDB db3 = null; final RocksDB db = RocksDB.open(options,
Options options = null; dbFolder.getRoot().getAbsolutePath())) {
List<ColumnFamilyHandle> columnFamilyHandleList =
new ArrayList<>();
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList2 =
new ArrayList<>();
try {
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
db2 = RocksDB.openReadOnly( try (final RocksDB db2 = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
assertThat("value"). assertThat("value").
isEqualTo(new String(db2.get("key".getBytes()))); isEqualTo(new String(db2.get("key".getBytes())));
db.close(); }
db2.close(); }
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
cfDescriptors.add( final List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>();
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfDescriptors.add(new ColumnFamilyDescriptor(
new ColumnFamilyOptions())); RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts));
db = RocksDB.open( final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, columnFamilyHandleList); try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(),
cfDescriptors, columnFamilyHandleList)) {
try (final ColumnFamilyOptions newCfOpts = new ColumnFamilyOptions();
final ColumnFamilyOptions newCf2Opts = new ColumnFamilyOptions()
) {
columnFamilyHandleList.add(db.createColumnFamily( columnFamilyHandleList.add(db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf".getBytes(), new ColumnFamilyOptions()))); new ColumnFamilyDescriptor("new_cf".getBytes(), newCfOpts)));
columnFamilyHandleList.add(db.createColumnFamily( columnFamilyHandleList.add(db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf2".getBytes(), new ColumnFamilyOptions()))); new ColumnFamilyDescriptor("new_cf2".getBytes(), newCf2Opts)));
db.put(columnFamilyHandleList.get(2), "key2".getBytes(), db.put(columnFamilyHandleList.get(2), "key2".getBytes(),
"value2".getBytes()); "value2".getBytes());
db2 = RocksDB.openReadOnly( final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try (final RocksDB db2 = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList); readOnlyColumnFamilyHandleList)) {
try (final ColumnFamilyOptions newCfOpts2 =
new ColumnFamilyOptions();
final ColumnFamilyOptions newCf2Opts2 =
new ColumnFamilyOptions()
) {
assertThat(db2.get("key2".getBytes())).isNull(); assertThat(db2.get("key2".getBytes())).isNull();
assertThat(db2.get(readOnlyColumnFamilyHandleList.get(0), "key2".getBytes())). assertThat(db2.get(readOnlyColumnFamilyHandleList.get(0),
"key2".getBytes())).
isNull(); isNull();
cfDescriptors.clear(); cfDescriptors.clear();
cfDescriptors.add( cfDescriptors.add(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions())); newCfOpts2));
cfDescriptors.add( cfDescriptors.add(new ColumnFamilyDescriptor("new_cf2".getBytes(),
new ColumnFamilyDescriptor("new_cf2".getBytes(), new ColumnFamilyOptions())); newCf2Opts2));
db3 = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, readOnlyColumnFamilyHandleList2); final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList2
assertThat(new String(db3.get(readOnlyColumnFamilyHandleList2.get(1), = new ArrayList<>();
try (final RocksDB db3 = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList2)) {
try {
assertThat(new String(db3.get(
readOnlyColumnFamilyHandleList2.get(1),
"key2".getBytes()))).isEqualTo("value2"); "key2".getBytes()))).isEqualTo("value2");
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList2) {
columnFamilyHandle.close();
} }
if (db != null) {
db.close();
} }
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) {
columnFamilyHandle.dispose();
} }
if (db2 != null) { } finally {
db2.close(); for (final ColumnFamilyHandle columnFamilyHandle :
readOnlyColumnFamilyHandleList) {
columnFamilyHandle.close();
} }
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList2) {
columnFamilyHandle.dispose();
} }
if (db3 != null) {
db3.close();
} }
if (options != null) { } finally {
options.dispose(); for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandleList) {
columnFamilyHandle.close();
}
}
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failToWriteInReadOnly() throws RocksDBException { public void failToWriteInReadOnly() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options()
RocksDB rDb = null; .setCreateIfMissing(true)) {
Options options = null;
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>();
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try {
cfDescriptors.add( try (final RocksDB db = RocksDB.open(options,
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, dbFolder.getRoot().getAbsolutePath())) {
new ColumnFamilyOptions())); //no-op
}
}
options = new Options(); try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
options.setCreateIfMissing(true); final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts)
);
db = RocksDB.open(options, final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
dbFolder.getRoot().getAbsolutePath()); new ArrayList<>();
db.close(); try (final RocksDB rDb = RocksDB.openReadOnly(
rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList); readOnlyColumnFamilyHandleList)) {
try {
// test that put fails in readonly mode // test that put fails in readonly mode
rDb.put("key".getBytes(), "value".getBytes()); rDb.put("key".getBytes(), "value".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (rDb != null) {
rDb.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failToCFWriteInReadOnly() throws RocksDBException { public void failToCFWriteInReadOnly() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
RocksDB rDb = null; final RocksDB db = RocksDB.open(options,
Options options = null; dbFolder.getRoot().getAbsolutePath())) {
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); //no-op
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList = }
new ArrayList<>();
try {
cfDescriptors.add(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions()));
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
dbFolder.getRoot().getAbsolutePath()); final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
db.close(); new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts)
rDb = RocksDB.openReadOnly( );
final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try (final RocksDB rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList); readOnlyColumnFamilyHandleList)) {
try {
rDb.put(readOnlyColumnFamilyHandleList.get(0), rDb.put(readOnlyColumnFamilyHandleList.get(0),
"key".getBytes(), "value".getBytes()); "key".getBytes(), "value".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (rDb != null) {
rDb.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failToRemoveInReadOnly() throws RocksDBException { public void failToRemoveInReadOnly() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
RocksDB rDb = null; final RocksDB db = RocksDB.open(options,
Options options = null; dbFolder.getRoot().getAbsolutePath())) {
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); //no-op
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList = }
new ArrayList<>();
try {
cfDescriptors.add(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions()));
options = new Options(); try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
options.setCreateIfMissing(true); final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts)
);
db = RocksDB.open(options, final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
dbFolder.getRoot().getAbsolutePath()); new ArrayList<>();
db.close();
rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList);
try (final RocksDB rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList)) {
try {
rDb.remove("key".getBytes()); rDb.remove("key".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (rDb != null) {
rDb.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failToCFRemoveInReadOnly() throws RocksDBException { public void failToCFRemoveInReadOnly() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
RocksDB rDb = null; final RocksDB db = RocksDB.open(options,
Options options = null; dbFolder.getRoot().getAbsolutePath())) {
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); //no-op
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList = }
new ArrayList<>();
try {
cfDescriptors.add(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions()));
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
dbFolder.getRoot().getAbsolutePath()); final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
db.close(); new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts)
);
rDb = RocksDB.openReadOnly( final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try (final RocksDB rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList); readOnlyColumnFamilyHandleList)) {
try {
rDb.remove(readOnlyColumnFamilyHandleList.get(0), rDb.remove(readOnlyColumnFamilyHandleList.get(0),
"key".getBytes()); "key".getBytes());
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (rDb != null) {
rDb.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failToWriteBatchReadOnly() throws RocksDBException { public void failToWriteBatchReadOnly() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
RocksDB rDb = null; final RocksDB db = RocksDB.open(options,
Options options = null; dbFolder.getRoot().getAbsolutePath())) {
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); //no-op
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList = }
new ArrayList<>();
try {
cfDescriptors.add(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions()));
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
dbFolder.getRoot().getAbsolutePath()); final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
db.close(); new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts)
);
rDb = RocksDB.openReadOnly( final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try (final RocksDB rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList); readOnlyColumnFamilyHandleList);
final WriteBatch wb = new WriteBatch();
WriteBatch wb = new WriteBatch(); final WriteOptions wOpts = new WriteOptions()) {
try {
wb.put("key".getBytes(), "value".getBytes()); wb.put("key".getBytes(), "value".getBytes());
rDb.write(new WriteOptions(), wb); rDb.write(wOpts, wb);
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
} }
if (rDb != null) {
rDb.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void failToCFWriteBatchReadOnly() throws RocksDBException { public void failToCFWriteBatchReadOnly() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
RocksDB rDb = null; final RocksDB db = RocksDB.open(options,
Options options = null; dbFolder.getRoot().getAbsolutePath())) {
WriteBatch wb = null; //no-op
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); }
List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try {
cfDescriptors.add(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
new ColumnFamilyOptions()));
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()) {
dbFolder.getRoot().getAbsolutePath()); final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
db.close(); new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts)
);
rDb = RocksDB.openReadOnly( final List<ColumnFamilyHandle> readOnlyColumnFamilyHandleList =
new ArrayList<>();
try (final RocksDB rDb = RocksDB.openReadOnly(
dbFolder.getRoot().getAbsolutePath(), cfDescriptors, dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
readOnlyColumnFamilyHandleList); readOnlyColumnFamilyHandleList);
final WriteBatch wb = new WriteBatch();
wb = new WriteBatch(); final WriteOptions wOpts = new WriteOptions()) {
wb.put(readOnlyColumnFamilyHandleList.get(0), try {
"key".getBytes(), "value".getBytes()); wb.put(readOnlyColumnFamilyHandleList.get(0), "key".getBytes(),
rDb.write(new WriteOptions(), wb); "value".getBytes());
rDb.write(wOpts, wb);
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : readOnlyColumnFamilyHandleList) { for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandle.dispose(); readOnlyColumnFamilyHandleList) {
} columnFamilyHandle.close();
if (db != null) {
db.close();
}
if (rDb != null) {
rDb.close();
} }
if (options != null) {
options.dispose();
} }
if (wb != null) {
wb.dispose();
} }
} }
} }

@ -25,126 +25,110 @@ public class ReadOptionsTest {
@Test @Test
public void verifyChecksum() { public void verifyChecksum() {
ReadOptions opt = null; try (final ReadOptions opt = new ReadOptions()) {
try { final Random rand = new Random();
opt = new ReadOptions(); final boolean boolValue = rand.nextBoolean();
Random rand = new Random();
boolean boolValue = rand.nextBoolean();
opt.setVerifyChecksums(boolValue); opt.setVerifyChecksums(boolValue);
assertThat(opt.verifyChecksums()).isEqualTo(boolValue); assertThat(opt.verifyChecksums()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void fillCache() { public void fillCache() {
ReadOptions opt = null; try (final ReadOptions opt = new ReadOptions()) {
try { final Random rand = new Random();
opt = new ReadOptions(); final boolean boolValue = rand.nextBoolean();
Random rand = new Random();
boolean boolValue = rand.nextBoolean();
opt.setFillCache(boolValue); opt.setFillCache(boolValue);
assertThat(opt.fillCache()).isEqualTo(boolValue); assertThat(opt.fillCache()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void tailing() { public void tailing() {
ReadOptions opt = null; try (final ReadOptions opt = new ReadOptions()) {
try { final Random rand = new Random();
opt = new ReadOptions(); final boolean boolValue = rand.nextBoolean();
Random rand = new Random();
boolean boolValue = rand.nextBoolean();
opt.setTailing(boolValue); opt.setTailing(boolValue);
assertThat(opt.tailing()).isEqualTo(boolValue); assertThat(opt.tailing()).isEqualTo(boolValue);
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void snapshot() { public void snapshot() {
ReadOptions opt = null; try (final ReadOptions opt = new ReadOptions()) {
try {
opt = new ReadOptions();
opt.setSnapshot(null); opt.setSnapshot(null);
assertThat(opt.snapshot()).isNull(); assertThat(opt.snapshot()).isNull();
} finally {
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void failSetVerifyChecksumUninitialized() { public void failSetVerifyChecksumUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.setVerifyChecksums(true); readOptions.setVerifyChecksums(true);
} }
}
@Test @Test
public void failVerifyChecksumUninitialized() { public void failVerifyChecksumUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.verifyChecksums(); readOptions.verifyChecksums();
} }
}
@Test @Test
public void failSetFillCacheUninitialized() { public void failSetFillCacheUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.setFillCache(true); readOptions.setFillCache(true);
} }
}
@Test @Test
public void failFillCacheUninitialized() { public void failFillCacheUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.fillCache(); readOptions.fillCache();
} }
}
@Test @Test
public void failSetTailingUninitialized() { public void failSetTailingUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.setTailing(true); readOptions.setTailing(true);
} }
}
@Test @Test
public void failTailingUninitialized() { public void failTailingUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.tailing(); readOptions.tailing();
} }
}
@Test @Test
public void failSetSnapshotUninitialized() { public void failSetSnapshotUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.setSnapshot(null); readOptions.setSnapshot(null);
} }
}
@Test @Test
public void failSnapshotUninitialized() { public void failSnapshotUninitialized() {
ReadOptions readOptions = setupUninitializedReadOptions( try (final ReadOptions readOptions =
exception); setupUninitializedReadOptions(exception)) {
readOptions.snapshot(); readOptions.snapshot();
} }
}
private ReadOptions setupUninitializedReadOptions( private ReadOptions setupUninitializedReadOptions(
ExpectedException exception) { ExpectedException exception) {
ReadOptions readOptions = new ReadOptions(); final ReadOptions readOptions = new ReadOptions();
readOptions.dispose(); readOptions.close();
exception.expect(AssertionError.class); exception.expect(AssertionError.class);
return readOptions; return readOptions;
} }

@ -9,10 +9,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -30,96 +27,65 @@ public class RocksDBTest {
@Test @Test
public void open() throws RocksDBException { public void open() throws RocksDBException {
RocksDB db = null; try (final RocksDB db =
Options opt = null; RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
try { assertThat(db).isNotNull();
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
db.close();
opt = new Options();
opt.setCreateIfMissing(true);
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath());
} finally {
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
@Test
public void open_opt() throws RocksDBException {
try (final Options opt = new Options().setCreateIfMissing(true);
final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath())) {
assertThat(db).isNotNull();
} }
} }
@Test @Test
public void put() throws RocksDBException { public void put() throws RocksDBException {
RocksDB db = null; try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
WriteOptions opt = null; final WriteOptions opt = new WriteOptions()) {
try {
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
db.put("key1".getBytes(), "value".getBytes()); db.put("key1".getBytes(), "value".getBytes());
opt = new WriteOptions();
db.put(opt, "key2".getBytes(), "12345678".getBytes()); db.put(opt, "key2".getBytes(), "12345678".getBytes());
assertThat(db.get("key1".getBytes())).isEqualTo( assertThat(db.get("key1".getBytes())).isEqualTo(
"value".getBytes()); "value".getBytes());
assertThat(db.get("key2".getBytes())).isEqualTo( assertThat(db.get("key2".getBytes())).isEqualTo(
"12345678".getBytes()); "12345678".getBytes());
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void write() throws RocksDBException { public void write() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setMergeOperator(
Options options = null; new StringAppendOperator()).setCreateIfMissing(true);
WriteBatch wb1 = null; final RocksDB db = RocksDB.open(options,
WriteBatch wb2 = null; dbFolder.getRoot().getAbsolutePath());
WriteOptions opts = null; final WriteOptions opts = new WriteOptions()) {
try {
options = new Options(). try (final WriteBatch wb1 = new WriteBatch()) {
setMergeOperator(new StringAppendOperator()).
setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
opts = new WriteOptions();
wb1 = new WriteBatch();
wb1.put("key1".getBytes(), "aa".getBytes()); wb1.put("key1".getBytes(), "aa".getBytes());
wb1.merge("key1".getBytes(), "bb".getBytes()); wb1.merge("key1".getBytes(), "bb".getBytes());
wb2 = new WriteBatch();
try (final WriteBatch wb2 = new WriteBatch()) {
wb2.put("key2".getBytes(), "xx".getBytes()); wb2.put("key2".getBytes(), "xx".getBytes());
wb2.merge("key2".getBytes(), "yy".getBytes()); wb2.merge("key2".getBytes(), "yy".getBytes());
db.write(opts, wb1); db.write(opts, wb1);
db.write(opts, wb2); db.write(opts, wb2);
}
}
assertThat(db.get("key1".getBytes())).isEqualTo( assertThat(db.get("key1".getBytes())).isEqualTo(
"aa,bb".getBytes()); "aa,bb".getBytes());
assertThat(db.get("key2".getBytes())).isEqualTo( assertThat(db.get("key2".getBytes())).isEqualTo(
"xx,yy".getBytes()); "xx,yy".getBytes());
} finally {
if (db != null) {
db.close();
}
if (wb1 != null) {
wb1.dispose();
}
if (wb2 != null) {
wb2.dispose();
}
if (options != null) {
options.dispose();
}
if (opts != null) {
opts.dispose();
}
} }
} }
@Test @Test
public void getWithOutValue() throws RocksDBException { public void getWithOutValue() throws RocksDBException {
RocksDB db = null; try (final RocksDB db =
try { RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
db.put("key1".getBytes(), "value".getBytes()); db.put("key1".getBytes(), "value".getBytes());
db.put("key2".getBytes(), "12345678".getBytes()); db.put("key2".getBytes(), "12345678".getBytes());
byte[] outValue = new byte[5]; byte[] outValue = new byte[5];
@ -134,20 +100,13 @@ public class RocksDBTest {
getResult = db.get("key2".getBytes(), outValue); getResult = db.get("key2".getBytes(), outValue);
assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
assertThat(outValue).isEqualTo("12345".getBytes()); assertThat(outValue).isEqualTo("12345".getBytes());
} finally {
if (db != null) {
db.close();
}
} }
} }
@Test @Test
public void getWithOutValueReadOptions() throws RocksDBException { public void getWithOutValueReadOptions() throws RocksDBException {
RocksDB db = null; try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
ReadOptions rOpt = null; final ReadOptions rOpt = new ReadOptions()) {
try {
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
rOpt = new ReadOptions();
db.put("key1".getBytes(), "value".getBytes()); db.put("key1".getBytes(), "value".getBytes());
db.put("key2".getBytes(), "12345678".getBytes()); db.put("key2".getBytes(), "12345678".getBytes());
byte[] outValue = new byte[5]; byte[] outValue = new byte[5];
@ -163,29 +122,18 @@ public class RocksDBTest {
getResult = db.get(rOpt, "key2".getBytes(), outValue); getResult = db.get(rOpt, "key2".getBytes(), outValue);
assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND); assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
assertThat(outValue).isEqualTo("12345".getBytes()); assertThat(outValue).isEqualTo("12345".getBytes());
} finally {
if (db != null) {
db.close();
}
if (rOpt != null) {
rOpt.dispose();
}
} }
} }
@Test @Test
public void multiGet() throws RocksDBException { public void multiGet() throws RocksDBException, InterruptedException {
RocksDB db = null; try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
ReadOptions rOpt = null; final ReadOptions rOpt = new ReadOptions()) {
try {
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
rOpt = new ReadOptions();
db.put("key1".getBytes(), "value".getBytes()); db.put("key1".getBytes(), "value".getBytes());
db.put("key2".getBytes(), "12345678".getBytes()); db.put("key2".getBytes(), "12345678".getBytes());
List<byte[]> lookupKeys = new ArrayList<byte[]>() {{ List<byte[]> lookupKeys = new ArrayList<>();
add("key1".getBytes()); lookupKeys.add("key1".getBytes());
add("key2".getBytes()); lookupKeys.add("key2".getBytes());
}};
Map<byte[], byte[]> results = db.multiGet(lookupKeys); Map<byte[], byte[]> results = db.multiGet(lookupKeys);
assertThat(results).isNotNull(); assertThat(results).isNotNull();
assertThat(results.values()).isNotNull(); assertThat(results.values()).isNotNull();
@ -213,27 +161,18 @@ public class RocksDBTest {
assertThat(results.values()).isNotNull(); assertThat(results.values()).isNotNull();
assertThat(results.values()). assertThat(results.values()).
contains("value".getBytes()); contains("value".getBytes());
} finally {
if (db != null) {
db.close();
}
if (rOpt != null) {
rOpt.dispose();
}
} }
} }
@Test @Test
public void merge() throws RocksDBException { public void merge() throws RocksDBException {
RocksDB db = null; try (final Options opt = new Options()
Options opt = null; .setCreateIfMissing(true)
WriteOptions wOpt; .setMergeOperator(new StringAppendOperator());
try { final WriteOptions wOpt = new WriteOptions();
opt = new Options(). final RocksDB db = RocksDB.open(opt,
setCreateIfMissing(true). dbFolder.getRoot().getAbsolutePath())
setMergeOperator(new StringAppendOperator()); ) {
wOpt = new WriteOptions();
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath());
db.put("key1".getBytes(), "value".getBytes()); db.put("key1".getBytes(), "value".getBytes());
assertThat(db.get("key1".getBytes())).isEqualTo( assertThat(db.get("key1".getBytes())).isEqualTo(
"value".getBytes()); "value".getBytes());
@ -249,23 +188,13 @@ public class RocksDBTest {
db.merge(wOpt, "key2".getBytes(), "xxxx".getBytes()); db.merge(wOpt, "key2".getBytes(), "xxxx".getBytes());
assertThat(db.get("key2".getBytes())).isEqualTo( assertThat(db.get("key2".getBytes())).isEqualTo(
"xxxx".getBytes()); "xxxx".getBytes());
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void remove() throws RocksDBException { public void remove() throws RocksDBException {
RocksDB db = null; try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
WriteOptions wOpt; final WriteOptions wOpt = new WriteOptions()) {
try {
wOpt = new WriteOptions();
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
db.put("key1".getBytes(), "value".getBytes()); db.put("key1".getBytes(), "value".getBytes());
db.put("key2".getBytes(), "12345678".getBytes()); db.put("key2".getBytes(), "12345678".getBytes());
assertThat(db.get("key1".getBytes())).isEqualTo( assertThat(db.get("key1".getBytes())).isEqualTo(
@ -276,52 +205,34 @@ public class RocksDBTest {
db.remove(wOpt, "key2".getBytes()); db.remove(wOpt, "key2".getBytes());
assertThat(db.get("key1".getBytes())).isNull(); assertThat(db.get("key1".getBytes())).isNull();
assertThat(db.get("key2".getBytes())).isNull(); assertThat(db.get("key2".getBytes())).isNull();
} finally {
if (db != null) {
db.close();
}
} }
} }
@Test @Test
public void getIntProperty() throws RocksDBException { public void getIntProperty() throws RocksDBException {
RocksDB db = null; try (
Options options = null; final Options options = new Options()
WriteOptions wOpt = null; .setCreateIfMissing(true)
try { .setMaxWriteBufferNumber(10)
options = new Options(); .setMinWriteBufferNumberToMerge(10);
wOpt = new WriteOptions(); final RocksDB db = RocksDB.open(options,
// Setup options dbFolder.getRoot().getAbsolutePath());
options.setCreateIfMissing(true); final WriteOptions wOpt = new WriteOptions().setDisableWAL(true)
options.setMaxWriteBufferNumber(10); ) {
options.setMinWriteBufferNumberToMerge(10);
wOpt.setDisableWAL(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.put(wOpt, "key1".getBytes(), "value1".getBytes()); db.put(wOpt, "key1".getBytes(), "value1".getBytes());
db.put(wOpt, "key2".getBytes(), "value2".getBytes()); db.put(wOpt, "key2".getBytes(), "value2".getBytes());
db.put(wOpt, "key3".getBytes(), "value3".getBytes()); db.put(wOpt, "key3".getBytes(), "value3".getBytes());
db.put(wOpt, "key4".getBytes(), "value4".getBytes()); db.put(wOpt, "key4".getBytes(), "value4".getBytes());
assertThat(db.getLongProperty("rocksdb.num-entries-active-mem-table")).isGreaterThan(0); assertThat(db.getLongProperty("rocksdb.num-entries-active-mem-table"))
assertThat(db.getLongProperty("rocksdb.cur-size-active-mem-table")).isGreaterThan(0); .isGreaterThan(0);
} finally { assertThat(db.getLongProperty("rocksdb.cur-size-active-mem-table"))
if (db != null) { .isGreaterThan(0);
db.close();
}
if (options != null) {
options.dispose();
}
if (wOpt != null) {
wOpt.dispose();
}
} }
} }
@Test @Test
public void fullCompactRange() throws RocksDBException { public void fullCompactRange() throws RocksDBException {
RocksDB db = null; try (final Options opt = new Options().
Options opt = null;
try {
opt = new Options().
setCreateIfMissing(true). setCreateIfMissing(true).
setDisableAutoCompactions(true). setDisableAutoCompactions(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
@ -333,9 +244,8 @@ public class RocksDBTest {
setMaxBytesForLevelBase(500 << 10). setMaxBytesForLevelBase(500 << 10).
setMaxBytesForLevelMultiplier(1). setMaxBytesForLevelMultiplier(1).
setDisableAutoCompactions(false); setDisableAutoCompactions(false);
// open database final RocksDB db = RocksDB.open(opt,
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
dbFolder.getRoot().getAbsolutePath());
// fill database with key/value pairs // fill database with key/value pairs
byte[] b = new byte[10000]; byte[] b = new byte[10000];
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
@ -343,34 +253,17 @@ public class RocksDBTest {
db.put((String.valueOf(i)).getBytes(), b); db.put((String.valueOf(i)).getBytes(), b);
} }
db.compactRange(); db.compactRange();
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void fullCompactRangeColumnFamily() public void fullCompactRangeColumnFamily()
throws RocksDBException { throws RocksDBException {
RocksDB db = null; try (
DBOptions opt = null; final DBOptions opt = new DBOptions().
List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>();
try {
opt = new DBOptions().
setCreateIfMissing(true). setCreateIfMissing(true).
setCreateMissingColumnFamilies(true); setCreateMissingColumnFamilies(true);
List<ColumnFamilyDescriptor> columnFamilyDescriptors = final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
new ArrayList<>();
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
RocksDB.DEFAULT_COLUMN_FAMILY));
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
"new_cf".getBytes(),
new ColumnFamilyOptions().
setDisableAutoCompactions(true). setDisableAutoCompactions(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
setNumLevels(4). setNumLevels(4).
@ -380,12 +273,20 @@ public class RocksDBTest {
setTargetFileSizeMultiplier(1). setTargetFileSizeMultiplier(1).
setMaxBytesForLevelBase(500 << 10). setMaxBytesForLevelBase(500 << 10).
setMaxBytesForLevelMultiplier(1). setMaxBytesForLevelMultiplier(1).
setDisableAutoCompactions(false))); setDisableAutoCompactions(false)
) {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));
// open database // open database
db = RocksDB.open(opt, final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
try (final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
columnFamilyDescriptors, columnFamilyDescriptors,
columnFamilyHandles); columnFamilyHandles)) {
try {
// fill database with key/value pairs // fill database with key/value pairs
byte[] b = new byte[10000]; byte[] b = new byte[10000];
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
@ -395,14 +296,10 @@ public class RocksDBTest {
} }
db.compactRange(columnFamilyHandles.get(1)); db.compactRange(columnFamilyHandles.get(1));
} finally { } finally {
for (ColumnFamilyHandle handle : columnFamilyHandles) { for (final ColumnFamilyHandle handle : columnFamilyHandles) {
handle.dispose(); handle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -410,10 +307,7 @@ public class RocksDBTest {
@Test @Test
public void compactRangeWithKeys() public void compactRangeWithKeys()
throws RocksDBException { throws RocksDBException {
RocksDB db = null; try (final Options opt = new Options().
Options opt = null;
try {
opt = new Options().
setCreateIfMissing(true). setCreateIfMissing(true).
setDisableAutoCompactions(true). setDisableAutoCompactions(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
@ -425,9 +319,8 @@ public class RocksDBTest {
setMaxBytesForLevelBase(500 << 10). setMaxBytesForLevelBase(500 << 10).
setMaxBytesForLevelMultiplier(1). setMaxBytesForLevelMultiplier(1).
setDisableAutoCompactions(false); setDisableAutoCompactions(false);
// open database final RocksDB db = RocksDB.open(opt,
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
dbFolder.getRoot().getAbsolutePath());
// fill database with key/value pairs // fill database with key/value pairs
byte[] b = new byte[10000]; byte[] b = new byte[10000];
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
@ -435,23 +328,14 @@ public class RocksDBTest {
db.put((String.valueOf(i)).getBytes(), b); db.put((String.valueOf(i)).getBytes(), b);
} }
db.compactRange("0".getBytes(), "201".getBytes()); db.compactRange("0".getBytes(), "201".getBytes());
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void compactRangeWithKeysReduce() public void compactRangeWithKeysReduce()
throws RocksDBException { throws RocksDBException {
RocksDB db = null; try (
Options opt = null; final Options opt = new Options().
try {
opt = new Options().
setCreateIfMissing(true). setCreateIfMissing(true).
setDisableAutoCompactions(true). setDisableAutoCompactions(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
@ -463,9 +347,8 @@ public class RocksDBTest {
setMaxBytesForLevelBase(500 << 10). setMaxBytesForLevelBase(500 << 10).
setMaxBytesForLevelMultiplier(1). setMaxBytesForLevelMultiplier(1).
setDisableAutoCompactions(false); setDisableAutoCompactions(false);
// open database final RocksDB db = RocksDB.open(opt,
db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
dbFolder.getRoot().getAbsolutePath());
// fill database with key/value pairs // fill database with key/value pairs
byte[] b = new byte[10000]; byte[] b = new byte[10000];
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
@ -475,34 +358,16 @@ public class RocksDBTest {
db.flush(new FlushOptions().setWaitForFlush(true)); db.flush(new FlushOptions().setWaitForFlush(true));
db.compactRange("0".getBytes(), "201".getBytes(), db.compactRange("0".getBytes(), "201".getBytes(),
true, -1, 0); true, -1, 0);
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void compactRangeWithKeysColumnFamily() public void compactRangeWithKeysColumnFamily()
throws RocksDBException { throws RocksDBException {
RocksDB db = null; try (final DBOptions opt = new DBOptions().
DBOptions opt = null;
List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>();
try {
opt = new DBOptions().
setCreateIfMissing(true). setCreateIfMissing(true).
setCreateMissingColumnFamilies(true); setCreateMissingColumnFamilies(true);
List<ColumnFamilyDescriptor> columnFamilyDescriptors = final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
new ArrayList<>();
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
RocksDB.DEFAULT_COLUMN_FAMILY));
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
"new_cf".getBytes(),
new ColumnFamilyOptions().
setDisableAutoCompactions(true). setDisableAutoCompactions(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
setNumLevels(4). setNumLevels(4).
@ -512,12 +377,22 @@ public class RocksDBTest {
setTargetFileSizeMultiplier(1). setTargetFileSizeMultiplier(1).
setMaxBytesForLevelBase(500 << 10). setMaxBytesForLevelBase(500 << 10).
setMaxBytesForLevelMultiplier(1). setMaxBytesForLevelMultiplier(1).
setDisableAutoCompactions(false))); setDisableAutoCompactions(false)
) {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
);
// open database // open database
db = RocksDB.open(opt, final List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>();
try (final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
columnFamilyDescriptors, columnFamilyDescriptors,
columnFamilyHandles); columnFamilyHandles)) {
try {
// fill database with key/value pairs // fill database with key/value pairs
byte[] b = new byte[10000]; byte[] b = new byte[10000];
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
@ -528,14 +403,10 @@ public class RocksDBTest {
db.compactRange(columnFamilyHandles.get(1), db.compactRange(columnFamilyHandles.get(1),
"0".getBytes(), "201".getBytes()); "0".getBytes(), "201".getBytes());
} finally { } finally {
for (ColumnFamilyHandle handle : columnFamilyHandles) { for (final ColumnFamilyHandle handle : columnFamilyHandles) {
handle.dispose(); handle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -543,21 +414,10 @@ public class RocksDBTest {
@Test @Test
public void compactRangeWithKeysReduceColumnFamily() public void compactRangeWithKeysReduceColumnFamily()
throws RocksDBException { throws RocksDBException {
RocksDB db = null; try (final DBOptions opt = new DBOptions().
DBOptions opt = null;
List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>();
try {
opt = new DBOptions().
setCreateIfMissing(true). setCreateIfMissing(true).
setCreateMissingColumnFamilies(true); setCreateMissingColumnFamilies(true);
List<ColumnFamilyDescriptor> columnFamilyDescriptors = final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
new ArrayList<>();
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
RocksDB.DEFAULT_COLUMN_FAMILY));
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
"new_cf".getBytes(),
new ColumnFamilyOptions().
setDisableAutoCompactions(true). setDisableAutoCompactions(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
setNumLevels(4). setNumLevels(4).
@ -567,12 +427,21 @@ public class RocksDBTest {
setTargetFileSizeMultiplier(1). setTargetFileSizeMultiplier(1).
setMaxBytesForLevelBase(500 << 10). setMaxBytesForLevelBase(500 << 10).
setMaxBytesForLevelMultiplier(1). setMaxBytesForLevelMultiplier(1).
setDisableAutoCompactions(false))); setDisableAutoCompactions(false)
) {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
);
final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
// open database // open database
db = RocksDB.open(opt, try (final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
columnFamilyDescriptors, columnFamilyDescriptors,
columnFamilyHandles); columnFamilyHandles)) {
try {
// fill database with key/value pairs // fill database with key/value pairs
byte[] b = new byte[10000]; byte[] b = new byte[10000];
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
@ -583,14 +452,10 @@ public class RocksDBTest {
db.compactRange(columnFamilyHandles.get(1), "0".getBytes(), db.compactRange(columnFamilyHandles.get(1), "0".getBytes(),
"201".getBytes(), true, -1, 0); "201".getBytes(), true, -1, 0);
} finally { } finally {
for (ColumnFamilyHandle handle : columnFamilyHandles) { for (final ColumnFamilyHandle handle : columnFamilyHandles) {
handle.dispose(); handle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@ -598,9 +463,6 @@ public class RocksDBTest {
@Test @Test
public void compactRangeToLevel() public void compactRangeToLevel()
throws RocksDBException, InterruptedException { throws RocksDBException, InterruptedException {
RocksDB db = null;
Options opt = null;
try {
final int NUM_KEYS_PER_L0_FILE = 100; final int NUM_KEYS_PER_L0_FILE = 100;
final int KEY_SIZE = 20; final int KEY_SIZE = 20;
final int VALUE_SIZE = 300; final int VALUE_SIZE = 300;
@ -609,7 +471,7 @@ public class RocksDBTest {
final int NUM_L0_FILES = 10; final int NUM_L0_FILES = 10;
final int TEST_SCALE = 5; final int TEST_SCALE = 5;
final int KEY_INTERVAL = 100; final int KEY_INTERVAL = 100;
opt = new Options(). try (final Options opt = new Options().
setCreateIfMissing(true). setCreateIfMissing(true).
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
setNumLevels(5). setNumLevels(5).
@ -625,8 +487,9 @@ public class RocksDBTest {
setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100). setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100).
setMaxBytesForLevelMultiplier(2). setMaxBytesForLevelMultiplier(2).
setDisableAutoCompactions(true); setDisableAutoCompactions(true);
db = RocksDB.open(opt, final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())
) {
// fill database with key/value pairs // fill database with key/value pairs
byte[] value = new byte[VALUE_SIZE]; byte[] value = new byte[VALUE_SIZE];
int int_key = 0; int int_key = 0;
@ -669,24 +532,12 @@ public class RocksDBTest {
db.getProperty("rocksdb.num-files-at-level2")). db.getProperty("rocksdb.num-files-at-level2")).
isEqualTo("0"); isEqualTo("0");
} }
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
@Test @Test
public void compactRangeToLevelColumnFamily() public void compactRangeToLevelColumnFamily()
throws RocksDBException { throws RocksDBException {
RocksDB db = null;
DBOptions opt = null;
List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>();
try {
final int NUM_KEYS_PER_L0_FILE = 100; final int NUM_KEYS_PER_L0_FILE = 100;
final int KEY_SIZE = 20; final int KEY_SIZE = 20;
final int VALUE_SIZE = 300; final int VALUE_SIZE = 300;
@ -695,16 +546,11 @@ public class RocksDBTest {
final int NUM_L0_FILES = 10; final int NUM_L0_FILES = 10;
final int TEST_SCALE = 5; final int TEST_SCALE = 5;
final int KEY_INTERVAL = 100; final int KEY_INTERVAL = 100;
opt = new DBOptions().
try (final DBOptions opt = new DBOptions().
setCreateIfMissing(true). setCreateIfMissing(true).
setCreateMissingColumnFamilies(true); setCreateMissingColumnFamilies(true);
List<ColumnFamilyDescriptor> columnFamilyDescriptors = final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
new ArrayList<>();
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
RocksDB.DEFAULT_COLUMN_FAMILY));
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
"new_cf".getBytes(),
new ColumnFamilyOptions().
setCompactionStyle(CompactionStyle.LEVEL). setCompactionStyle(CompactionStyle.LEVEL).
setNumLevels(5). setNumLevels(5).
// a slightly bigger write buffer than L0 file // a slightly bigger write buffer than L0 file
@ -718,12 +564,21 @@ public class RocksDBTest {
// To disable auto compaction // To disable auto compaction
setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100). setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100).
setMaxBytesForLevelMultiplier(2). setMaxBytesForLevelMultiplier(2).
setDisableAutoCompactions(true))); setDisableAutoCompactions(true)
) {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
Arrays.asList(
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
);
final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
// open database // open database
db = RocksDB.open(opt, try (final RocksDB db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath(), dbFolder.getRoot().getAbsolutePath(),
columnFamilyDescriptors, columnFamilyDescriptors,
columnFamilyHandles); columnFamilyHandles)) {
try {
// fill database with key/value pairs // fill database with key/value pairs
byte[] value = new byte[VALUE_SIZE]; byte[] value = new byte[VALUE_SIZE];
int int_key = 0; int int_key = 0;
@ -774,36 +629,24 @@ public class RocksDBTest {
isEqualTo("0"); isEqualTo("0");
} }
} finally { } finally {
for (ColumnFamilyHandle handle : columnFamilyHandles) { for (final ColumnFamilyHandle handle : columnFamilyHandles) {
handle.dispose(); handle.close();
} }
if (db != null) {
db.close();
} }
if (opt != null) {
opt.dispose();
} }
} }
} }
@Test @Test
public void enableDisableFileDeletions() throws RocksDBException { public void enableDisableFileDeletions() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
try { dbFolder.getRoot().getAbsolutePath())
options = new Options().setCreateIfMissing(true); ) {
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.disableFileDeletions(); db.disableFileDeletions();
db.enableFileDeletions(false); db.enableFileDeletions(false);
db.disableFileDeletions(); db.disableFileDeletions();
db.enableFileDeletions(true); db.enableFileDeletions(true);
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
} }
} }
} }

@ -18,7 +18,7 @@ public class RocksEnvTest {
@Test @Test
public void rocksEnv() { public void rocksEnv() {
Env rocksEnv = RocksEnv.getDefault(); try (final Env rocksEnv = RocksEnv.getDefault()) {
rocksEnv.setBackgroundThreads(5); rocksEnv.setBackgroundThreads(5);
// default rocksenv will always return zero for flush pool // default rocksenv will always return zero for flush pool
// no matter what was set via setBackgroundThreads // no matter what was set via setBackgroundThreads
@ -36,3 +36,4 @@ public class RocksEnvTest {
isEqualTo(0); isEqualTo(0);
} }
} }
}

@ -22,20 +22,15 @@ public class RocksIteratorTest {
@Test @Test
public void rocksIterator() throws RocksDBException { public void rocksIterator() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true)
RocksIterator iterator = null;
try {
options = new Options();
options.setCreateIfMissing(true)
.setCreateMissingColumnFamilies(true); .setCreateMissingColumnFamilies(true);
db = RocksDB.open(options, final RocksDB db = RocksDB.open(options,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
db.put("key1".getBytes(), "value1".getBytes()); db.put("key1".getBytes(), "value1".getBytes());
db.put("key2".getBytes(), "value2".getBytes()); db.put("key2".getBytes(), "value2".getBytes());
iterator = db.newIterator(); try (final RocksIterator iterator = db.newIterator()) {
iterator.seekToFirst(); iterator.seekToFirst();
assertThat(iterator.isValid()).isTrue(); assertThat(iterator.isValid()).isTrue();
assertThat(iterator.key()).isEqualTo("key1".getBytes()); assertThat(iterator.key()).isEqualTo("key1".getBytes());
@ -57,15 +52,6 @@ public class RocksIteratorTest {
assertThat(iterator.key()).isEqualTo("key2".getBytes()); assertThat(iterator.key()).isEqualTo("key2".getBytes());
assertThat(iterator.value()).isEqualTo("value2".getBytes()); assertThat(iterator.value()).isEqualTo("value2".getBytes());
iterator.status(); iterator.status();
} finally {
if (iterator != null) {
iterator.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }

@ -33,19 +33,14 @@ public class RocksMemEnvTest {
"baz".getBytes() "baz".getBytes()
}; };
Env env = null; try (final Env env = new RocksMemEnv();
Options options = null; final Options options = new Options()
RocksDB db = null; .setCreateIfMissing(true)
FlushOptions flushOptions = null; .setEnv(env);
try { final FlushOptions flushOptions = new FlushOptions()
env = new RocksMemEnv(); .setWaitForFlush(true);
options = new Options(). ) {
setCreateIfMissing(true). try (final RocksDB db = RocksDB.open(options, "dir/db")) {
setEnv(env);
flushOptions = new FlushOptions().
setWaitForFlush(true);
db = RocksDB.open(options, "dir/db");
// write key/value pairs using MemEnv // write key/value pairs using MemEnv
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
db.put(keys[i], values[i]); db.put(keys[i], values[i]);
@ -57,7 +52,7 @@ public class RocksMemEnvTest {
} }
// Check iterator access // Check iterator access
RocksIterator iterator = db.newIterator(); try (final RocksIterator iterator = db.newIterator()) {
iterator.seekToFirst(); iterator.seekToFirst();
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
assertThat(iterator.isValid()).isTrue(); assertThat(iterator.isValid()).isTrue();
@ -67,7 +62,7 @@ public class RocksMemEnvTest {
} }
// reached end of database // reached end of database
assertThat(iterator.isValid()).isFalse(); assertThat(iterator.isValid()).isFalse();
iterator.dispose(); }
// flush // flush
db.flush(flushOptions); db.flush(flushOptions);
@ -76,30 +71,17 @@ public class RocksMemEnvTest {
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
assertThat(db.get(keys[i])).isEqualTo(values[i]); assertThat(db.get(keys[i])).isEqualTo(values[i]);
} }
}
db.close();
options.setCreateIfMissing(false); options.setCreateIfMissing(false);
// After reopen the values shall still be in the mem env. // After reopen the values shall still be in the mem env.
// as long as the env is not freed. // as long as the env is not freed.
db = RocksDB.open(options, "dir/db"); try (final RocksDB db = RocksDB.open(options, "dir/db")) {
// read key/value pairs using MemEnv // read key/value pairs using MemEnv
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
assertThat(db.get(keys[i])).isEqualTo(values[i]); assertThat(db.get(keys[i])).isEqualTo(values[i]);
} }
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
if (flushOptions != null) {
flushOptions.dispose();
}
if (env != null) {
env.dispose();
} }
} }
} }
@ -125,18 +107,13 @@ public class RocksMemEnvTest {
"baz".getBytes() "baz".getBytes()
}; };
Env env = null; try (final Env env = new RocksMemEnv();
Options options = null; final Options options = new Options()
RocksDB db = null, otherDb = null; .setCreateIfMissing(true)
.setEnv(env);
try { final RocksDB db = RocksDB.open(options, "dir/db");
env = new RocksMemEnv(); final RocksDB otherDb = RocksDB.open(options, "dir/otherDb")
options = new Options(). ) {
setCreateIfMissing(true).
setEnv(env);
db = RocksDB.open(options, "dir/db");
otherDb = RocksDB.open(options, "dir/otherDb");
// write key/value pairs using MemEnv // write key/value pairs using MemEnv
// to db and to otherDb. // to db and to otherDb.
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
@ -154,43 +131,18 @@ public class RocksMemEnvTest {
assertThat(otherDb.get(keys[i])).isNull(); assertThat(otherDb.get(keys[i])).isNull();
assertThat(otherDb.get(otherKeys[i])).isEqualTo(values[i]); assertThat(otherDb.get(otherKeys[i])).isEqualTo(values[i]);
} }
} finally {
if (db != null) {
db.close();
}
if (otherDb != null) {
otherDb.close();
}
if (options != null) {
options.dispose();
}
if (env != null) {
env.dispose();
}
} }
} }
@Test(expected = RocksDBException.class) @Test(expected = RocksDBException.class)
public void createIfMissingFalse() throws RocksDBException { public void createIfMissingFalse() throws RocksDBException {
Env env = null; try (final Env env = new RocksMemEnv();
Options options = null; final Options options = new Options()
RocksDB db = null; .setCreateIfMissing(false)
.setEnv(env);
try { final RocksDB db = RocksDB.open(options, "db/dir")) {
env = new RocksMemEnv();
options = new Options().
setCreateIfMissing(false).
setEnv(env);
// shall throw an exception because db dir does not // shall throw an exception because db dir does not
// exist. // exist.
db = RocksDB.open(options, "db/dir");
} finally {
if (options != null) {
options.dispose();
}
if (env != null) {
env.dispose();
}
} }
} }
} }

@ -5,7 +5,11 @@ import org.junit.rules.ExternalResource;
/** /**
* Resource to trigger garbage collection after each test * Resource to trigger garbage collection after each test
* run. * run.
*
* @deprecated Will be removed with the implementation of
* {@link RocksObject#finalize()}
*/ */
@Deprecated
public class RocksMemoryResource extends ExternalResource { public class RocksMemoryResource extends ExternalResource {
static { static {

@ -17,89 +17,45 @@ public class SliceTest {
@Test @Test
public void slice() { public void slice() {
Slice slice = null; try (final Slice slice = new Slice("testSlice")) {
Slice otherSlice = null;
Slice thirdSlice = null;
try {
slice = new Slice("testSlice");
assertThat(slice.empty()).isFalse(); assertThat(slice.empty()).isFalse();
assertThat(slice.size()).isEqualTo(9); assertThat(slice.size()).isEqualTo(9);
assertThat(slice.data()).isEqualTo("testSlice".getBytes()); assertThat(slice.data()).isEqualTo("testSlice".getBytes());
}
otherSlice = new Slice("otherSlice".getBytes()); try (final Slice otherSlice = new Slice("otherSlice".getBytes())) {
assertThat(otherSlice.data()).isEqualTo("otherSlice".getBytes()); assertThat(otherSlice.data()).isEqualTo("otherSlice".getBytes());
}
thirdSlice = new Slice("otherSlice".getBytes(), 5); try (final Slice thirdSlice = new Slice("otherSlice".getBytes(), 5)) {
assertThat(thirdSlice.data()).isEqualTo("Slice".getBytes()); assertThat(thirdSlice.data()).isEqualTo("Slice".getBytes());
} finally {
if (slice != null) {
slice.dispose();
}
if (otherSlice != null) {
otherSlice.dispose();
}
if (thirdSlice != null) {
thirdSlice.dispose();
}
} }
} }
@Test @Test
public void sliceEquals() { public void sliceEquals() {
Slice slice = null; try (final Slice slice = new Slice("abc");
Slice slice2 = null; final Slice slice2 = new Slice("abc")) {
try {
slice = new Slice("abc");
slice2 = new Slice("abc");
assertThat(slice.equals(slice2)).isTrue(); assertThat(slice.equals(slice2)).isTrue();
assertThat(slice.hashCode() == slice2.hashCode()).isTrue(); assertThat(slice.hashCode() == slice2.hashCode()).isTrue();
} finally {
if (slice != null) {
slice.dispose();
}
if (slice2 != null) {
slice2.dispose();
}
} }
} }
@Test @Test
public void sliceStartWith() { public void sliceStartWith() {
Slice slice = null; try (final Slice slice = new Slice("matchpoint");
Slice match = null; final Slice match = new Slice("mat");
Slice noMatch = null; final Slice noMatch = new Slice("nomatch")) {
try { assertThat(slice.startsWith(match)).isTrue();
slice = new Slice("matchpoint");
match = new Slice("mat");
noMatch = new Slice("nomatch");
//assertThat(slice.startsWith(match)).isTrue();
assertThat(slice.startsWith(noMatch)).isFalse(); assertThat(slice.startsWith(noMatch)).isFalse();
} finally {
if (slice != null) {
slice.dispose();
}
if (match != null) {
match.dispose();
}
if (noMatch != null) {
noMatch.dispose();
}
} }
} }
@Test @Test
public void sliceToString() { public void sliceToString() {
Slice slice = null; try (final Slice slice = new Slice("stringTest")) {
try {
slice = new Slice("stringTest");
assertThat(slice.toString()).isEqualTo("stringTest"); assertThat(slice.toString()).isEqualTo("stringTest");
assertThat(slice.toString(true)).isNotEqualTo(""); assertThat(slice.toString(true)).isNotEqualTo("");
} finally {
if (slice != null) {
slice.dispose();
}
} }
} }
} }

@ -22,23 +22,18 @@ public class SnapshotTest {
@Test @Test
public void snapshots() throws RocksDBException { public void snapshots() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
ReadOptions readOptions = null; dbFolder.getRoot().getAbsolutePath())) {
try {
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
// Get new Snapshot of database // Get new Snapshot of database
Snapshot snapshot = db.getSnapshot(); try (final Snapshot snapshot = db.getSnapshot()) {
assertThat(snapshot.getSequenceNumber()).isGreaterThan(0); assertThat(snapshot.getSequenceNumber()).isGreaterThan(0);
assertThat(snapshot.getSequenceNumber()).isEqualTo(1); assertThat(snapshot.getSequenceNumber()).isEqualTo(1);
readOptions = new ReadOptions(); try (final ReadOptions readOptions = new ReadOptions()) {
// set snapshot in ReadOptions // set snapshot in ReadOptions
readOptions.setSnapshot(snapshot); readOptions.setSnapshot(snapshot);
// retrieve key value pair // retrieve key value pair
assertThat(new String(db.get("key".getBytes()))). assertThat(new String(db.get("key".getBytes()))).
isEqualTo("value"); isEqualTo("value");
@ -56,7 +51,7 @@ public class SnapshotTest {
assertThat(db.get(readOptions, "newkey".getBytes())). assertThat(db.get(readOptions, "newkey".getBytes())).
isNull(); isNull();
// Retrieve snapshot from read options // Retrieve snapshot from read options
Snapshot sameSnapshot = readOptions.snapshot(); try (final Snapshot sameSnapshot = readOptions.snapshot()) {
readOptions.setSnapshot(sameSnapshot); readOptions.setSnapshot(sameSnapshot);
// results must be the same with new Snapshot // results must be the same with new Snapshot
// instance using the same native pointer // instance using the same native pointer
@ -79,42 +74,28 @@ public class SnapshotTest {
"newkey".getBytes()))).isEqualTo("newvalue"); "newkey".getBytes()))).isEqualTo("newvalue");
// release Snapshot // release Snapshot
db.releaseSnapshot(snapshot); db.releaseSnapshot(snapshot);
} finally {
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
if (readOptions != null) {
readOptions.dispose();
} }
} }
} }
@Test @Test
public void iteratorWithSnapshot() throws RocksDBException { public void iteratorWithSnapshot() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
ReadOptions readOptions = null; dbFolder.getRoot().getAbsolutePath())) {
RocksIterator iterator = null;
RocksIterator snapshotIterator = null;
try {
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
// Get new Snapshot of database // Get new Snapshot of database
Snapshot snapshot = db.getSnapshot();
readOptions = new ReadOptions();
// set snapshot in ReadOptions // set snapshot in ReadOptions
readOptions.setSnapshot(snapshot); try (final Snapshot snapshot = db.getSnapshot();
final ReadOptions readOptions =
new ReadOptions().setSnapshot(snapshot)) {
db.put("key2".getBytes(), "value2".getBytes()); db.put("key2".getBytes(), "value2".getBytes());
// iterate over current state of db // iterate over current state of db
iterator = db.newIterator(); try (final RocksIterator iterator = db.newIterator()) {
iterator.seekToFirst(); iterator.seekToFirst();
assertThat(iterator.isValid()).isTrue(); assertThat(iterator.isValid()).isTrue();
assertThat(iterator.key()).isEqualTo("key".getBytes()); assertThat(iterator.key()).isEqualTo("key".getBytes());
@ -123,59 +104,43 @@ public class SnapshotTest {
assertThat(iterator.key()).isEqualTo("key2".getBytes()); assertThat(iterator.key()).isEqualTo("key2".getBytes());
iterator.next(); iterator.next();
assertThat(iterator.isValid()).isFalse(); assertThat(iterator.isValid()).isFalse();
}
// iterate using a snapshot // iterate using a snapshot
snapshotIterator = db.newIterator(readOptions); try (final RocksIterator snapshotIterator =
db.newIterator(readOptions)) {
snapshotIterator.seekToFirst(); snapshotIterator.seekToFirst();
assertThat(snapshotIterator.isValid()).isTrue(); assertThat(snapshotIterator.isValid()).isTrue();
assertThat(snapshotIterator.key()).isEqualTo("key".getBytes()); assertThat(snapshotIterator.key()).isEqualTo("key".getBytes());
snapshotIterator.next(); snapshotIterator.next();
assertThat(snapshotIterator.isValid()).isFalse(); assertThat(snapshotIterator.isValid()).isFalse();
}
// release Snapshot // release Snapshot
db.releaseSnapshot(snapshot); db.releaseSnapshot(snapshot);
} finally {
if (iterator != null) {
iterator.dispose();
}
if (snapshotIterator != null) {
snapshotIterator.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
if (readOptions != null) {
readOptions.dispose();
} }
} }
} }
@Test @Test
public void iteratorWithSnapshotOnColumnFamily() throws RocksDBException { public void iteratorWithSnapshotOnColumnFamily() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true);
ReadOptions readOptions = null; final RocksDB db = RocksDB.open(options,
RocksIterator iterator = null; dbFolder.getRoot().getAbsolutePath())) {
RocksIterator snapshotIterator = null;
try {
options = new Options();
options.setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.put("key".getBytes(), "value".getBytes()); db.put("key".getBytes(), "value".getBytes());
// Get new Snapshot of database // Get new Snapshot of database
Snapshot snapshot = db.getSnapshot();
readOptions = new ReadOptions();
// set snapshot in ReadOptions // set snapshot in ReadOptions
readOptions.setSnapshot(snapshot); try (final Snapshot snapshot = db.getSnapshot();
final ReadOptions readOptions = new ReadOptions()
.setSnapshot(snapshot)) {
db.put("key2".getBytes(), "value2".getBytes()); db.put("key2".getBytes(), "value2".getBytes());
// iterate over current state of column family // iterate over current state of column family
iterator = db.newIterator(db.getDefaultColumnFamily()); try (final RocksIterator iterator = db.newIterator(
db.getDefaultColumnFamily())) {
iterator.seekToFirst(); iterator.seekToFirst();
assertThat(iterator.isValid()).isTrue(); assertThat(iterator.isValid()).isTrue();
assertThat(iterator.key()).isEqualTo("key".getBytes()); assertThat(iterator.key()).isEqualTo("key".getBytes());
@ -184,10 +149,11 @@ public class SnapshotTest {
assertThat(iterator.key()).isEqualTo("key2".getBytes()); assertThat(iterator.key()).isEqualTo("key2".getBytes());
iterator.next(); iterator.next();
assertThat(iterator.isValid()).isFalse(); assertThat(iterator.isValid()).isFalse();
}
// iterate using a snapshot on default column family // iterate using a snapshot on default column family
snapshotIterator = db.newIterator(db.getDefaultColumnFamily(), try (final RocksIterator snapshotIterator = db.newIterator(
readOptions); db.getDefaultColumnFamily(), readOptions)) {
snapshotIterator.seekToFirst(); snapshotIterator.seekToFirst();
assertThat(snapshotIterator.isValid()).isTrue(); assertThat(snapshotIterator.isValid()).isTrue();
assertThat(snapshotIterator.key()).isEqualTo("key".getBytes()); assertThat(snapshotIterator.key()).isEqualTo("key".getBytes());
@ -196,21 +162,7 @@ public class SnapshotTest {
// release Snapshot // release Snapshot
db.releaseSnapshot(snapshot); db.releaseSnapshot(snapshot);
} finally {
if (iterator != null) {
iterator.dispose();
}
if (snapshotIterator != null) {
snapshotIterator.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
if (readOptions != null) {
readOptions.dispose();
} }
} }
} }

@ -26,19 +26,18 @@ public class StatisticsCollectorTest {
@Test @Test
public void statisticsCollector() public void statisticsCollector()
throws InterruptedException, RocksDBException { throws InterruptedException, RocksDBException {
Options opt = null; try (final Options opt = new Options()
RocksDB db = null; .createStatistics()
try { .setCreateIfMissing(true);
opt = new Options().createStatistics().setCreateIfMissing(true); final RocksDB db = RocksDB.open(opt,
Statistics stats = opt.statisticsPtr(); dbFolder.getRoot().getAbsolutePath())) {
final Statistics stats = opt.statisticsPtr();
db = RocksDB.open(opt,
dbFolder.getRoot().getAbsolutePath()); final StatsCallbackMock callback = new StatsCallbackMock();
final StatsCollectorInput statsInput =
StatsCallbackMock callback = new StatsCallbackMock(); new StatsCollectorInput(stats, callback);
StatsCollectorInput statsInput = new StatsCollectorInput(stats, callback);
final StatisticsCollector statsCollector = new StatisticsCollector(
StatisticsCollector statsCollector = new StatisticsCollector(
Collections.singletonList(statsInput), 100); Collections.singletonList(statsInput), 100);
statsCollector.start(); statsCollector.start();
@ -48,13 +47,6 @@ public class StatisticsCollectorTest {
assertThat(callback.histCallbackCount).isGreaterThan(0); assertThat(callback.histCallbackCount).isGreaterThan(0);
statsCollector.shutDown(1000); statsCollector.shutDown(1000);
} finally {
if (db != null) {
db.close();
}
if (opt != null) {
opt.dispose();
}
} }
} }
} }

@ -17,41 +17,25 @@ public class TransactionLogIteratorTest {
@Test @Test
public void transactionLogIterator() throws RocksDBException { public void transactionLogIterator() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true);
TransactionLogIterator transactionLogIterator = null; final RocksDB db = RocksDB.open(options,
try { dbFolder.getRoot().getAbsolutePath());
options = new Options(). final TransactionLogIterator transactionLogIterator =
setCreateIfMissing(true); db.getUpdatesSince(0)) {
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); //no-op
transactionLogIterator = db.getUpdatesSince(0);
} finally {
if (transactionLogIterator != null) {
transactionLogIterator.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void getBatch() throws RocksDBException { public void getBatch() throws RocksDBException {
final int numberOfPuts = 5; final int numberOfPuts = 5;
RocksDB db = null; try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true)
ColumnFamilyHandle cfHandle = null; .setWalTtlSeconds(1000)
TransactionLogIterator transactionLogIterator = null; .setWalSizeLimitMB(10);
try { final RocksDB db = RocksDB.open(options,
options = new Options(). dbFolder.getRoot().getAbsolutePath())) {
setCreateIfMissing(true).
setWalTtlSeconds(1000).
setWalSizeLimitMB(10);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
for (int i = 0; i < numberOfPuts; i++) { for (int i = 0; i < numberOfPuts; i++) {
db.put(String.valueOf(i).getBytes(), db.put(String.valueOf(i).getBytes(),
@ -65,9 +49,8 @@ public class TransactionLogIteratorTest {
isEqualTo(numberOfPuts); isEqualTo(numberOfPuts);
// insert 5 writes into a cf // insert 5 writes into a cf
cfHandle = db.createColumnFamily( try (final ColumnFamilyHandle cfHandle = db.createColumnFamily(
new ColumnFamilyDescriptor("new_cf".getBytes())); new ColumnFamilyDescriptor("new_cf".getBytes()))) {
for (int i = 0; i < numberOfPuts; i++) { for (int i = 0; i < numberOfPuts; i++) {
db.put(cfHandle, String.valueOf(i).getBytes(), db.put(cfHandle, String.valueOf(i).getBytes(),
String.valueOf(i).getBytes()); String.valueOf(i).getBytes());
@ -78,45 +61,34 @@ public class TransactionLogIteratorTest {
isEqualTo(numberOfPuts + numberOfPuts); isEqualTo(numberOfPuts + numberOfPuts);
// Get updates since the beginning // Get updates since the beginning
transactionLogIterator = db.getUpdatesSince(0); try (final TransactionLogIterator transactionLogIterator =
db.getUpdatesSince(0)) {
assertThat(transactionLogIterator.isValid()).isTrue(); assertThat(transactionLogIterator.isValid()).isTrue();
transactionLogIterator.status(); transactionLogIterator.status();
// The first sequence number is 1 // The first sequence number is 1
TransactionLogIterator.BatchResult batchResult = final TransactionLogIterator.BatchResult batchResult =
transactionLogIterator.getBatch(); transactionLogIterator.getBatch();
assertThat(batchResult.sequenceNumber()).isEqualTo(1); assertThat(batchResult.sequenceNumber()).isEqualTo(1);
} finally {
if (transactionLogIterator != null) {
transactionLogIterator.dispose();
} }
if (cfHandle != null) {
cfHandle.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void transactionLogIteratorStallAtLastRecord() throws RocksDBException { public void transactionLogIteratorStallAtLastRecord()
RocksDB db = null; throws RocksDBException {
Options options = null; try (final Options options = new Options()
TransactionLogIterator transactionLogIterator = null; .setCreateIfMissing(true)
try { .setWalTtlSeconds(1000)
options = new Options(). .setWalSizeLimitMB(10);
setCreateIfMissing(true). final RocksDB db = RocksDB.open(options,
setWalTtlSeconds(1000). dbFolder.getRoot().getAbsolutePath())) {
setWalSizeLimitMB(10);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.put("key1".getBytes(), "value1".getBytes()); db.put("key1".getBytes(), "value1".getBytes());
// Get updates since the beginning // Get updates since the beginning
transactionLogIterator = db.getUpdatesSince(0); try (final TransactionLogIterator transactionLogIterator =
db.getUpdatesSince(0)) {
transactionLogIterator.status(); transactionLogIterator.status();
assertThat(transactionLogIterator.isValid()).isTrue(); assertThat(transactionLogIterator.isValid()).isTrue();
transactionLogIterator.next(); transactionLogIterator.next();
@ -126,56 +98,40 @@ public class TransactionLogIteratorTest {
transactionLogIterator.next(); transactionLogIterator.next();
transactionLogIterator.status(); transactionLogIterator.status();
assertThat(transactionLogIterator.isValid()).isTrue(); assertThat(transactionLogIterator.isValid()).isTrue();
} finally {
if (transactionLogIterator != null) {
transactionLogIterator.dispose();
}
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void transactionLogIteratorCheckAfterRestart() throws RocksDBException { public void transactionLogIteratorCheckAfterRestart()
throws RocksDBException {
final int numberOfKeys = 2; final int numberOfKeys = 2;
RocksDB db = null; try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true)
TransactionLogIterator transactionLogIterator = null; .setWalTtlSeconds(1000)
try { .setWalSizeLimitMB(10)) {
options = new Options().
setCreateIfMissing(true). try (final RocksDB db = RocksDB.open(options,
setWalTtlSeconds(1000). dbFolder.getRoot().getAbsolutePath())) {
setWalSizeLimitMB(10);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
db.put("key1".getBytes(), "value1".getBytes()); db.put("key1".getBytes(), "value1".getBytes());
db.put("key2".getBytes(), "value2".getBytes()); db.put("key2".getBytes(), "value2".getBytes());
db.flush(new FlushOptions().setWaitForFlush(true)); db.flush(new FlushOptions().setWaitForFlush(true));
}
// reopen // reopen
db.close(); try (final RocksDB db = RocksDB.open(options,
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath())) {
assertThat(db.getLatestSequenceNumber()).isEqualTo(numberOfKeys); assertThat(db.getLatestSequenceNumber()).isEqualTo(numberOfKeys);
transactionLogIterator = db.getUpdatesSince(0); try (final TransactionLogIterator transactionLogIterator =
db.getUpdatesSince(0)) {
for (int i = 0; i < numberOfKeys; i++) { for (int i = 0; i < numberOfKeys; i++) {
transactionLogIterator.status(); transactionLogIterator.status();
assertThat(transactionLogIterator.isValid()).isTrue(); assertThat(transactionLogIterator.isValid()).isTrue();
transactionLogIterator.next(); transactionLogIterator.next();
} }
} finally {
if (transactionLogIterator != null) {
transactionLogIterator.dispose();
}
if (db != null) {
db.close();
} }
if (options != null) {
options.dispose();
} }
} }
} }

@ -11,6 +11,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -26,81 +27,54 @@ public class TtlDBTest {
public TemporaryFolder dbFolder = new TemporaryFolder(); public TemporaryFolder dbFolder = new TemporaryFolder();
@Test @Test
public void ttlDBOpen() throws RocksDBException, public void ttlDBOpen() throws RocksDBException, InterruptedException {
InterruptedException { try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true)
TtlDB ttlDB = null; .setMaxGrandparentOverlapFactor(0);
try { final TtlDB ttlDB = TtlDB.open(options,
options = new Options(). dbFolder.getRoot().getAbsolutePath())
setCreateIfMissing(true). ) {
setMaxGrandparentOverlapFactor(0);
ttlDB = TtlDB.open(options,
dbFolder.getRoot().getAbsolutePath());
ttlDB.put("key".getBytes(), "value".getBytes()); ttlDB.put("key".getBytes(), "value".getBytes());
assertThat(ttlDB.get("key".getBytes())). assertThat(ttlDB.get("key".getBytes())).
isEqualTo("value".getBytes()); isEqualTo("value".getBytes());
assertThat(ttlDB.get("key".getBytes())).isNotNull(); assertThat(ttlDB.get("key".getBytes())).isNotNull();
} finally {
if (ttlDB != null) {
ttlDB.close();
}
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void ttlDBOpenWithTtl() throws RocksDBException, public void ttlDBOpenWithTtl() throws RocksDBException, InterruptedException {
InterruptedException { try (final Options options = new Options()
Options options = null; .setCreateIfMissing(true)
TtlDB ttlDB = null; .setMaxGrandparentOverlapFactor(0);
try { final TtlDB ttlDB = TtlDB.open(options,
options = new Options(). dbFolder.getRoot().getAbsolutePath(), 1, false);
setCreateIfMissing(true). ) {
setMaxGrandparentOverlapFactor(0);
ttlDB = TtlDB.open(options, dbFolder.getRoot().getAbsolutePath(),
1, false);
ttlDB.put("key".getBytes(), "value".getBytes()); ttlDB.put("key".getBytes(), "value".getBytes());
assertThat(ttlDB.get("key".getBytes())). assertThat(ttlDB.get("key".getBytes())).
isEqualTo("value".getBytes()); isEqualTo("value".getBytes());
TimeUnit.SECONDS.sleep(2); TimeUnit.SECONDS.sleep(2);
ttlDB.compactRange(); ttlDB.compactRange();
assertThat(ttlDB.get("key".getBytes())).isNull(); assertThat(ttlDB.get("key".getBytes())).isNull();
} finally {
if (ttlDB != null) {
ttlDB.close();
}
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void ttlDbOpenWithColumnFamilies() throws RocksDBException, InterruptedException { public void ttlDbOpenWithColumnFamilies() throws RocksDBException,
DBOptions dbOptions = null; InterruptedException {
TtlDB ttlDB = null; final List<ColumnFamilyDescriptor> cfNames = Arrays.asList(
List<ColumnFamilyDescriptor> cfNames = new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ArrayList<>(); new ColumnFamilyDescriptor("new_cf".getBytes())
List<ColumnFamilyHandle> columnFamilyHandleList = );
new ArrayList<>(); final List<Integer> ttlValues = Arrays.asList(0, 1);
cfNames.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
cfNames.add(new ColumnFamilyDescriptor("new_cf".getBytes())); final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
List<Integer> ttlValues = new ArrayList<>(); try (final DBOptions dbOptions = new DBOptions()
// Default column family with infinite lifetime .setCreateMissingColumnFamilies(true)
ttlValues.add(0); .setCreateIfMissing(true);
// new column family with 1 second ttl final TtlDB ttlDB = TtlDB.open(dbOptions,
ttlValues.add(1); dbFolder.getRoot().getAbsolutePath(), cfNames,
columnFamilyHandleList, ttlValues, false)) {
try { try {
dbOptions = new DBOptions().
setCreateMissingColumnFamilies(true).
setCreateIfMissing(true);
ttlDB = TtlDB.open(dbOptions, dbFolder.getRoot().getAbsolutePath(),
cfNames, columnFamilyHandleList, ttlValues, false);
ttlDB.put("key".getBytes(), "value".getBytes()); ttlDB.put("key".getBytes(), "value".getBytes());
assertThat(ttlDB.get("key".getBytes())). assertThat(ttlDB.get("key".getBytes())).
isEqualTo("value".getBytes()); isEqualTo("value".getBytes());
@ -116,18 +90,11 @@ public class TtlDBTest {
assertThat(ttlDB.get("key".getBytes())).isNotNull(); assertThat(ttlDB.get("key".getBytes())).isNotNull();
assertThat(ttlDB.get(columnFamilyHandleList.get(1), assertThat(ttlDB.get(columnFamilyHandleList.get(1),
"key".getBytes())).isNull(); "key".getBytes())).isNull();
} finally { } finally {
for (ColumnFamilyHandle columnFamilyHandle : for (final ColumnFamilyHandle columnFamilyHandle :
columnFamilyHandleList) { columnFamilyHandleList) {
columnFamilyHandle.dispose(); columnFamilyHandle.close();
}
if (ttlDB != null) {
ttlDB.close();
} }
if (dbOptions != null) {
dbOptions.dispose();
} }
} }
} }
@ -135,15 +102,12 @@ public class TtlDBTest {
@Test @Test
public void createTtlColumnFamily() throws RocksDBException, public void createTtlColumnFamily() throws RocksDBException,
InterruptedException { InterruptedException {
Options options = null; try (final Options options = new Options().setCreateIfMissing(true);
TtlDB ttlDB = null; final TtlDB ttlDB = TtlDB.open(options,
ColumnFamilyHandle columnFamilyHandle = null;
try {
options = new Options().setCreateIfMissing(true);
ttlDB = TtlDB.open(options,
dbFolder.getRoot().getAbsolutePath()); dbFolder.getRoot().getAbsolutePath());
columnFamilyHandle = ttlDB.createColumnFamilyWithTtl( final ColumnFamilyHandle columnFamilyHandle =
new ColumnFamilyDescriptor("new_cf".getBytes()), 1); ttlDB.createColumnFamilyWithTtl(
new ColumnFamilyDescriptor("new_cf".getBytes()), 1)) {
ttlDB.put(columnFamilyHandle, "key".getBytes(), ttlDB.put(columnFamilyHandle, "key".getBytes(),
"value".getBytes()); "value".getBytes());
assertThat(ttlDB.get(columnFamilyHandle, "key".getBytes())). assertThat(ttlDB.get(columnFamilyHandle, "key".getBytes())).
@ -151,16 +115,6 @@ public class TtlDBTest {
TimeUnit.SECONDS.sleep(2); TimeUnit.SECONDS.sleep(2);
ttlDB.compactRange(columnFamilyHandle); ttlDB.compactRange(columnFamilyHandle);
assertThat(ttlDB.get(columnFamilyHandle, "key".getBytes())).isNull(); assertThat(ttlDB.get(columnFamilyHandle, "key".getBytes())).isNull();
} finally {
if (columnFamilyHandle != null) {
columnFamilyHandle.dispose();
}
if (ttlDB != null) {
ttlDB.close();
}
if (options != null) {
options.dispose();
}
} }
} }
} }

@ -23,28 +23,26 @@ public class WriteBatchHandlerTest {
@Test @Test
public void writeBatchHandler() throws IOException, RocksDBException { public void writeBatchHandler() throws IOException, RocksDBException {
WriteBatch batch = null;
CapturingWriteBatchHandler handler = null;
try {
// setup test data // setup test data
final List<Tuple<Action, Tuple<byte[], byte[]>>> testEvents = new ArrayList<>(); final List<Tuple<Action, Tuple<byte[], byte[]>>> testEvents = Arrays.asList(
testEvents.add(new Tuple<>(Action.DELETE, new Tuple<>(Action.DELETE,
new Tuple<byte[], byte[]>("k0".getBytes(), null))); new Tuple<byte[], byte[]>("k0".getBytes(), null)),
testEvents.add(new Tuple<>(Action.PUT, new Tuple<>(Action.PUT,
new Tuple<>("k1".getBytes(), "v1".getBytes()))); new Tuple<>("k1".getBytes(), "v1".getBytes())),
testEvents.add(new Tuple<>(Action.PUT, new Tuple<>(Action.PUT,
new Tuple<>("k2".getBytes(), "v2".getBytes()))); new Tuple<>("k2".getBytes(), "v2".getBytes())),
testEvents.add(new Tuple<>(Action.PUT, new Tuple<>(Action.PUT,
new Tuple<>("k3".getBytes(), "v3".getBytes()))); new Tuple<>("k3".getBytes(), "v3".getBytes())),
testEvents.add(new Tuple<>(Action.LOG, new Tuple<>(Action.LOG,
new Tuple<byte[], byte[]>(null, "log1".getBytes()))); new Tuple<byte[], byte[]>(null, "log1".getBytes())),
testEvents.add(new Tuple<>(Action.MERGE, new Tuple<>(Action.MERGE,
new Tuple<>("k2".getBytes(), "v22".getBytes()))); new Tuple<>("k2".getBytes(), "v22".getBytes())),
testEvents.add(new Tuple<>(Action.DELETE, new Tuple<>(Action.DELETE,
new Tuple<byte[], byte[]>("k3".getBytes(), null))); new Tuple<byte[], byte[]>("k3".getBytes(), null))
);
// load test data to the write batch // load test data to the write batch
batch = new WriteBatch(); try (final WriteBatch batch = new WriteBatch()) {
for (final Tuple<Action, Tuple<byte[], byte[]>> testEvent : testEvents) { for (final Tuple<Action, Tuple<byte[], byte[]>> testEvent : testEvents) {
final Tuple<byte[], byte[]> data = testEvent.value; final Tuple<byte[], byte[]> data = testEvent.value;
switch (testEvent.key) { switch (testEvent.key) {
@ -67,28 +65,26 @@ public class WriteBatchHandlerTest {
} }
} }
// attempt to read test data back from the WriteBatch by iterating with a handler // attempt to read test data back from the WriteBatch by iterating
handler = new CapturingWriteBatchHandler(); // with a handler
try (final CapturingWriteBatchHandler handler =
new CapturingWriteBatchHandler()) {
batch.iterate(handler); batch.iterate(handler);
// compare the results to the test data // compare the results to the test data
final List<Tuple<Action, Tuple<byte[], byte[]>>> actualEvents = handler.getEvents(); final List<Tuple<Action, Tuple<byte[], byte[]>>> actualEvents =
handler.getEvents();
assertThat(testEvents.size()).isSameAs(actualEvents.size()); assertThat(testEvents.size()).isSameAs(actualEvents.size());
for (int i = 0; i < testEvents.size(); i++) { for (int i = 0; i < testEvents.size(); i++) {
assertThat(equals(testEvents.get(i), actualEvents.get(i))).isTrue(); assertThat(equals(testEvents.get(i), actualEvents.get(i))).isTrue();
} }
} finally {
if (handler != null) {
handler.dispose();
}
if (batch != null) {
batch.dispose();
} }
} }
} }
private static boolean equals(final Tuple<Action, Tuple<byte[], byte[]>> expected, private static boolean equals(
final Tuple<Action, Tuple<byte[], byte[]>> expected,
final Tuple<Action, Tuple<byte[], byte[]>> actual) { final Tuple<Action, Tuple<byte[], byte[]>> actual) {
if (!expected.key.equals(actual.key)) { if (!expected.key.equals(actual.key)) {
return false; return false;
@ -136,7 +132,8 @@ public class WriteBatchHandlerTest {
*/ */
private static class CapturingWriteBatchHandler extends WriteBatch.Handler { private static class CapturingWriteBatchHandler extends WriteBatch.Handler {
private final List<Tuple<Action, Tuple<byte[], byte[]>>> events = new ArrayList<>(); private final List<Tuple<Action, Tuple<byte[], byte[]>>> events
= new ArrayList<>();
/** /**
* Returns a copy of the current events list * Returns a copy of the current events list
@ -159,12 +156,14 @@ public class WriteBatchHandlerTest {
@Override @Override
public void delete(final byte[] key) { public void delete(final byte[] key) {
events.add(new Tuple<>(Action.DELETE, new Tuple<byte[], byte[]>(key, null))); events.add(new Tuple<>(Action.DELETE,
new Tuple<byte[], byte[]>(key, null)));
} }
@Override @Override
public void logData(final byte[] blob) { public void logData(final byte[] blob) {
events.add(new Tuple<>(Action.LOG, new Tuple<byte[], byte[]>(null, blob))); events.add(new Tuple<>(Action.LOG,
new Tuple<byte[], byte[]>(null, blob)));
} }
} }
} }

@ -20,9 +20,9 @@ import static org.assertj.core.api.Assertions.assertThat;
/** /**
* This class mimics the db/write_batch_test.cc * This class mimics the db/write_batch_test.cc
* in the c++ rocksdb library. * in the c++ rocksdb library.
* * <p/>
* Not ported yet: * Not ported yet:
* * <p/>
* Continue(); * Continue();
* PutGatherSlices(); * PutGatherSlices();
*/ */
@ -36,17 +36,19 @@ public class WriteBatchTest {
@Test @Test
public void emptyWriteBatch() { public void emptyWriteBatch() {
WriteBatch batch = new WriteBatch(); try (final WriteBatch batch = new WriteBatch()) {
assertThat(batch.count()).isEqualTo(0); assertThat(batch.count()).isEqualTo(0);
} }
}
@Test @Test
public void multipleBatchOperations() public void multipleBatchOperations()
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
WriteBatch batch = new WriteBatch(); try (WriteBatch batch = new WriteBatch()) {
batch.put("foo".getBytes("US-ASCII"), "bar".getBytes("US-ASCII")); batch.put("foo".getBytes("US-ASCII"), "bar".getBytes("US-ASCII"));
batch.remove("box".getBytes("US-ASCII")); batch.remove("box".getBytes("US-ASCII"));
batch.put("baz".getBytes("US-ASCII"), "boo".getBytes("US-ASCII")); batch.put("baz".getBytes("US-ASCII"), "boo".getBytes("US-ASCII"));
WriteBatchTestInternalHelper.setSequence(batch, 100); WriteBatchTestInternalHelper.setSequence(batch, 100);
assertThat(WriteBatchTestInternalHelper.sequence(batch)). assertThat(WriteBatchTestInternalHelper.sequence(batch)).
isNotNull(). isNotNull().
@ -57,12 +59,13 @@ public class WriteBatchTest {
"Delete(box)@101" + "Delete(box)@101" +
"Put(foo, bar)@100"); "Put(foo, bar)@100");
} }
}
@Test @Test
public void testAppendOperation() public void testAppendOperation()
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
WriteBatch b1 = new WriteBatch(); try (final WriteBatch b1 = new WriteBatch();
WriteBatch b2 = new WriteBatch(); final WriteBatch b2 = new WriteBatch()) {
WriteBatchTestInternalHelper.setSequence(b1, 200); WriteBatchTestInternalHelper.setSequence(b1, 200);
WriteBatchTestInternalHelper.setSequence(b2, 300); WriteBatchTestInternalHelper.setSequence(b2, 300);
WriteBatchTestInternalHelper.append(b1, b2); WriteBatchTestInternalHelper.append(b1, b2);
@ -70,7 +73,8 @@ public class WriteBatchTest {
assertThat(b1.count()).isEqualTo(0); assertThat(b1.count()).isEqualTo(0);
b2.put("a".getBytes("US-ASCII"), "va".getBytes("US-ASCII")); b2.put("a".getBytes("US-ASCII"), "va".getBytes("US-ASCII"));
WriteBatchTestInternalHelper.append(b1, b2); WriteBatchTestInternalHelper.append(b1, b2);
assertThat("Put(a, va)@200".equals(new String(getContents(b1), "US-ASCII"))); assertThat("Put(a, va)@200".equals(new String(getContents(b1),
"US-ASCII")));
assertThat(b1.count()).isEqualTo(1); assertThat(b1.count()).isEqualTo(1);
b2.clear(); b2.clear();
b2.put("b".getBytes("US-ASCII"), "vb".getBytes("US-ASCII")); b2.put("b".getBytes("US-ASCII"), "vb".getBytes("US-ASCII"));
@ -88,11 +92,12 @@ public class WriteBatchTest {
.equals(new String(getContents(b1), "US-ASCII"))); .equals(new String(getContents(b1), "US-ASCII")));
assertThat(b1.count()).isEqualTo(4); assertThat(b1.count()).isEqualTo(4);
} }
}
@Test @Test
public void blobOperation() public void blobOperation()
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
WriteBatch batch = new WriteBatch(); try (final WriteBatch batch = new WriteBatch()) {
batch.put("k1".getBytes("US-ASCII"), "v1".getBytes("US-ASCII")); batch.put("k1".getBytes("US-ASCII"), "v1".getBytes("US-ASCII"));
batch.put("k2".getBytes("US-ASCII"), "v2".getBytes("US-ASCII")); batch.put("k2".getBytes("US-ASCII"), "v2".getBytes("US-ASCII"));
batch.put("k3".getBytes("US-ASCII"), "v3".getBytes("US-ASCII")); batch.put("k3".getBytes("US-ASCII"), "v3".getBytes("US-ASCII"));
@ -108,8 +113,13 @@ public class WriteBatchTest {
"Put(k3, v3)@2") "Put(k3, v3)@2")
.equals(new String(getContents(batch), "US-ASCII"))); .equals(new String(getContents(batch), "US-ASCII")));
} }
}
static byte[] getContents(final WriteBatch wb) {
return getContents(wb.nativeHandle_);
}
static native byte[] getContents(WriteBatch batch); private static native byte[] getContents(final long writeBatchHandle);
} }
/** /**
@ -117,7 +127,23 @@ public class WriteBatchTest {
* c++ WriteBatchInternal. * c++ WriteBatchInternal.
*/ */
class WriteBatchTestInternalHelper { class WriteBatchTestInternalHelper {
static native void setSequence(WriteBatch batch, long sn); static void setSequence(final WriteBatch wb, final long sn) {
static native long sequence(WriteBatch batch); setSequence(wb.nativeHandle_, sn);
static native void append(WriteBatch b1, WriteBatch b2); }
static long sequence(final WriteBatch wb) {
return sequence(wb.nativeHandle_);
}
static void append(final WriteBatch wb1, final WriteBatch wb2) {
append(wb1.nativeHandle_, wb2.nativeHandle_);
}
private static native void setSequence(final long writeBatchHandle,
final long sn);
private static native long sequence(final long writeBatchHandle);
private static native void append(final long writeBatchHandle1,
final long writeBatchHandle2);
} }

@ -32,13 +32,9 @@ public class WriteBatchWithIndexTest {
@Test @Test
public void readYourOwnWrites() throws RocksDBException { public void readYourOwnWrites() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
try { dbFolder.getRoot().getAbsolutePath())) {
options = new Options();
// Setup options
options.setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
final byte[] k1 = "key1".getBytes(); final byte[] k1 = "key1".getBytes();
final byte[] v1 = "value1".getBytes(); final byte[] v1 = "value1".getBytes();
@ -48,13 +44,9 @@ public class WriteBatchWithIndexTest {
db.put(k1, v1); db.put(k1, v1);
db.put(k2, v2); db.put(k2, v2);
final WriteBatchWithIndex wbwi = new WriteBatchWithIndex(true); try (final WriteBatchWithIndex wbwi = new WriteBatchWithIndex(true);
final RocksIterator base = db.newIterator();
RocksIterator base = null; final RocksIterator it = wbwi.newIteratorWithBase(base)) {
RocksIterator it = null;
try {
base = db.newIterator();
it = wbwi.newIteratorWithBase(base);
it.seek(k1); it.seek(k1);
assertThat(it.isValid()).isTrue(); assertThat(it.isValid()).isTrue();
@ -95,72 +87,36 @@ public class WriteBatchWithIndexTest {
assertThat(it.isValid()).isTrue(); assertThat(it.isValid()).isTrue();
assertThat(it.key()).isEqualTo(k1); assertThat(it.key()).isEqualTo(k1);
assertThat(it.value()).isEqualTo(v1Other); assertThat(it.value()).isEqualTo(v1Other);
} finally {
if (it != null) {
it.dispose();
}
if (base != null) {
base.dispose();
}
}
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
} }
} }
} }
@Test @Test
public void write_writeBatchWithIndex() throws RocksDBException { public void write_writeBatchWithIndex() throws RocksDBException {
RocksDB db = null; try (final Options options = new Options().setCreateIfMissing(true);
Options options = null; final RocksDB db = RocksDB.open(options,
try { dbFolder.getRoot().getAbsolutePath())) {
options = new Options();
// Setup options
options.setCreateIfMissing(true);
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());
final byte[] k1 = "key1".getBytes(); final byte[] k1 = "key1".getBytes();
final byte[] v1 = "value1".getBytes(); final byte[] v1 = "value1".getBytes();
final byte[] k2 = "key2".getBytes(); final byte[] k2 = "key2".getBytes();
final byte[] v2 = "value2".getBytes(); final byte[] v2 = "value2".getBytes();
WriteBatchWithIndex wbwi = null; try (final WriteBatchWithIndex wbwi = new WriteBatchWithIndex()) {
try {
wbwi = new WriteBatchWithIndex();
wbwi.put(k1, v1); wbwi.put(k1, v1);
wbwi.put(k2, v2); wbwi.put(k2, v2);
db.write(new WriteOptions(), wbwi); db.write(new WriteOptions(), wbwi);
} finally {
if(wbwi != null) {
wbwi.dispose();
}
} }
assertThat(db.get(k1)).isEqualTo(v1); assertThat(db.get(k1)).isEqualTo(v1);
assertThat(db.get(k2)).isEqualTo(v2); assertThat(db.get(k2)).isEqualTo(v2);
} finally {
if (db != null) {
db.close();
}
if (options != null) {
options.dispose();
}
} }
} }
@Test @Test
public void iterator() throws RocksDBException { public void iterator() throws RocksDBException {
final WriteBatchWithIndex wbwi = new WriteBatchWithIndex(true); try (final WriteBatchWithIndex wbwi = new WriteBatchWithIndex(true)) {
final String k1 = "key1"; final String k1 = "key1";
final String v1 = "value1"; final String v1 = "value1";
@ -185,7 +141,7 @@ public class WriteBatchWithIndexTest {
final byte[] k4b = k4.getBytes(); final byte[] k4b = k4.getBytes();
wbwi.remove(k4b); wbwi.remove(k4b);
WBWIRocksIterator.WriteEntry[] expected = { final WBWIRocksIterator.WriteEntry[] expected = {
new WBWIRocksIterator.WriteEntry(WBWIRocksIterator.WriteType.PUT, new WBWIRocksIterator.WriteEntry(WBWIRocksIterator.WriteType.PUT,
new DirectSlice(k1), new DirectSlice(v1)), new DirectSlice(k1), new DirectSlice(v1)),
new WBWIRocksIterator.WriteEntry(WBWIRocksIterator.WriteType.PUT, new WBWIRocksIterator.WriteEntry(WBWIRocksIterator.WriteType.PUT,
@ -196,10 +152,7 @@ public class WriteBatchWithIndexTest {
new DirectSlice(k4), DirectSlice.NONE) new DirectSlice(k4), DirectSlice.NONE)
}; };
WBWIRocksIterator it = null; try (final WBWIRocksIterator it = wbwi.newIterator()) {
try {
it = wbwi.newIterator();
//direct access - seek to key offsets //direct access - seek to key offsets
final int[] testOffsets = {2, 0, 1, 3}; final int[] testOffsets = {2, 0, 1, 3};
@ -209,7 +162,9 @@ public class WriteBatchWithIndexTest {
it.seek(key); it.seek(key);
assertThat(it.isValid()).isTrue(); assertThat(it.isValid()).isTrue();
assertThat(it.entry().equals(expected[testOffset])).isTrue();
final WBWIRocksIterator.WriteEntry entry = it.entry();
assertThat(entry.equals(expected[testOffset])).isTrue();
} }
//forward iterative access //forward iterative access
@ -223,23 +178,18 @@ public class WriteBatchWithIndexTest {
for (it.seekToLast(); it.isValid(); it.prev()) { for (it.seekToLast(); it.isValid(); it.prev()) {
assertThat(it.entry().equals(expected[i--])).isTrue(); assertThat(it.entry().equals(expected[i--])).isTrue();
} }
} finally {
if(it != null) {
it.dispose();
} }
} }
} }
@Test @Test
public void zeroByteTests() { public void zeroByteTests() {
final WriteBatchWithIndex wbwi = new WriteBatchWithIndex(true); try (final WriteBatchWithIndex wbwi = new WriteBatchWithIndex(true)) {
byte[] zeroByteValue = new byte[] { 0, 0 }; final byte[] zeroByteValue = new byte[]{0, 0};
//add zero byte value //add zero byte value
wbwi.put(zeroByteValue, zeroByteValue); wbwi.put(zeroByteValue, zeroByteValue);
ByteBuffer buffer = ByteBuffer.allocateDirect(zeroByteValue.length); final ByteBuffer buffer = ByteBuffer.allocateDirect(zeroByteValue.length);
buffer.put(zeroByteValue); buffer.put(zeroByteValue);
WBWIRocksIterator.WriteEntry[] expected = { WBWIRocksIterator.WriteEntry[] expected = {
@ -247,15 +197,11 @@ public class WriteBatchWithIndexTest {
new DirectSlice(buffer, zeroByteValue.length), new DirectSlice(buffer, zeroByteValue.length),
new DirectSlice(buffer, zeroByteValue.length)) new DirectSlice(buffer, zeroByteValue.length))
}; };
WBWIRocksIterator it = null;
try { try (final WBWIRocksIterator it = wbwi.newIterator()) {
it = wbwi.newIterator();
it.seekToFirst(); it.seekToFirst();
assertThat(it.entry().equals(expected[0])).isTrue(); assertThat(it.entry().equals(expected[0])).isTrue();
assertThat(it.entry().hashCode() == expected[0].hashCode()).isTrue(); assertThat(it.entry().hashCode() == expected[0].hashCode()).isTrue();
} finally {
if(it != null) {
it.dispose();
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save