From 7260662b399d8d70c658261c8c6b595889b864a3 Mon Sep 17 00:00:00 2001 From: Injun Song Date: Fri, 30 Sep 2016 06:04:41 +0900 Subject: [PATCH] Add Java API for SstFileWriter Add Java API for SstFileWriter. Closes https://github.com/facebook/rocksdb/issues/1248 --- java/CMakeLists.txt | 6 + java/Makefile | 6 + java/rocksjni/env_options.cc | 315 ++++++++++++++++++ java/rocksjni/external_sst_file_info.cc | 242 ++++++++++++++ java/rocksjni/rocksjni.cc | 72 ++++ java/rocksjni/sst_file_writerjni.cc | 94 ++++++ .../src/main/java/org/rocksdb/EnvOptions.java | 207 ++++++++++++ .../java/org/rocksdb/ExternalSstFileInfo.java | 135 ++++++++ java/src/main/java/org/rocksdb/RocksDB.java | 118 ++++++- .../main/java/org/rocksdb/SstFileWriter.java | 46 +++ .../test/java/org/rocksdb/EnvOptionsTest.java | 142 ++++++++ .../org/rocksdb/ExternalSstFileInfoTest.java | 105 ++++++ .../java/org/rocksdb/SstFileWriterTest.java | 84 +++++ src.mk | 3 + 14 files changed, 1570 insertions(+), 5 deletions(-) create mode 100644 java/rocksjni/env_options.cc create mode 100644 java/rocksjni/external_sst_file_info.cc create mode 100644 java/rocksjni/sst_file_writerjni.cc create mode 100644 java/src/main/java/org/rocksdb/EnvOptions.java create mode 100644 java/src/main/java/org/rocksdb/ExternalSstFileInfo.java create mode 100644 java/src/main/java/org/rocksdb/SstFileWriter.java create mode 100644 java/src/test/java/org/rocksdb/EnvOptionsTest.java create mode 100644 java/src/test/java/org/rocksdb/ExternalSstFileInfoTest.java create mode 100644 java/src/test/java/org/rocksdb/SstFileWriterTest.java diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index 35b68307c..623897753 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -9,6 +9,8 @@ set(JNI_NATIVE_SOURCES rocksjni/comparator.cc rocksjni/comparatorjnicallback.cc rocksjni/env.cc + rocksjni/env_options.cc + rocksjni/external_sst_file_info.cc rocksjni/filter.cc rocksjni/iterator.cc rocksjni/loggerjnicallback.cc @@ -21,6 +23,7 @@ set(JNI_NATIVE_SOURCES rocksjni/rocksjni.cc rocksjni/slice.cc rocksjni/snapshot.cc + rocksjni/sst_file_writerjni.cc rocksjni/statistics.cc rocksjni/table.cc rocksjni/transaction_log.cc @@ -49,6 +52,8 @@ set(NATIVE_JAVA_CLASSES org.rocksdb.DirectComparator org.rocksdb.DirectSlice org.rocksdb.Env + org.rocksdb.EnvOptions + org.rocksdb.ExternalSstFileInfo org.rocksdb.FlushOptions org.rocksdb.Filter org.rocksdb.GenericRateLimiterConfig @@ -68,6 +73,7 @@ set(NATIVE_JAVA_CLASSES org.rocksdb.RocksMemEnv org.rocksdb.SkipListMemTableConfig org.rocksdb.Slice + org.rocksdb.SstFileWriter org.rocksdb.Statistics org.rocksdb.TransactionLogIterator org.rocksdb.TtlDB diff --git a/java/Makefile b/java/Makefile index 8f90a4ba9..2471b02f7 100644 --- a/java/Makefile +++ b/java/Makefile @@ -14,6 +14,8 @@ NATIVE_JAVA_CLASSES = org.rocksdb.AbstractCompactionFilter\ org.rocksdb.DirectComparator\ org.rocksdb.DirectSlice\ org.rocksdb.Env\ + org.rocksdb.EnvOptions\ + org.rocksdb.ExternalSstFileInfo\ org.rocksdb.FlushOptions\ org.rocksdb.Filter\ org.rocksdb.GenericRateLimiterConfig\ @@ -32,6 +34,7 @@ NATIVE_JAVA_CLASSES = org.rocksdb.AbstractCompactionFilter\ org.rocksdb.RocksMemEnv\ org.rocksdb.SkipListMemTableConfig\ org.rocksdb.Slice\ + org.rocksdb.SstFileWriter\ org.rocksdb.Statistics\ org.rocksdb.TransactionLogIterator\ org.rocksdb.TtlDB\ @@ -72,6 +75,8 @@ JAVA_TESTS = org.rocksdb.BackupableDBOptionsTest\ org.rocksdb.DBOptionsTest\ org.rocksdb.DirectComparatorTest\ org.rocksdb.DirectSliceTest\ + org.rocksdb.EnvOptionsTest\ + org.rocksdb.ExternalSstFileInfoTest\ org.rocksdb.util.EnvironmentTest\ org.rocksdb.FilterTest\ org.rocksdb.FlushTest\ @@ -95,6 +100,7 @@ JAVA_TESTS = org.rocksdb.BackupableDBOptionsTest\ org.rocksdb.util.SizeUnitTest\ org.rocksdb.SliceTest\ org.rocksdb.SnapshotTest\ + org.rocksdb.SstFileWriterTest\ org.rocksdb.TransactionLogIteratorTest\ org.rocksdb.TtlDBTest\ org.rocksdb.StatisticsCollectorTest\ diff --git a/java/rocksjni/env_options.cc b/java/rocksjni/env_options.cc new file mode 100644 index 000000000..0618ad33d --- /dev/null +++ b/java/rocksjni/env_options.cc @@ -0,0 +1,315 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. +// +// This file implements the "bridge" between Java and C++ and enables +// calling c++ rocksdb::BackupableDB and rocksdb::BackupableDBOptions methods +// from Java side. + +#include + +#include "include/org_rocksdb_EnvOptions.h" +#include "rocksdb/env.h" + +#define ENV_OPTIONS_SET_BOOL(_jhandle, _opt) \ + reinterpret_cast(_jhandle)->_opt = \ + static_cast(_opt) + +#define ENV_OPTIONS_SET_SIZE_T(_jhandle, _opt) \ + reinterpret_cast(_jhandle)->_opt = \ + static_cast(_opt) + +#define ENV_OPTIONS_SET_UINT64_T(_jhandle, _opt) \ + reinterpret_cast(_jhandle)->_opt = \ + static_cast(_opt) + +#define ENV_OPTIONS_GET(_jhandle, _opt) \ + reinterpret_cast(_jhandle)->_opt + +/* + * Class: org_rocksdb_EnvOptions + * Method: newEnvOptions + * Signature: ()J + */ +jlong Java_org_rocksdb_EnvOptions_newEnvOptions(JNIEnv *env, jclass jcls) { + auto *env_opt = new rocksdb::EnvOptions(); + return reinterpret_cast(env_opt); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: disposeInternal + * Signature: (J)V + */ +void Java_org_rocksdb_EnvOptions_disposeInternal(JNIEnv *env, jobject jobj, + jlong jhandle) { + delete reinterpret_cast(jhandle); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setUseOsBuffer + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setUseOsBuffer(JNIEnv *env, jobject jobj, + jlong jhandle, + jboolean use_os_buffer) { + ENV_OPTIONS_SET_BOOL(jhandle, use_os_buffer); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: useOsBuffer + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_useOsBuffer(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, use_os_buffer); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setUseMmapReads + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setUseMmapReads(JNIEnv *env, jobject jobj, + jlong jhandle, + jboolean use_mmap_reads) { + ENV_OPTIONS_SET_BOOL(jhandle, use_mmap_reads); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: useMmapReads + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_useMmapReads(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, use_mmap_reads); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setUseMmapWrites + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setUseMmapWrites(JNIEnv *env, jobject jobj, + jlong jhandle, + jboolean use_mmap_writes) { + ENV_OPTIONS_SET_BOOL(jhandle, use_mmap_writes); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: useMmapWrites + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_useMmapWrites(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, use_mmap_writes); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setUseDirectReads + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setUseDirectReads(JNIEnv *env, jobject jobj, + jlong jhandle, + jboolean use_direct_reads) { + ENV_OPTIONS_SET_BOOL(jhandle, use_direct_reads); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: useDirectReads + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_useDirectReads(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, use_direct_reads); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setUseDirectWrites + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setUseDirectWrites( + JNIEnv *env, jobject jobj, jlong jhandle, jboolean use_direct_writes) { + ENV_OPTIONS_SET_BOOL(jhandle, use_direct_writes); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: useDirectWrites + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_useDirectWrites(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, use_direct_writes); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setAllowFallocate + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setAllowFallocate(JNIEnv *env, jobject jobj, + jlong jhandle, + jboolean allow_fallocate) { + ENV_OPTIONS_SET_BOOL(jhandle, allow_fallocate); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: allowFallocate + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_allowFallocate(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, allow_fallocate); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setSetFdCloexec + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setSetFdCloexec(JNIEnv *env, jobject jobj, + jlong jhandle, + jboolean set_fd_cloexec) { + ENV_OPTIONS_SET_BOOL(jhandle, set_fd_cloexec); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setFdCloexec + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_setFdCloexec(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, set_fd_cloexec); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setBytesPerSync + * Signature: (JJ)V + */ +void Java_org_rocksdb_EnvOptions_setBytesPerSync(JNIEnv *env, jobject jobj, + jlong jhandle, + jlong bytes_per_sync) { + ENV_OPTIONS_SET_UINT64_T(jhandle, bytes_per_sync); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: bytesPerSync + * Signature: (J)J + */ +jlong Java_org_rocksdb_EnvOptions_bytesPerSync(JNIEnv *env, jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, bytes_per_sync); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setFallocateWithKeepSize + * Signature: (JZ)V + */ +void Java_org_rocksdb_EnvOptions_setFallocateWithKeepSize( + JNIEnv *env, jobject jobj, jlong jhandle, + jboolean fallocate_with_keep_size) { + ENV_OPTIONS_SET_BOOL(jhandle, fallocate_with_keep_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: fallocateWithKeepSize + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_EnvOptions_fallocateWithKeepSize(JNIEnv *env, + jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, fallocate_with_keep_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setCompactionReadaheadSize + * Signature: (JJ)V + */ +void Java_org_rocksdb_EnvOptions_setCompactionReadaheadSize( + JNIEnv *env, jobject jobj, jlong jhandle, jlong compaction_readahead_size) { + ENV_OPTIONS_SET_SIZE_T(jhandle, compaction_readahead_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: compactionReadaheadSize + * Signature: (J)J + */ +jlong Java_org_rocksdb_EnvOptions_compactionReadaheadSize(JNIEnv *env, + jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, compaction_readahead_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setRandomAccessMaxBufferSize + * Signature: (JJ)V + */ +void Java_org_rocksdb_EnvOptions_setRandomAccessMaxBufferSize( + JNIEnv *env, jobject jobj, jlong jhandle, + jlong random_access_max_buffer_size) { + ENV_OPTIONS_SET_SIZE_T(jhandle, random_access_max_buffer_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: randomAccessMaxBufferSize + * Signature: (J)J + */ +jlong Java_org_rocksdb_EnvOptions_randomAccessMaxBufferSize(JNIEnv *env, + jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, random_access_max_buffer_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setWritableFileMaxBufferSize + * Signature: (JJ)V + */ +void Java_org_rocksdb_EnvOptions_setWritableFileMaxBufferSize( + JNIEnv *env, jobject jobj, jlong jhandle, + jlong writable_file_max_buffer_size) { + ENV_OPTIONS_SET_SIZE_T(jhandle, writable_file_max_buffer_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: writableFileMaxBufferSize + * Signature: (J)J + */ +jlong Java_org_rocksdb_EnvOptions_writableFileMaxBufferSize(JNIEnv *env, + jobject jobj, + jlong jhandle) { + return ENV_OPTIONS_GET(jhandle, writable_file_max_buffer_size); +} + +/* + * Class: org_rocksdb_EnvOptions + * Method: setRateLimiter + * Signature: (JJ)V + */ +void Java_org_rocksdb_EnvOptions_setRateLimiter(JNIEnv *env, jobject jobj, + jlong jhandle, + jlong rl_handle) { + auto *rate_limiter = reinterpret_cast(rl_handle); + auto *env_opt = reinterpret_cast(jhandle); + env_opt->rate_limiter = rate_limiter; +} diff --git a/java/rocksjni/external_sst_file_info.cc b/java/rocksjni/external_sst_file_info.cc new file mode 100644 index 000000000..d5ea27eee --- /dev/null +++ b/java/rocksjni/external_sst_file_info.cc @@ -0,0 +1,242 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. +// +// This file implements the "bridge" between Java and C++ and enables +// calling c++ rocksdb::BackupableDB and rocksdb::BackupableDBOptions methods +// from Java side. + +#include + +#include "include/org_rocksdb_ExternalSstFileInfo.h" +#include "rocksdb/sst_file_writer.h" + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: newExternalSstFileInfo + * Signature: ()J + */ +jlong Java_org_rocksdb_ExternalSstFileInfo_newExternalSstFileInfo__( + JNIEnv *env, jclass jcls) { + return reinterpret_cast(new rocksdb::ExternalSstFileInfo()); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: newExternalSstFileInfo + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJII)J + */ +jlong Java_org_rocksdb_ExternalSstFileInfo_newExternalSstFileInfo__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2JJII( + JNIEnv *env, jclass jcls, jstring jfile_path, jstring jsmallest_key, + jstring jlargest_key, jlong jsequence_number, jlong jfile_size, + jint jnum_entries, jint jversion) { + const char *file_path = env->GetStringUTFChars(jfile_path, NULL); + const char *smallest_key = env->GetStringUTFChars(jsmallest_key, NULL); + const char *largest_key = env->GetStringUTFChars(jlargest_key, NULL); + auto *external_sst_file_info = new rocksdb::ExternalSstFileInfo( + file_path, smallest_key, largest_key, + static_cast(jsequence_number), + static_cast(jfile_size), static_cast(jnum_entries), + static_cast(jversion)); + env->ReleaseStringUTFChars(jfile_path, file_path); + env->ReleaseStringUTFChars(jsmallest_key, smallest_key); + env->ReleaseStringUTFChars(jlargest_key, largest_key); + return reinterpret_cast(external_sst_file_info); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setFilePath + * Signature: (JLjava/lang/String;)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setFilePath(JNIEnv *env, jobject jobj, + jlong jhandle, + jstring jfile_path) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + const char *file_path = env->GetStringUTFChars(jfile_path, NULL); + external_sst_file_info->file_path = file_path; + env->ReleaseStringUTFChars(jfile_path, file_path); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: filePath + * Signature: (J)Ljava/lang/String; + */ +jstring Java_org_rocksdb_ExternalSstFileInfo_filePath(JNIEnv *env, jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return env->NewStringUTF(external_sst_file_info->file_path.data()); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setSmallestKey + * Signature: (JLjava/lang/String;)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setSmallestKey( + JNIEnv *env, jobject jobj, jlong jhandle, jstring jsmallest_key) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + const char *smallest_key = env->GetStringUTFChars(jsmallest_key, NULL); + external_sst_file_info->smallest_key = smallest_key; + env->ReleaseStringUTFChars(jsmallest_key, smallest_key); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: smallestKey + * Signature: (J)Ljava/lang/String; + */ +jstring Java_org_rocksdb_ExternalSstFileInfo_smallestKey(JNIEnv *env, + jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return env->NewStringUTF(external_sst_file_info->smallest_key.data()); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setLargestKey + * Signature: (JLjava/lang/String;)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setLargestKey(JNIEnv *env, + jobject jobj, + jlong jhandle, + jstring jlargest_key) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + const char *largest_key = env->GetStringUTFChars(jlargest_key, NULL); + external_sst_file_info->largest_key = largest_key; + env->ReleaseStringUTFChars(jlargest_key, largest_key); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: largestKey + * Signature: (J)Ljava/lang/String; + */ +jstring Java_org_rocksdb_ExternalSstFileInfo_largestKey(JNIEnv *env, + jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return env->NewStringUTF(external_sst_file_info->largest_key.data()); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setSequenceNumber + * Signature: (JJ)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setSequenceNumber( + JNIEnv *env, jobject jobj, jlong jhandle, jlong jsequence_number) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + external_sst_file_info->sequence_number = + static_cast(jsequence_number); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: sequenceNumber + * Signature: (J)J + */ +jlong Java_org_rocksdb_ExternalSstFileInfo_sequenceNumber(JNIEnv *env, + jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return static_cast(external_sst_file_info->sequence_number); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setFileSize + * Signature: (JJ)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setFileSize(JNIEnv *env, jobject jobj, + jlong jhandle, + jlong jfile_size) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + external_sst_file_info->file_size = static_cast(jfile_size); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: fileSize + * Signature: (J)J + */ +jlong Java_org_rocksdb_ExternalSstFileInfo_fileSize(JNIEnv *env, jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return static_cast(external_sst_file_info->file_size); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setNumEntries + * Signature: (JI)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setNumEntries(JNIEnv *env, + jobject jobj, + jlong jhandle, + jint jnum_entries) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + external_sst_file_info->num_entries = static_cast(jnum_entries); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: numEntries + * Signature: (J)I + */ +jint Java_org_rocksdb_ExternalSstFileInfo_numEntries(JNIEnv *env, jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return static_cast(external_sst_file_info->num_entries); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: setVersion + * Signature: (JI)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_setVersion(JNIEnv *env, jobject jobj, + jlong jhandle, + jint jversion) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + external_sst_file_info->version = static_cast(jversion); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: version + * Signature: (J)I + */ +jint Java_org_rocksdb_ExternalSstFileInfo_version(JNIEnv *env, jobject jobj, + jlong jhandle) { + auto *external_sst_file_info = + reinterpret_cast(jhandle); + return static_cast(external_sst_file_info->version); +} + +/* + * Class: org_rocksdb_ExternalSstFileInfo + * Method: disposeInternal + * Signature: (J)V + */ +void Java_org_rocksdb_ExternalSstFileInfo_disposeInternal(JNIEnv *env, + jobject jobj, + jlong jhandle) { + delete reinterpret_cast(jhandle); +} diff --git a/java/rocksjni/rocksjni.cc b/java/rocksjni/rocksjni.cc index 2cf096fed..eec6701e4 100644 --- a/java/rocksjni/rocksjni.cc +++ b/java/rocksjni/rocksjni.cc @@ -1740,3 +1740,75 @@ void Java_org_rocksdb_RocksDB_setOptions(JNIEnv* env, jobject jdb, auto* cf_handle = reinterpret_cast(jcf_handle); db->SetOptions(cf_handle, options_map); } + +////////////////////////////////////////////////////////////////////////////// +// rocksdb::DB::AddFile + +void add_file_helper(JNIEnv* env, const jobjectArray& jfile_path_list, + int file_path_list_len, + std::vector* file_path_list) { + for (int i = 0; i < file_path_list_len; i++) { + jstring jfile_path = + static_cast(env->GetObjectArrayElement(jfile_path_list, i)); + const char* file_path = env->GetStringUTFChars(jfile_path, NULL); + file_path_list->push_back(std::string(file_path)); + env->ReleaseStringUTFChars(jfile_path, file_path); + env->DeleteLocalRef(jfile_path); + } +} + +void add_file_helper( + JNIEnv* env, jlongArray jfi_handle_list, int fi_handle_list_len, + std::vector* file_info_list) { + jlong* jfih = env->GetLongArrayElements(jfi_handle_list, NULL); + for (int i = 0; i < fi_handle_list_len; i++) { + auto* file_info = + reinterpret_cast(*(jfih + i)); + file_info_list->push_back(*file_info); + } +} + +/* + * Class: org_rocksdb_RocksDB + * Method: addFile + * Signature: (JJ[Ljava/lang/String;IZ)V + */ +void Java_org_rocksdb_RocksDB_addFile__JJ_3Ljava_lang_String_2IZ( + JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jcf_handle, + jobjectArray jfile_path_list, jint jfile_path_list_len, + jboolean jmove_file) { + auto* db = reinterpret_cast(jdb_handle); + std::vector file_path_list; + add_file_helper(env, jfile_path_list, static_cast(jfile_path_list_len), + &file_path_list); + auto* column_family = + reinterpret_cast(jcf_handle); + rocksdb::Status s = + db->AddFile(column_family, file_path_list, static_cast(jmove_file)); + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} + +/* + * Class: org_rocksdb_RocksDB + * Method: addFile + * Signature: (JJ[JIZ)V + */ +void Java_org_rocksdb_RocksDB_addFile__JJ_3JIZ( + JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jcf_handle, + jlongArray jfile_info_handle_list, jint jfile_info_handle_list_len, + jboolean jmove_file) { + auto* db = reinterpret_cast(jdb_handle); + std::vector file_info_list; + add_file_helper(env, jfile_info_handle_list, + static_cast(jfile_info_handle_list_len), + &file_info_list); + auto* column_family = + reinterpret_cast(jcf_handle); + rocksdb::Status s = + db->AddFile(column_family, file_info_list, static_cast(jmove_file)); + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} diff --git a/java/rocksjni/sst_file_writerjni.cc b/java/rocksjni/sst_file_writerjni.cc new file mode 100644 index 000000000..f3fb3c88a --- /dev/null +++ b/java/rocksjni/sst_file_writerjni.cc @@ -0,0 +1,94 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. +// +// This file implements the "bridge" between Java and C++ and enables +// calling c++ rocksdb::BackupableDB and rocksdb::BackupableDBOptions methods +// from Java side. + +#include +#include + +#include "include/org_rocksdb_SstFileWriter.h" +#include "rocksdb/comparator.h" +#include "rocksdb/env.h" +#include "rocksdb/options.h" +#include "rocksdb/sst_file_writer.h" +#include "rocksjni/portal.h" + +/* + * Class: org_rocksdb_SstFileWriter + * Method: newSstFileWriter + * Signature: (JJJ)J + */ +jlong Java_org_rocksdb_SstFileWriter_newSstFileWriter(JNIEnv *env, jclass jcls, + jlong jenvoptions, + jlong joptions, + jlong jcomparator) { + auto *env_options = + reinterpret_cast(jenvoptions); + auto *options = reinterpret_cast(joptions); + auto *comparator = reinterpret_cast(jcomparator); + rocksdb::SstFileWriter *sst_file_writer = + new rocksdb::SstFileWriter(*env_options, *options, comparator); + return reinterpret_cast(sst_file_writer); +} + +/* + * Class: org_rocksdb_SstFileWriter + * Method: open + * Signature: (JLjava/lang/String;)V + */ +void Java_org_rocksdb_SstFileWriter_open(JNIEnv *env, jobject jobj, + jlong jhandle, jstring jfile_path) { + const char *file_path = env->GetStringUTFChars(jfile_path, NULL); + rocksdb::Status s = + reinterpret_cast(jhandle)->Open(file_path); + env->ReleaseStringUTFChars(jfile_path, file_path); + + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} + +/* + * Class: org_rocksdb_SstFileWriter + * Method: add + * Signature: (JJJ)V + */ +void Java_org_rocksdb_SstFileWriter_add(JNIEnv *env, jobject jobj, + jlong jhandle, jlong jkey_handle, + jlong jvalue_handle) { + auto *key_slice = reinterpret_cast(jkey_handle); + auto *value_slice = reinterpret_cast(jvalue_handle); + rocksdb::Status s = reinterpret_cast(jhandle)->Add( + *key_slice, *value_slice); + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} + +/* + * Class: org_rocksdb_SstFileWriter + * Method: finish + * Signature: (J)V + */ +void Java_org_rocksdb_SstFileWriter_finish(JNIEnv *env, jobject jobj, + jlong jhandle) { + rocksdb::Status s = + reinterpret_cast(jhandle)->Finish(); + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} + +/* + * Class: org_rocksdb_SstFileWriter + * Method: disposeInternal + * Signature: (J)V + */ +void Java_org_rocksdb_SstFileWriter_disposeInternal(JNIEnv *env, jobject jobj, + jlong jhandle) { + delete reinterpret_cast(jhandle); +} diff --git a/java/src/main/java/org/rocksdb/EnvOptions.java b/java/src/main/java/org/rocksdb/EnvOptions.java new file mode 100644 index 000000000..2fabf4b7c --- /dev/null +++ b/java/src/main/java/org/rocksdb/EnvOptions.java @@ -0,0 +1,207 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + +package org.rocksdb; + +public class EnvOptions extends RocksObject { + static { + RocksDB.loadLibrary(); + } + + public EnvOptions() { + super(newEnvOptions()); + } + + public EnvOptions setUseOsBuffer(final boolean useOsBuffer) { + setUseOsBuffer(nativeHandle_, useOsBuffer); + return this; + } + + public boolean useOsBuffer() { + assert(isOwningHandle()); + return useOsBuffer(nativeHandle_); + } + + public EnvOptions setUseMmapReads(final boolean useMmapReads) { + setUseMmapReads(nativeHandle_, useMmapReads); + return this; + } + + public boolean useMmapReads() { + assert(isOwningHandle()); + return useMmapReads(nativeHandle_); + } + + public EnvOptions setUseMmapWrites(final boolean useMmapWrites) { + setUseMmapWrites(nativeHandle_, useMmapWrites); + return this; + } + + public boolean useMmapWrites() { + assert(isOwningHandle()); + return useMmapWrites(nativeHandle_); + } + + public EnvOptions setUseDirectReads(final boolean useDirectReads) { + setUseDirectReads(nativeHandle_, useDirectReads); + return this; + } + + public boolean useDirectReads() { + assert(isOwningHandle()); + return useDirectReads(nativeHandle_); + } + + public EnvOptions setUseDirectWrites(final boolean useDirectWrites) { + setUseDirectWrites(nativeHandle_, useDirectWrites); + return this; + } + + public boolean useDirectWrites() { + assert(isOwningHandle()); + return useDirectWrites(nativeHandle_); + } + + public EnvOptions setAllowFallocate(final boolean allowFallocate) { + setAllowFallocate(nativeHandle_, allowFallocate); + return this; + } + + public boolean allowFallocate() { + assert(isOwningHandle()); + return allowFallocate(nativeHandle_); + } + + public EnvOptions setSetFdCloexec(final boolean setFdCloexec) { + setSetFdCloexec(nativeHandle_, setFdCloexec); + return this; + } + + public boolean setFdCloexec() { + assert(isOwningHandle()); + return setFdCloexec(nativeHandle_); + } + + public EnvOptions setBytesPerSync(final long bytesPerSync) { + setBytesPerSync(nativeHandle_, bytesPerSync); + return this; + } + + public long bytesPerSync() { + assert(isOwningHandle()); + return bytesPerSync(nativeHandle_); + } + + public EnvOptions setFallocateWithKeepSize(final boolean fallocateWithKeepSize) { + setFallocateWithKeepSize(nativeHandle_, fallocateWithKeepSize); + return this; + } + + public boolean fallocateWithKeepSize() { + assert(isOwningHandle()); + return fallocateWithKeepSize(nativeHandle_); + } + + public EnvOptions setCompactionReadaheadSize(final long compactionReadaheadSize) { + setCompactionReadaheadSize(nativeHandle_, compactionReadaheadSize); + return this; + } + + public long compactionReadaheadSize() { + assert(isOwningHandle()); + return compactionReadaheadSize(nativeHandle_); + } + + public EnvOptions setRandomAccessMaxBufferSize(final long randomAccessMaxBufferSize) { + setRandomAccessMaxBufferSize(nativeHandle_, randomAccessMaxBufferSize); + return this; + } + + public long randomAccessMaxBufferSize() { + assert(isOwningHandle()); + return randomAccessMaxBufferSize(nativeHandle_); + } + + public EnvOptions setWritableFileMaxBufferSize(final long writableFileMaxBufferSize) { + setWritableFileMaxBufferSize(nativeHandle_, writableFileMaxBufferSize); + return this; + } + + public long writableFileMaxBufferSize() { + assert(isOwningHandle()); + return writableFileMaxBufferSize(nativeHandle_); + } + + public EnvOptions setRateLimiterConfig(final RateLimiterConfig rateLimiterConfig) { + this.rateLimiterConfig = rateLimiterConfig; + setRateLimiter(nativeHandle_, rateLimiterConfig.newRateLimiterHandle()); + return this; + } + + public RateLimiterConfig rateLimiterConfig() { + assert(isOwningHandle()); + return rateLimiterConfig; + } + + private native static long newEnvOptions(); + + @Override protected final native void disposeInternal(final long handle); + + private native void setUseOsBuffer(final long handle, final boolean useOsBuffer); + + private native boolean useOsBuffer(final long handle); + + private native void setUseMmapReads(final long handle, final boolean useMmapReads); + + private native boolean useMmapReads(final long handle); + + private native void setUseMmapWrites(final long handle, final boolean useMmapWrites); + + private native boolean useMmapWrites(final long handle); + + private native void setUseDirectReads(final long handle, final boolean useDirectReads); + + private native boolean useDirectReads(final long handle); + + private native void setUseDirectWrites(final long handle, final boolean useDirectWrites); + + private native boolean useDirectWrites(final long handle); + + private native void setAllowFallocate(final long handle, final boolean allowFallocate); + + private native boolean allowFallocate(final long handle); + + private native void setSetFdCloexec(final long handle, final boolean setFdCloexec); + + private native boolean setFdCloexec(final long handle); + + private native void setBytesPerSync(final long handle, final long bytesPerSync); + + private native long bytesPerSync(final long handle); + + private native void setFallocateWithKeepSize( + final long handle, final boolean fallocateWithKeepSize); + + private native boolean fallocateWithKeepSize(final long handle); + + private native void setCompactionReadaheadSize( + final long handle, final long compactionReadaheadSize); + + private native long compactionReadaheadSize(final long handle); + + private native void setRandomAccessMaxBufferSize( + final long handle, final long randomAccessMaxBufferSize); + + private native long randomAccessMaxBufferSize(final long handle); + + private native void setWritableFileMaxBufferSize( + final long handle, final long writableFileMaxBufferSize); + + private native long writableFileMaxBufferSize(final long handle); + + private native void setRateLimiter(final long handle, final long rateLimiterHandle); + + private RateLimiterConfig rateLimiterConfig; +} diff --git a/java/src/main/java/org/rocksdb/ExternalSstFileInfo.java b/java/src/main/java/org/rocksdb/ExternalSstFileInfo.java new file mode 100644 index 000000000..a35c15539 --- /dev/null +++ b/java/src/main/java/org/rocksdb/ExternalSstFileInfo.java @@ -0,0 +1,135 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + +package org.rocksdb; + +import java.io.File; + +public class ExternalSstFileInfo extends RocksObject { + public ExternalSstFileInfo() { + super(newExternalSstFileInfo()); + } + + public ExternalSstFileInfo(final String filePath, final String smallestKey, + final String largestKey, final long sequenceNumber, final long fileSize, final int numEntries, + final int version) { + super(newExternalSstFileInfo(ensureNotNullFilePath(filePath), + ensureNotNullSmallestKey(smallestKey), ensureNotNullLargestKey(largestKey), sequenceNumber, + fileSize, numEntries, version)); + } + + private static String ensureNotNullFilePath(final String filePath) { + if (filePath == null) { + throw new NullPointerException("filePath is null."); + } + return filePath; + } + + private static String ensureNotNullSmallestKey(final String smallestKey) { + if (smallestKey == null) { + throw new NullPointerException("smallestKey is null."); + } + return smallestKey; + } + + private static String ensureNotNullLargestKey(final String largestKey) { + if (largestKey == null) { + throw new NullPointerException("largestKey is null."); + } + return largestKey; + } + + public void setFilePath(final String filePath) { + setFilePath(nativeHandle_, filePath); + } + + public String filePath() { + return filePath(nativeHandle_); + } + + public void setSmallestKey(final String smallestKey) { + setSmallestKey(nativeHandle_, smallestKey); + } + + public String smallestKey() { + return smallestKey(nativeHandle_); + } + + public void setLargestKey(final String largestKey) { + setLargestKey(nativeHandle_, largestKey); + } + + public String largestKey() { + return largestKey(nativeHandle_); + } + + public void setSequenceNumber(final long sequenceNumber) { + setSequenceNumber(nativeHandle_, sequenceNumber); + } + + public long sequenceNumber() { + return sequenceNumber(nativeHandle_); + } + + public void setFileSize(final long fileSize) { + setFileSize(nativeHandle_, fileSize); + } + + public long fileSize() { + return fileSize(nativeHandle_); + } + + public void setNumEntries(final int numEntries) { + setNumEntries(nativeHandle_, numEntries); + } + + public int numEntries() { + return numEntries(nativeHandle_); + } + + public void setVersion(final int version) { + setVersion(nativeHandle_, version); + } + + public int version() { + return version(nativeHandle_); + } + + private native static long newExternalSstFileInfo(); + + private native static long newExternalSstFileInfo(final String filePath, final String smallestKey, + final String largestKey, final long sequenceNumber, final long fileSize, final int numEntries, + final int version); + + private native void setFilePath(final long handle, final String filePath); + + private native String filePath(final long handle); + + private native void setSmallestKey(final long handle, final String smallestKey); + + private native String smallestKey(final long handle); + + private native void setLargestKey(final long handle, final String largestKey); + + private native String largestKey(final long handle); + + private native void setSequenceNumber(final long handle, final long sequenceNumber); + + private native long sequenceNumber(final long handle); + + private native void setFileSize(final long handle, final long fileSize); + + private native long fileSize(final long handle); + + private native void setNumEntries(final long handle, final int numEntries); + + private native int numEntries(final long handle); + + private native void setVersion(final long handle, final int version); + + private native int version(final long handle); + + @Override protected final native void disposeInternal(final long handle); +} diff --git a/java/src/main/java/org/rocksdb/RocksDB.java b/java/src/main/java/org/rocksdb/RocksDB.java index b27c1c4fc..6430e23d4 100644 --- a/java/src/main/java/org/rocksdb/RocksDB.java +++ b/java/src/main/java/org/rocksdb/RocksDB.java @@ -1944,11 +1944,116 @@ public class RocksDB extends RocksObject { } public void setOptions(final ColumnFamilyHandle columnFamilyHandle, - final MutableColumnFamilyOptions mutableColumnFamilyOptions) - throws RocksDBException { + final MutableColumnFamilyOptions mutableColumnFamilyOptions) + throws RocksDBException { setOptions(nativeHandle_, columnFamilyHandle.nativeHandle_, - mutableColumnFamilyOptions.getKeys(), - mutableColumnFamilyOptions.getValues()); + mutableColumnFamilyOptions.getKeys(), + mutableColumnFamilyOptions.getValues()); + } + + private long[] toNativeHandleList(final List objectList) { + final int len = objectList.size(); + final long[] handleList = new long[len]; + for (int i = 0; i < len; i++) { + handleList[i] = objectList.get(i).nativeHandle_; + } + return handleList; + } + + public void addFileWithFilePath(final ColumnFamilyHandle columnFamilyHandle, + final List filePathList) throws RocksDBException { + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, + filePathList.toArray(new String[filePathList.size()]), filePathList.size(), false); + } + + public void addFileWithFilePath(final ColumnFamilyHandle columnFamilyHandle, + final List filePathList, final boolean moveFile) throws RocksDBException { + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, + filePathList.toArray(new String[filePathList.size()]), filePathList.size(), moveFile); + } + + public void addFileWithFilePath(final List filePathList) throws RocksDBException { + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, + filePathList.toArray(new String[filePathList.size()]), filePathList.size(), false); + } + + public void addFileWithFilePath(final List filePathList, final boolean moveFile) + throws RocksDBException { + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, + filePathList.toArray(new String[filePathList.size()]), filePathList.size(), moveFile); + } + + public void addFileWithFilePath( + final ColumnFamilyHandle columnFamilyHandle, final String filePath) throws RocksDBException { + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, new String[] {filePath}, 1, false); + } + + public void addFileWithFilePath(final ColumnFamilyHandle columnFamilyHandle, + final String filePath, final boolean moveFile) throws RocksDBException { + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, new String[] {filePath}, 1, moveFile); + } + + public void addFileWithFilePath(final String filePath) throws RocksDBException { + addFile( + nativeHandle_, getDefaultColumnFamily().nativeHandle_, new String[] {filePath}, 1, false); + } + + public void addFileWithFilePath(final String filePath, final boolean moveFile) + throws RocksDBException { + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, new String[] {filePath}, 1, + moveFile); + } + + public void addFileWithFileInfo(final ColumnFamilyHandle columnFamilyHandle, + final List fileInfoList) throws RocksDBException { + final long[] fiHandleList = toNativeHandleList(fileInfoList); + addFile( + nativeHandle_, columnFamilyHandle.nativeHandle_, fiHandleList, fiHandleList.length, false); + } + + public void addFileWithFileInfo(final ColumnFamilyHandle columnFamilyHandle, + final List fileInfoList, final boolean moveFile) + throws RocksDBException { + final long[] fiHandleList = toNativeHandleList(fileInfoList); + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, fiHandleList, fiHandleList.length, + moveFile); + } + + public void addFileWithFileInfo(final List fileInfoList) + throws RocksDBException { + final long[] fiHandleList = toNativeHandleList(fileInfoList); + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, fiHandleList, + fiHandleList.length, false); + } + + public void addFileWithFileInfo(final List fileInfoList, + final boolean moveFile) throws RocksDBException { + final long[] fiHandleList = toNativeHandleList(fileInfoList); + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, fiHandleList, + fiHandleList.length, moveFile); + } + + public void addFileWithFileInfo(final ColumnFamilyHandle columnFamilyHandle, + final ExternalSstFileInfo fileInfo) throws RocksDBException { + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, new long[] {fileInfo.nativeHandle_}, 1, + false); + } + + public void addFileWithFileInfo(final ColumnFamilyHandle columnFamilyHandle, + final ExternalSstFileInfo fileInfo, final boolean moveFile) throws RocksDBException { + addFile(nativeHandle_, columnFamilyHandle.nativeHandle_, new long[] {fileInfo.nativeHandle_}, 1, + moveFile); + } + + public void addFileWithFileInfo(final ExternalSstFileInfo fileInfo) throws RocksDBException { + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, + new long[] {fileInfo.nativeHandle_}, 1, false); + } + + public void addFileWithFileInfo(final ExternalSstFileInfo fileInfo, final boolean moveFile) + throws RocksDBException { + addFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_, + new long[] {fileInfo.nativeHandle_}, 1, moveFile); } /** @@ -2142,6 +2247,9 @@ public class RocksDB extends RocksObject { throws RocksDBException; private native void setOptions(long handle, long cfHandle, String[] keys, String[] values) throws RocksDBException; - + private native void addFile(long handle, long cfHandle, String[] filePathList, + int filePathListLen, boolean moveFile) throws RocksDBException; + private native void addFile(long handle, long cfHandle, long[] fiHandleList, int fiHandleListLen, + boolean moveFile) throws RocksDBException; protected DBOptionsInterface options_; } diff --git a/java/src/main/java/org/rocksdb/SstFileWriter.java b/java/src/main/java/org/rocksdb/SstFileWriter.java new file mode 100644 index 000000000..38d819aaa --- /dev/null +++ b/java/src/main/java/org/rocksdb/SstFileWriter.java @@ -0,0 +1,46 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + +package org.rocksdb; + +public class SstFileWriter extends RocksObject { + static { + RocksDB.loadLibrary(); + } + + public SstFileWriter(final EnvOptions envOptions, final Options options, + final AbstractComparator> comparator) { + super(newSstFileWriter( + envOptions.nativeHandle_, options.nativeHandle_, comparator.getNativeHandle())); + } + + public void open(final String filePath) throws RocksDBException { + open(nativeHandle_, filePath); + } + + public void add(final Slice key, final Slice value) throws RocksDBException { + add(nativeHandle_, key.getNativeHandle(), value.getNativeHandle()); + } + + public void add(final DirectSlice key, final DirectSlice value) throws RocksDBException { + add(nativeHandle_, key.getNativeHandle(), value.getNativeHandle()); + } + + public void finish() throws RocksDBException { + finish(nativeHandle_); + } + + private native static long newSstFileWriter( + final long envOptionsHandle, final long optionsHandle, final long userComparatorHandle); + + private native void open(final long handle, final String filePath) throws RocksDBException; + + private native void add(final long handle, final long keyHandle, final long valueHandle) + throws RocksDBException; + + private native void finish(final long handle) throws RocksDBException; + + @Override protected final native void disposeInternal(final long handle); +} diff --git a/java/src/test/java/org/rocksdb/EnvOptionsTest.java b/java/src/test/java/org/rocksdb/EnvOptionsTest.java new file mode 100644 index 000000000..acc73998d --- /dev/null +++ b/java/src/test/java/org/rocksdb/EnvOptionsTest.java @@ -0,0 +1,142 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + +package org.rocksdb; + +import org.junit.ClassRule; +import org.junit.Test; + +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; + +public class EnvOptionsTest { + @ClassRule + public static final RocksMemoryResource rocksMemoryResource = new RocksMemoryResource(); + + public static final Random rand = PlatformRandomHelper.getPlatformSpecificRandomFactory(); + + @Test + public void useOsBuffer() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setUseOsBuffer(boolValue); + assertThat(envOptions.useOsBuffer()).isEqualTo(boolValue); + } + } + + @Test + public void useMmapReads() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setUseMmapReads(boolValue); + assertThat(envOptions.useMmapReads()).isEqualTo(boolValue); + } + } + + @Test + public void useMmapWrites() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setUseMmapWrites(boolValue); + assertThat(envOptions.useMmapWrites()).isEqualTo(boolValue); + } + } + + @Test + public void useDirectReads() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setUseDirectReads(boolValue); + assertThat(envOptions.useDirectReads()).isEqualTo(boolValue); + } + } + + @Test + public void useDirectWrites() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setUseDirectWrites(boolValue); + assertThat(envOptions.useDirectWrites()).isEqualTo(boolValue); + } + } + + @Test + public void allowFallocate() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setAllowFallocate(boolValue); + assertThat(envOptions.allowFallocate()).isEqualTo(boolValue); + } + } + + @Test + public void setFdCloexecs() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setSetFdCloexec(boolValue); + assertThat(envOptions.setFdCloexec()).isEqualTo(boolValue); + } + } + + @Test + public void bytesPerSync() { + try (final EnvOptions envOptions = new EnvOptions()) { + final long longValue = rand.nextLong(); + envOptions.setBytesPerSync(longValue); + assertThat(envOptions.bytesPerSync()).isEqualTo(longValue); + } + } + + @Test + public void fallocateWithKeepSize() { + try (final EnvOptions envOptions = new EnvOptions()) { + final boolean boolValue = rand.nextBoolean(); + envOptions.setFallocateWithKeepSize(boolValue); + assertThat(envOptions.fallocateWithKeepSize()).isEqualTo(boolValue); + } + } + + @Test + public void compactionReadaheadSize() { + try (final EnvOptions envOptions = new EnvOptions()) { + final int intValue = rand.nextInt(); + envOptions.setCompactionReadaheadSize(intValue); + assertThat(envOptions.compactionReadaheadSize()).isEqualTo(intValue); + } + } + + @Test + public void randomAccessMaxBufferSize() { + try (final EnvOptions envOptions = new EnvOptions()) { + final int intValue = rand.nextInt(); + envOptions.setRandomAccessMaxBufferSize(intValue); + assertThat(envOptions.randomAccessMaxBufferSize()).isEqualTo(intValue); + } + } + + @Test + public void writableFileMaxBufferSize() { + try (final EnvOptions envOptions = new EnvOptions()) { + final int intValue = rand.nextInt(); + envOptions.setWritableFileMaxBufferSize(intValue); + assertThat(envOptions.writableFileMaxBufferSize()).isEqualTo(intValue); + } + } + + @Test + public void rateLimiterConfig() { + try (final EnvOptions envOptions = new EnvOptions()) { + final RateLimiterConfig rateLimiterConfig1 = + new GenericRateLimiterConfig(1000, 100 * 1000, 1); + envOptions.setRateLimiterConfig(rateLimiterConfig1); + assertThat(envOptions.rateLimiterConfig()).isEqualTo(rateLimiterConfig1); + + final RateLimiterConfig rateLimiterConfig2 = new GenericRateLimiterConfig(1000); + envOptions.setRateLimiterConfig(rateLimiterConfig2); + assertThat(envOptions.rateLimiterConfig()).isEqualTo(rateLimiterConfig2); + } + } +} diff --git a/java/src/test/java/org/rocksdb/ExternalSstFileInfoTest.java b/java/src/test/java/org/rocksdb/ExternalSstFileInfoTest.java new file mode 100644 index 000000000..2e8b2368b --- /dev/null +++ b/java/src/test/java/org/rocksdb/ExternalSstFileInfoTest.java @@ -0,0 +1,105 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + +package org.rocksdb; + +import org.junit.ClassRule; +import org.junit.Test; + +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ExternalSstFileInfoTest { + @ClassRule + public static final RocksMemoryResource rocksMemoryResource = new RocksMemoryResource(); + + public static final Random rand = PlatformRandomHelper.getPlatformSpecificRandomFactory(); + + @Test + public void createExternalSstFileInfoWithoutParameters() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + assertThat(info).isNotNull(); + } + } + + @Test + public void createExternalSstFileInfoWithParameters() { + final String filePath = "path/to/sst"; + final String smallestKey = "min"; + final String largestKey = "max"; + final long sequenceNumber = rand.nextLong(); + final long fileSize = rand.nextLong(); + final int numEntries = rand.nextInt(); + final int version = rand.nextInt(); + try (final ExternalSstFileInfo info = new ExternalSstFileInfo( + filePath, smallestKey, largestKey, sequenceNumber, fileSize, numEntries, version)) { + assertThat(info).isNotNull(); + } + } + + @Test + public void filePath() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final String stringVale = "path/to/sst"; + info.setFilePath(stringVale); + assertThat(info.filePath()).isEqualTo(stringVale); + } + } + + @Test + public void smallestKey() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final String stringValue = "min"; + info.setSmallestKey(stringValue); + assertThat(info.smallestKey()).isEqualTo(stringValue); + } + } + + @Test + public void largestKey() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final String stringValue = "max"; + info.setLargestKey(stringValue); + assertThat(info.largestKey()).isEqualTo(stringValue); + } + } + + @Test + public void sequenceNumber() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final long longValue = rand.nextLong(); + info.setSequenceNumber(longValue); + assertThat(info.sequenceNumber()).isEqualTo(longValue); + } + } + + @Test + public void fileSize() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final long longValue = Math.max(1, rand.nextLong()); + info.setFileSize(longValue); + assertThat(info.fileSize()).isEqualTo(longValue); + } + } + + @Test + public void numEntries() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final int intValue = Math.max(1, rand.nextInt()); + info.setNumEntries(intValue); + assertThat(info.numEntries()).isEqualTo(intValue); + } + } + + @Test + public void version() { + try (final ExternalSstFileInfo info = new ExternalSstFileInfo()) { + final int intValue = rand.nextInt(); + info.setVersion(intValue); + assertThat(info.version()).isEqualTo(intValue); + } + } +} diff --git a/java/src/test/java/org/rocksdb/SstFileWriterTest.java b/java/src/test/java/org/rocksdb/SstFileWriterTest.java new file mode 100644 index 000000000..eb8c76d34 --- /dev/null +++ b/java/src/test/java/org/rocksdb/SstFileWriterTest.java @@ -0,0 +1,84 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. An additional grant +// of patent rights can be found in the PATENTS file in the same directory. + +package org.rocksdb; + +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.rocksdb.util.BytewiseComparator; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SstFileWriterTest { + private static final String SST_FILE_NAME = "test.sst"; + private static final String DB_DIRECTORY_NAME = "test_db"; + + @ClassRule + public static final RocksMemoryResource rocksMemoryResource = new RocksMemoryResource(); + + @Rule public TemporaryFolder parentFolder = new TemporaryFolder(); + + private File newSstFile(final TreeMap keyValues) + throws IOException, RocksDBException { + final EnvOptions envOptions = new EnvOptions(); + final ComparatorOptions comparatorOptions = new ComparatorOptions(); + final BytewiseComparator comparator = new BytewiseComparator(comparatorOptions); + final Options options = new Options().setComparator(comparator); + final SstFileWriter sstFileWriter = new SstFileWriter(envOptions, options, comparator); + final File sstFile = parentFolder.newFile(SST_FILE_NAME); + try { + sstFileWriter.open(sstFile.getAbsolutePath()); + for (Map.Entry keyValue : keyValues.entrySet()) { + Slice keySlice = new Slice(keyValue.getKey()); + Slice valueSlice = new Slice(keyValue.getValue()); + sstFileWriter.add(keySlice, valueSlice); + keySlice.close(); + valueSlice.close(); + } + sstFileWriter.finish(); + } finally { + assertThat(sstFileWriter).isNotNull(); + sstFileWriter.close(); + options.close(); + envOptions.close(); + comparatorOptions.close(); + comparator.close(); + } + return sstFile; + } + + @Test + public void generateSstFile() throws RocksDBException, IOException { + final TreeMap keyValues = new TreeMap<>(); + keyValues.put("key1", "value1"); + keyValues.put("key2", "value2"); + newSstFile(keyValues); + } + + @Test + public void ingestSstFile() throws RocksDBException, IOException { + final TreeMap keyValues = new TreeMap<>(); + keyValues.put("key1", "value1"); + keyValues.put("key2", "value2"); + final File sstFile = newSstFile(keyValues); + final File dbFolder = parentFolder.newFolder(DB_DIRECTORY_NAME); + final Options options = new Options().setCreateIfMissing(true); + final RocksDB db = RocksDB.open(options, dbFolder.getAbsolutePath()); + db.addFileWithFilePath(sstFile.getAbsolutePath()); + + assertThat(db.get("key1".getBytes())).isEqualTo("value1".getBytes()); + assertThat(db.get("key2".getBytes())).isEqualTo("value2".getBytes()); + + options.close(); + db.close(); + } +} diff --git a/src.mk b/src.mk index 9cbc8b438..2fe89f479 100644 --- a/src.mk +++ b/src.mk @@ -331,6 +331,8 @@ JNI_NATIVE_SOURCES = \ java/rocksjni/comparator.cc \ java/rocksjni/comparatorjnicallback.cc \ java/rocksjni/env.cc \ + java/rocksjni/env_options.cc \ + java/rocksjni/external_sst_file_info.cc \ java/rocksjni/filter.cc \ java/rocksjni/iterator.cc \ java/rocksjni/loggerjnicallback.cc \ @@ -344,6 +346,7 @@ JNI_NATIVE_SOURCES = \ java/rocksjni/rocksdb_exception_test.cc \ java/rocksjni/slice.cc \ java/rocksjni/snapshot.cc \ + java/rocksjni/sst_file_writerjni.cc \ java/rocksjni/statistics.cc \ java/rocksjni/table.cc \ java/rocksjni/transaction_log.cc \