summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/java/rocksjni
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/rocksdb/java/rocksjni
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/rocksdb/java/rocksjni.pom150
-rw-r--r--src/rocksdb/java/rocksjni/backupablejni.cc337
-rw-r--r--src/rocksdb/java/rocksjni/backupenginejni.cc267
-rw-r--r--src/rocksdb/java/rocksjni/cassandra_compactionfilterjni.cc23
-rw-r--r--src/rocksdb/java/rocksjni/cassandra_value_operator.cc47
-rw-r--r--src/rocksdb/java/rocksjni/checkpoint.cc67
-rw-r--r--src/rocksdb/java/rocksjni/clock_cache.cc40
-rw-r--r--src/rocksdb/java/rocksjni/columnfamilyhandle.cc72
-rw-r--r--src/rocksdb/java/rocksjni/compact_range_options.cc196
-rw-r--r--src/rocksdb/java/rocksjni/compaction_filter.cc28
-rw-r--r--src/rocksdb/java/rocksjni/compaction_filter_factory.cc38
-rw-r--r--src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.cc76
-rw-r--r--src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.h35
-rw-r--r--src/rocksdb/java/rocksjni/compaction_job_info.cc222
-rw-r--r--src/rocksdb/java/rocksjni/compaction_job_stats.cc361
-rw-r--r--src/rocksdb/java/rocksjni/compaction_options.cc116
-rw-r--r--src/rocksdb/java/rocksjni/compaction_options_fifo.cc77
-rw-r--r--src/rocksdb/java/rocksjni/compaction_options_universal.cc193
-rw-r--r--src/rocksdb/java/rocksjni/comparator.cc63
-rw-r--r--src/rocksdb/java/rocksjni/comparatorjnicallback.cc340
-rw-r--r--src/rocksdb/java/rocksjni/comparatorjnicallback.h93
-rw-r--r--src/rocksdb/java/rocksjni/compression_options.cc164
-rw-r--r--src/rocksdb/java/rocksjni/env.cc234
-rw-r--r--src/rocksdb/java/rocksjni/env_options.cc297
-rw-r--r--src/rocksdb/java/rocksjni/filter.cc42
-rw-r--r--src/rocksdb/java/rocksjni/ingest_external_file_options.cc196
-rw-r--r--src/rocksdb/java/rocksjni/iterator.cc186
-rw-r--r--src/rocksdb/java/rocksjni/jnicallback.cc53
-rw-r--r--src/rocksdb/java/rocksjni/jnicallback.h29
-rw-r--r--src/rocksdb/java/rocksjni/loggerjnicallback.cc294
-rw-r--r--src/rocksdb/java/rocksjni/loggerjnicallback.h49
-rw-r--r--src/rocksdb/java/rocksjni/lru_cache.cc43
-rw-r--r--src/rocksdb/java/rocksjni/memory_util.cc100
-rw-r--r--src/rocksdb/java/rocksjni/memtablejni.cc89
-rw-r--r--src/rocksdb/java/rocksjni/merge_operator.cc75
-rw-r--r--src/rocksdb/java/rocksjni/native_comparator_wrapper_test.cc43
-rw-r--r--src/rocksdb/java/rocksjni/optimistic_transaction_db.cc278
-rw-r--r--src/rocksdb/java/rocksjni/optimistic_transaction_options.cc73
-rw-r--r--src/rocksdb/java/rocksjni/options.cc6800
-rw-r--r--src/rocksdb/java/rocksjni/options_util.cc130
-rw-r--r--src/rocksdb/java/rocksjni/persistent_cache.cc53
-rw-r--r--src/rocksdb/java/rocksjni/portal.h7092
-rw-r--r--src/rocksdb/java/rocksjni/ratelimiterjni.cc121
-rw-r--r--src/rocksdb/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc22
-rw-r--r--src/rocksdb/java/rocksjni/restorejni.cc40
-rw-r--r--src/rocksdb/java/rocksjni/rocks_callback_object.cc31
-rw-r--r--src/rocksdb/java/rocksjni/rocksdb_exception_test.cc78
-rw-r--r--src/rocksdb/java/rocksjni/rocksjni.cc3046
-rw-r--r--src/rocksdb/java/rocksjni/slice.cc356
-rw-r--r--src/rocksdb/java/rocksjni/snapshot.cc26
-rw-r--r--src/rocksdb/java/rocksjni/sst_file_manager.cc232
-rw-r--r--src/rocksdb/java/rocksjni/sst_file_writerjni.cc268
-rw-r--r--src/rocksdb/java/rocksjni/statistics.cc247
-rw-r--r--src/rocksdb/java/rocksjni/statisticsjni.cc32
-rw-r--r--src/rocksdb/java/rocksjni/statisticsjni.h34
-rw-r--r--src/rocksdb/java/rocksjni/table.cc139
-rw-r--r--src/rocksdb/java/rocksjni/table_filter.cc25
-rw-r--r--src/rocksdb/java/rocksjni/table_filter_jnicallback.cc62
-rw-r--r--src/rocksdb/java/rocksjni/table_filter_jnicallback.h34
-rw-r--r--src/rocksdb/java/rocksjni/thread_status.cc121
-rw-r--r--src/rocksdb/java/rocksjni/trace_writer.cc23
-rw-r--r--src/rocksdb/java/rocksjni/trace_writer_jnicallback.cc115
-rw-r--r--src/rocksdb/java/rocksjni/trace_writer_jnicallback.h36
-rw-r--r--src/rocksdb/java/rocksjni/transaction.cc1584
-rw-r--r--src/rocksdb/java/rocksjni/transaction_db.cc453
-rw-r--r--src/rocksdb/java/rocksjni/transaction_db_options.cc158
-rw-r--r--src/rocksdb/java/rocksjni/transaction_log.cc76
-rw-r--r--src/rocksdb/java/rocksjni/transaction_notifier.cc42
-rw-r--r--src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.cc39
-rw-r--r--src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.h42
-rw-r--r--src/rocksdb/java/rocksjni/transaction_options.cc179
-rw-r--r--src/rocksdb/java/rocksjni/ttl.cc207
-rw-r--r--src/rocksdb/java/rocksjni/wal_filter.cc23
-rw-r--r--src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc144
-rw-r--r--src/rocksdb/java/rocksjni/wal_filter_jnicallback.h42
-rw-r--r--src/rocksdb/java/rocksjni/write_batch.cc604
-rw-r--r--src/rocksdb/java/rocksjni/write_batch_test.cc194
-rw-r--r--src/rocksdb/java/rocksjni/write_batch_with_index.cc746
-rw-r--r--src/rocksdb/java/rocksjni/write_buffer_manager.cc38
-rw-r--r--src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.cc514
-rw-r--r--src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.h84
81 files changed, 29418 insertions, 0 deletions
diff --git a/src/rocksdb/java/rocksjni.pom b/src/rocksdb/java/rocksjni.pom
new file mode 100644
index 00000000..94f07551
--- /dev/null
+++ b/src/rocksdb/java/rocksjni.pom
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <name>RocksDB JNI</name>
+ <url>http://rocksdb.org/</url>
+ <groupId>org.rocksdb</groupId>
+ <artifactId>rocksdbjni</artifactId>
+ <!-- Version will be automatically replaced -->
+ <version>-</version>
+ <description>RocksDB fat jar that contains .so files for linux32 and linux64, jnilib files
+ for Mac OSX, and a .dll for Windows x64.
+ </description>
+ <licenses>
+ <license>
+ <name>Apache License 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
+ <distribution>repo</distribution>
+ </license>
+ <license>
+ <name>GNU General Public License, version 2</name>
+ <url>http://www.gnu.org/licenses/gpl-2.0.html</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <scm>
+ <connection>scm:git:git://github.com/dropwizard/metrics.git</connection>
+ <developerConnection>scm:git:git@github.com:dropwizard/metrics.git</developerConnection>
+ <url>http://github.com/dropwizard/metrics/</url>
+ <tag>HEAD</tag>
+ </scm>
+ <developers>
+ <developer>
+ <name>Facebook</name>
+ <email>help@facebook.com</email>
+ <timezone>America/New_York</timezone>
+ <roles>
+ <role>architect</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <properties>
+ <project.build.source>1.7</project.build.source>
+ <project.build.target>1.7</project.build.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.2</version>
+ <configuration>
+ <source>${project.build.source}</source>
+ <target>${project.build.target}</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.18.1</version>
+ <configuration>
+ <argLine>${argLine} -ea -Xcheck:jni -Djava.library.path=${project.build.directory}</argLine>
+ <useManifestOnlyJar>false</useManifestOnlyJar>
+ <useSystemClassLoader>false</useSystemClassLoader>
+ <additionalClasspathElements>
+ <additionalClasspathElement>${project.build.directory}/*</additionalClasspathElement>
+ </additionalClasspathElements>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <version>0.7.2.201409121644</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>report</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.gmaven</groupId>
+ <artifactId>groovy-maven-plugin</artifactId>
+ <version>2.0</version>
+ <executions>
+ <execution>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <defaults>
+ <name>Xenu</name>
+ </defaults>
+ <source>
+ String fileContents = new File(project.basedir.absolutePath + '/../include/rocksdb/version.h').getText('UTF-8')
+ matcher = (fileContents =~ /(?s).*ROCKSDB_MAJOR ([0-9]+).*?/)
+ String major_version = matcher.getAt(0).getAt(1)
+ matcher = (fileContents =~ /(?s).*ROCKSDB_MINOR ([0-9]+).*?/)
+ String minor_version = matcher.getAt(0).getAt(1)
+ matcher = (fileContents =~ /(?s).*ROCKSDB_PATCH ([0-9]+).*?/)
+ String patch_version = matcher.getAt(0).getAt(1)
+ String version = String.format('%s.%s.%s', major_version, minor_version, patch_version)
+ // Set version to be used in pom.properties
+ project.version = version
+ // Set version to be set as jar name
+ project.build.finalName = project.artifactId + "-" + version
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>1.7.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/rocksdb/java/rocksjni/backupablejni.cc b/src/rocksdb/java/rocksjni/backupablejni.cc
new file mode 100644
index 00000000..c5ac3037
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/backupablejni.cc
@@ -0,0 +1,337 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::BackupEnginge and rocksdb::BackupableDBOptions methods
+// from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+#include "include/org_rocksdb_BackupableDBOptions.h"
+#include "rocksdb/utilities/backupable_db.h"
+#include "rocksjni/portal.h"
+
+///////////////////////////////////////////////////////////////////////////
+// BackupDBOptions
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: newBackupableDBOptions
+ * Signature: (Ljava/lang/String;)J
+ */
+jlong Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions(
+ JNIEnv* env, jclass /*jcls*/, jstring jpath) {
+ const char* cpath = env->GetStringUTFChars(jpath, nullptr);
+ if (cpath == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ auto* bopt = new rocksdb::BackupableDBOptions(cpath);
+ env->ReleaseStringUTFChars(jpath, cpath);
+ return reinterpret_cast<jlong>(bopt);
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: backupDir
+ * Signature: (J)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_BackupableDBOptions_backupDir(JNIEnv* env,
+ jobject /*jopt*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return env->NewStringUTF(bopt->backup_dir.c_str());
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setBackupEnv
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setBackupEnv(
+ JNIEnv* /*env*/, jobject /*jopt*/, jlong jhandle, jlong jrocks_env_handle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jrocks_env_handle);
+ bopt->backup_env = rocks_env;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setShareTableFiles
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setShareTableFiles(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jboolean flag) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->share_table_files = flag;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: shareTableFiles
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_BackupableDBOptions_shareTableFiles(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->share_table_files;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setInfoLog
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setInfoLog(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong /*jlogger_handle*/) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ auto* sptr_logger =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(jhandle);
+ bopt->info_log = sptr_logger->get();
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setSync
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setSync(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jboolean flag) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->sync = flag;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: sync
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_BackupableDBOptions_sync(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->sync;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setDestroyOldData
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setDestroyOldData(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jboolean flag) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->destroy_old_data = flag;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: destroyOldData
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_BackupableDBOptions_destroyOldData(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->destroy_old_data;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setBackupLogFiles
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setBackupLogFiles(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jboolean flag) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->backup_log_files = flag;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: backupLogFiles
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_BackupableDBOptions_backupLogFiles(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->backup_log_files;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setBackupRateLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setBackupRateLimit(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jbackup_rate_limit) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->backup_rate_limit = jbackup_rate_limit;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: backupRateLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_BackupableDBOptions_backupRateLimit(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->backup_rate_limit;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setBackupRateLimiter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setBackupRateLimiter(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jrate_limiter_handle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ auto* sptr_rate_limiter =
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(
+ jrate_limiter_handle);
+ bopt->backup_rate_limiter = *sptr_rate_limiter;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setRestoreRateLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setRestoreRateLimit(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jrestore_rate_limit) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->restore_rate_limit = jrestore_rate_limit;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: restoreRateLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_BackupableDBOptions_restoreRateLimit(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->restore_rate_limit;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setRestoreRateLimiter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setRestoreRateLimiter(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jrate_limiter_handle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ auto* sptr_rate_limiter =
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(
+ jrate_limiter_handle);
+ bopt->restore_rate_limiter = *sptr_rate_limiter;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setShareFilesWithChecksum
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setShareFilesWithChecksum(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean flag) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->share_files_with_checksum = flag;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: shareFilesWithChecksum
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_BackupableDBOptions_shareFilesWithChecksum(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return bopt->share_files_with_checksum;
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setMaxBackgroundOperations
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setMaxBackgroundOperations(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jint max_background_operations) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->max_background_operations = static_cast<int>(max_background_operations);
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: maxBackgroundOperations
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_BackupableDBOptions_maxBackgroundOperations(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return static_cast<jint>(bopt->max_background_operations);
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: setCallbackTriggerIntervalSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_setCallbackTriggerIntervalSize(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jcallback_trigger_interval_size) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ bopt->callback_trigger_interval_size =
+ static_cast<uint64_t>(jcallback_trigger_interval_size);
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: callbackTriggerIntervalSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_BackupableDBOptions_callbackTriggerIntervalSize(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ return static_cast<jlong>(bopt->callback_trigger_interval_size);
+}
+
+/*
+ * Class: org_rocksdb_BackupableDBOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_BackupableDBOptions_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jopt*/,
+ jlong jhandle) {
+ auto* bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
+ assert(bopt != nullptr);
+ delete bopt;
+}
diff --git a/src/rocksdb/java/rocksjni/backupenginejni.cc b/src/rocksdb/java/rocksjni/backupenginejni.cc
new file mode 100644
index 00000000..e62b0b4f
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/backupenginejni.cc
@@ -0,0 +1,267 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling C++ rocksdb::BackupEngine methods from the Java side.
+
+#include <jni.h>
+#include <vector>
+
+#include "include/org_rocksdb_BackupEngine.h"
+#include "rocksdb/utilities/backupable_db.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: open
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_BackupEngine_open(JNIEnv* env, jclass /*jcls*/,
+ jlong env_handle,
+ jlong backupable_db_options_handle) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(env_handle);
+ auto* backupable_db_options = reinterpret_cast<rocksdb::BackupableDBOptions*>(
+ backupable_db_options_handle);
+ rocksdb::BackupEngine* backup_engine;
+ auto status = rocksdb::BackupEngine::Open(rocks_env, *backupable_db_options,
+ &backup_engine);
+
+ if (status.ok()) {
+ return reinterpret_cast<jlong>(backup_engine);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ return 0;
+ }
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: createNewBackup
+ * Signature: (JJZ)V
+ */
+void Java_org_rocksdb_BackupEngine_createNewBackup(
+ JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jlong db_handle,
+ jboolean jflush_before_backup) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ auto status = backup_engine->CreateNewBackup(
+ db, static_cast<bool>(jflush_before_backup));
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: createNewBackupWithMetadata
+ * Signature: (JJLjava/lang/String;Z)V
+ */
+void Java_org_rocksdb_BackupEngine_createNewBackupWithMetadata(
+ JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jlong db_handle,
+ jstring japp_metadata, jboolean jflush_before_backup) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+
+ jboolean has_exception = JNI_FALSE;
+ std::string app_metadata =
+ rocksdb::JniUtil::copyStdString(env, japp_metadata, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, "Could not copy jstring to std::string");
+ return;
+ }
+
+ auto status = backup_engine->CreateNewBackupWithMetadata(
+ db, app_metadata, static_cast<bool>(jflush_before_backup));
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: getBackupInfo
+ * Signature: (J)Ljava/util/List;
+ */
+jobject Java_org_rocksdb_BackupEngine_getBackupInfo(JNIEnv* env,
+ jobject /*jbe*/,
+ jlong jbe_handle) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ std::vector<rocksdb::BackupInfo> backup_infos;
+ backup_engine->GetBackupInfo(&backup_infos);
+ return rocksdb::BackupInfoListJni::getBackupInfo(env, backup_infos);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: getCorruptedBackups
+ * Signature: (J)[I
+ */
+jintArray Java_org_rocksdb_BackupEngine_getCorruptedBackups(JNIEnv* env,
+ jobject /*jbe*/,
+ jlong jbe_handle) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ std::vector<rocksdb::BackupID> backup_ids;
+ backup_engine->GetCorruptedBackups(&backup_ids);
+ // store backupids in int array
+ std::vector<jint> int_backup_ids(backup_ids.begin(), backup_ids.end());
+
+ // Store ints in java array
+ // Its ok to loose precision here (64->32)
+ jsize ret_backup_ids_size = static_cast<jsize>(backup_ids.size());
+ jintArray ret_backup_ids = env->NewIntArray(ret_backup_ids_size);
+ if (ret_backup_ids == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetIntArrayRegion(ret_backup_ids, 0, ret_backup_ids_size,
+ int_backup_ids.data());
+ return ret_backup_ids;
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: garbageCollect
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_BackupEngine_garbageCollect(JNIEnv* env, jobject /*jbe*/,
+ jlong jbe_handle) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ auto status = backup_engine->GarbageCollect();
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: purgeOldBackups
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_BackupEngine_purgeOldBackups(JNIEnv* env, jobject /*jbe*/,
+ jlong jbe_handle,
+ jint jnum_backups_to_keep) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ auto status = backup_engine->PurgeOldBackups(
+ static_cast<uint32_t>(jnum_backups_to_keep));
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: deleteBackup
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_BackupEngine_deleteBackup(JNIEnv* env, jobject /*jbe*/,
+ jlong jbe_handle,
+ jint jbackup_id) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ auto status =
+ backup_engine->DeleteBackup(static_cast<rocksdb::BackupID>(jbackup_id));
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: restoreDbFromBackup
+ * Signature: (JILjava/lang/String;Ljava/lang/String;J)V
+ */
+void Java_org_rocksdb_BackupEngine_restoreDbFromBackup(
+ JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jint jbackup_id,
+ jstring jdb_dir, jstring jwal_dir, jlong jrestore_options_handle) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ const char* db_dir = env->GetStringUTFChars(jdb_dir, nullptr);
+ if (db_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
+ if (wal_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_dir, db_dir);
+ return;
+ }
+ auto* restore_options =
+ reinterpret_cast<rocksdb::RestoreOptions*>(jrestore_options_handle);
+ auto status = backup_engine->RestoreDBFromBackup(
+ static_cast<rocksdb::BackupID>(jbackup_id), db_dir, wal_dir,
+ *restore_options);
+
+ env->ReleaseStringUTFChars(jwal_dir, wal_dir);
+ env->ReleaseStringUTFChars(jdb_dir, db_dir);
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: restoreDbFromLatestBackup
+ * Signature: (JLjava/lang/String;Ljava/lang/String;J)V
+ */
+void Java_org_rocksdb_BackupEngine_restoreDbFromLatestBackup(
+ JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jstring jdb_dir,
+ jstring jwal_dir, jlong jrestore_options_handle) {
+ auto* backup_engine = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ const char* db_dir = env->GetStringUTFChars(jdb_dir, nullptr);
+ if (db_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
+ if (wal_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_dir, db_dir);
+ return;
+ }
+ auto* restore_options =
+ reinterpret_cast<rocksdb::RestoreOptions*>(jrestore_options_handle);
+ auto status = backup_engine->RestoreDBFromLatestBackup(db_dir, wal_dir,
+ *restore_options);
+
+ env->ReleaseStringUTFChars(jwal_dir, wal_dir);
+ env->ReleaseStringUTFChars(jdb_dir, db_dir);
+
+ if (status.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+}
+
+/*
+ * Class: org_rocksdb_BackupEngine
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_BackupEngine_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jbe*/,
+ jlong jbe_handle) {
+ auto* be = reinterpret_cast<rocksdb::BackupEngine*>(jbe_handle);
+ assert(be != nullptr);
+ delete be;
+}
diff --git a/src/rocksdb/java/rocksjni/cassandra_compactionfilterjni.cc b/src/rocksdb/java/rocksjni/cassandra_compactionfilterjni.cc
new file mode 100644
index 00000000..799e25e3
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/cassandra_compactionfilterjni.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CassandraCompactionFilter.h"
+#include "utilities/cassandra/cassandra_compaction_filter.h"
+
+/*
+ * Class: org_rocksdb_CassandraCompactionFilter
+ * Method: createNewCassandraCompactionFilter0
+ * Signature: (ZI)J
+ */
+jlong Java_org_rocksdb_CassandraCompactionFilter_createNewCassandraCompactionFilter0(
+ JNIEnv* /*env*/, jclass /*jcls*/, jboolean purge_ttl_on_expiration,
+ jint gc_grace_period_in_seconds) {
+ auto* compaction_filter = new rocksdb::cassandra::CassandraCompactionFilter(
+ purge_ttl_on_expiration, gc_grace_period_in_seconds);
+ // set the native handle to our native compaction filter
+ return reinterpret_cast<jlong>(compaction_filter);
+}
diff --git a/src/rocksdb/java/rocksjni/cassandra_value_operator.cc b/src/rocksdb/java/rocksjni/cassandra_value_operator.cc
new file mode 100644
index 00000000..73b3dcc6
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/cassandra_value_operator.cc
@@ -0,0 +1,47 @@
+// Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory>
+#include <string>
+
+#include "include/org_rocksdb_CassandraValueMergeOperator.h"
+#include "rocksdb/db.h"
+#include "rocksdb/memtablerep.h"
+#include "rocksdb/merge_operator.h"
+#include "rocksdb/options.h"
+#include "rocksdb/slice_transform.h"
+#include "rocksdb/statistics.h"
+#include "rocksdb/table.h"
+#include "rocksjni/portal.h"
+#include "utilities/cassandra/merge_operator.h"
+
+/*
+ * Class: org_rocksdb_CassandraValueMergeOperator
+ * Method: newSharedCassandraValueMergeOperator
+ * Signature: (II)J
+ */
+jlong Java_org_rocksdb_CassandraValueMergeOperator_newSharedCassandraValueMergeOperator(
+ JNIEnv* /*env*/, jclass /*jclazz*/, jint gcGracePeriodInSeconds,
+ jint operands_limit) {
+ auto* op = new std::shared_ptr<rocksdb::MergeOperator>(
+ new rocksdb::cassandra::CassandraValueMergeOperator(
+ gcGracePeriodInSeconds, operands_limit));
+ return reinterpret_cast<jlong>(op);
+}
+
+/*
+ * Class: org_rocksdb_CassandraValueMergeOperator
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CassandraValueMergeOperator_disposeInternal(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* op =
+ reinterpret_cast<std::shared_ptr<rocksdb::MergeOperator>*>(jhandle);
+ delete op;
+}
diff --git a/src/rocksdb/java/rocksjni/checkpoint.cc b/src/rocksdb/java/rocksjni/checkpoint.cc
new file mode 100644
index 00000000..f67f0162
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/checkpoint.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::Checkpoint methods from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+#include "include/org_rocksdb_Checkpoint.h"
+#include "rocksdb/db.h"
+#include "rocksdb/utilities/checkpoint.h"
+#include "rocksjni/portal.h"
+/*
+ * Class: org_rocksdb_Checkpoint
+ * Method: newCheckpoint
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Checkpoint_newCheckpoint(JNIEnv* /*env*/,
+ jclass /*jclazz*/,
+ jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::Checkpoint* checkpoint;
+ rocksdb::Checkpoint::Create(db, &checkpoint);
+ return reinterpret_cast<jlong>(checkpoint);
+}
+
+/*
+ * Class: org_rocksdb_Checkpoint
+ * Method: dispose
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Checkpoint_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(jhandle);
+ assert(checkpoint != nullptr);
+ delete checkpoint;
+}
+
+/*
+ * Class: org_rocksdb_Checkpoint
+ * Method: createCheckpoint
+ * Signature: (JLjava/lang/String;)V
+ */
+void Java_org_rocksdb_Checkpoint_createCheckpoint(JNIEnv* env, jobject /*jobj*/,
+ jlong jcheckpoint_handle,
+ jstring jcheckpoint_path) {
+ const char* checkpoint_path = env->GetStringUTFChars(jcheckpoint_path, 0);
+ if (checkpoint_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(jcheckpoint_handle);
+ rocksdb::Status s = checkpoint->CreateCheckpoint(checkpoint_path);
+
+ env->ReleaseStringUTFChars(jcheckpoint_path, checkpoint_path);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
diff --git a/src/rocksdb/java/rocksjni/clock_cache.cc b/src/rocksdb/java/rocksjni/clock_cache.cc
new file mode 100644
index 00000000..b1cf0855
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/clock_cache.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::ClockCache.
+
+#include <jni.h>
+
+#include "cache/clock_cache.h"
+#include "include/org_rocksdb_ClockCache.h"
+
+/*
+ * Class: org_rocksdb_ClockCache
+ * Method: newClockCache
+ * Signature: (JIZ)J
+ */
+jlong Java_org_rocksdb_ClockCache_newClockCache(
+ JNIEnv* /*env*/, jclass /*jcls*/, jlong jcapacity, jint jnum_shard_bits,
+ jboolean jstrict_capacity_limit) {
+ auto* sptr_clock_cache =
+ new std::shared_ptr<rocksdb::Cache>(rocksdb::NewClockCache(
+ static_cast<size_t>(jcapacity), static_cast<int>(jnum_shard_bits),
+ static_cast<bool>(jstrict_capacity_limit)));
+ return reinterpret_cast<jlong>(sptr_clock_cache);
+}
+
+/*
+ * Class: org_rocksdb_ClockCache
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_ClockCache_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_clock_cache =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache>*>(jhandle);
+ delete sptr_clock_cache; // delete std::shared_ptr
+}
diff --git a/src/rocksdb/java/rocksjni/columnfamilyhandle.cc b/src/rocksdb/java/rocksjni/columnfamilyhandle.cc
new file mode 100644
index 00000000..ed280573
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/columnfamilyhandle.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::ColumnFamilyHandle.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "include/org_rocksdb_ColumnFamilyHandle.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_ColumnFamilyHandle
+ * Method: getName
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_ColumnFamilyHandle_getName(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* cfh = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jhandle);
+ std::string cf_name = cfh->GetName();
+ return rocksdb::JniUtil::copyBytes(env, cf_name);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyHandle
+ * Method: getID
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyHandle_getID(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* cfh = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jhandle);
+ const int32_t id = cfh->GetID();
+ return static_cast<jint>(id);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyHandle
+ * Method: getDescriptor
+ * Signature: (J)Lorg/rocksdb/ColumnFamilyDescriptor;
+ */
+jobject Java_org_rocksdb_ColumnFamilyHandle_getDescriptor(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* cfh = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jhandle);
+ rocksdb::ColumnFamilyDescriptor desc;
+ rocksdb::Status s = cfh->GetDescriptor(&desc);
+ if (s.ok()) {
+ return rocksdb::ColumnFamilyDescriptorJni::construct(env, &desc);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyHandle
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_ColumnFamilyHandle_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* cfh = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jhandle);
+ assert(cfh != nullptr);
+ delete cfh;
+}
diff --git a/src/rocksdb/java/rocksjni/compact_range_options.cc b/src/rocksdb/java/rocksjni/compact_range_options.cc
new file mode 100644
index 00000000..cc9ac859
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compact_range_options.cc
@@ -0,0 +1,196 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactRangeOptions.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompactRangeOptions.h"
+#include "rocksdb/options.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: newCompactRangeOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompactRangeOptions_newCompactRangeOptions(
+ JNIEnv* /*env*/, jclass /*jclazz*/) {
+ auto* options = new rocksdb::CompactRangeOptions();
+ return reinterpret_cast<jlong>(options);
+}
+
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: exclusiveManualCompaction
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompactRangeOptions_exclusiveManualCompaction(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return static_cast<jboolean>(options->exclusive_manual_compaction);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setExclusiveManualCompaction
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setExclusiveManualCompaction(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean exclusive_manual_compaction) {
+ auto* options =
+ reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->exclusive_manual_compaction = static_cast<bool>(exclusive_manual_compaction);
+}
+
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: bottommostLevelCompaction
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactRangeOptions_bottommostLevelCompaction(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return rocksdb::BottommostLevelCompactionJni::toJavaBottommostLevelCompaction(
+ options->bottommost_level_compaction);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setBottommostLevelCompaction
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setBottommostLevelCompaction(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jint bottommost_level_compaction) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->bottommost_level_compaction =
+ rocksdb::BottommostLevelCompactionJni::toCppBottommostLevelCompaction(bottommost_level_compaction);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: changeLevel
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompactRangeOptions_changeLevel
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return static_cast<jboolean>(options->change_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setChangeLevel
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setChangeLevel
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean change_level) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->change_level = static_cast<bool>(change_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: targetLevel
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactRangeOptions_targetLevel
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return static_cast<jint>(options->target_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setTargetLevel
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setTargetLevel
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jint target_level) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->target_level = static_cast<int>(target_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: targetPathId
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactRangeOptions_targetPathId
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return static_cast<jint>(options->target_path_id);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setTargetPathId
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setTargetPathId
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jint target_path_id) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->target_path_id = static_cast<uint32_t>(target_path_id);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: allowWriteStall
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompactRangeOptions_allowWriteStall
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return static_cast<jboolean>(options->allow_write_stall);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setAllowWriteStall
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setAllowWriteStall
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean allow_write_stall) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->allow_write_stall = static_cast<bool>(allow_write_stall);
+}
+
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: maxSubcompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactRangeOptions_maxSubcompactions
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ return static_cast<jint>(options->max_subcompactions);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: setMaxSubcompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_setMaxSubcompactions
+ (JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jint max_subcompactions) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ options->max_subcompactions = static_cast<uint32_t>(max_subcompactions);
+}
+
+/*
+ * Class: org_rocksdb_CompactRangeOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactRangeOptions_disposeInternal(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::CompactRangeOptions*>(jhandle);
+ delete options;
+}
diff --git a/src/rocksdb/java/rocksjni/compaction_filter.cc b/src/rocksdb/java/rocksjni/compaction_filter.cc
new file mode 100644
index 00000000..263bae05
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_filter.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionFilter.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_AbstractCompactionFilter.h"
+#include "rocksdb/compaction_filter.h"
+
+// <editor-fold desc="org.rocksdb.AbstractCompactionFilter">
+
+/*
+ * Class: org_rocksdb_AbstractCompactionFilter
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_AbstractCompactionFilter_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ auto* cf = reinterpret_cast<rocksdb::CompactionFilter*>(handle);
+ assert(cf != nullptr);
+ delete cf;
+}
+// </editor-fold>
diff --git a/src/rocksdb/java/rocksjni/compaction_filter_factory.cc b/src/rocksdb/java/rocksjni/compaction_filter_factory.cc
new file mode 100644
index 00000000..2ef0a774
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_filter_factory.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionFilterFactory.
+
+#include <jni.h>
+#include <memory>
+
+#include "include/org_rocksdb_AbstractCompactionFilterFactory.h"
+#include "rocksjni/compaction_filter_factory_jnicallback.h"
+
+/*
+ * Class: org_rocksdb_AbstractCompactionFilterFactory
+ * Method: createNewCompactionFilterFactory0
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_AbstractCompactionFilterFactory_createNewCompactionFilterFactory0(
+ JNIEnv* env, jobject jobj) {
+ auto* cff = new rocksdb::CompactionFilterFactoryJniCallback(env, jobj);
+ auto* ptr_sptr_cff =
+ new std::shared_ptr<rocksdb::CompactionFilterFactoryJniCallback>(cff);
+ return reinterpret_cast<jlong>(ptr_sptr_cff);
+}
+
+/*
+ * Class: org_rocksdb_AbstractCompactionFilterFactory
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_AbstractCompactionFilterFactory_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* ptr_sptr_cff = reinterpret_cast<
+ std::shared_ptr<rocksdb::CompactionFilterFactoryJniCallback>*>(jhandle);
+ delete ptr_sptr_cff;
+}
diff --git a/src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.cc b/src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.cc
new file mode 100644
index 00000000..c727a3e0
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::CompactionFilterFactory.
+
+#include "rocksjni/compaction_filter_factory_jnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+CompactionFilterFactoryJniCallback::CompactionFilterFactoryJniCallback(
+ JNIEnv* env, jobject jcompaction_filter_factory)
+ : JniCallback(env, jcompaction_filter_factory) {
+
+ // Note: The name of a CompactionFilterFactory will not change during
+ // it's lifetime, so we cache it in a global var
+ jmethodID jname_method_id =
+ AbstractCompactionFilterFactoryJni::getNameMethodId(env);
+ if(jname_method_id == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ jstring jname =
+ (jstring)env->CallObjectMethod(m_jcallback_obj, jname_method_id);
+ if(env->ExceptionCheck()) {
+ // exception thrown
+ return;
+ }
+ jboolean has_exception = JNI_FALSE;
+ m_name = JniUtil::copyString(env, jname, &has_exception); // also releases jname
+ if (has_exception == JNI_TRUE) {
+ // exception thrown
+ return;
+ }
+
+ m_jcreate_compaction_filter_methodid =
+ AbstractCompactionFilterFactoryJni::getCreateCompactionFilterMethodId(env);
+ if(m_jcreate_compaction_filter_methodid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+}
+
+const char* CompactionFilterFactoryJniCallback::Name() const {
+ return m_name.get();
+}
+
+std::unique_ptr<CompactionFilter> CompactionFilterFactoryJniCallback::CreateCompactionFilter(
+ const CompactionFilter::Context& context) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ jlong addr_compaction_filter = env->CallLongMethod(m_jcallback_obj,
+ m_jcreate_compaction_filter_methodid,
+ static_cast<jboolean>(context.is_full_compaction),
+ static_cast<jboolean>(context.is_manual_compaction));
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallLongMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return nullptr;
+ }
+
+ auto* cff = reinterpret_cast<CompactionFilter*>(addr_compaction_filter);
+
+ releaseJniEnv(attached_thread);
+
+ return std::unique_ptr<CompactionFilter>(cff);
+}
+
+} // namespace rocksdb
diff --git a/src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.h b/src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.h
new file mode 100644
index 00000000..10802edf
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_filter_factory_jnicallback.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::CompactionFilterFactory.
+
+#ifndef JAVA_ROCKSJNI_COMPACTION_FILTER_FACTORY_JNICALLBACK_H_
+#define JAVA_ROCKSJNI_COMPACTION_FILTER_FACTORY_JNICALLBACK_H_
+
+#include <jni.h>
+#include <memory>
+
+#include "rocksdb/compaction_filter.h"
+#include "rocksjni/jnicallback.h"
+
+namespace rocksdb {
+
+class CompactionFilterFactoryJniCallback : public JniCallback, public CompactionFilterFactory {
+ public:
+ CompactionFilterFactoryJniCallback(
+ JNIEnv* env, jobject jcompaction_filter_factory);
+ virtual std::unique_ptr<CompactionFilter> CreateCompactionFilter(
+ const CompactionFilter::Context& context);
+ virtual const char* Name() const;
+
+ private:
+ std::unique_ptr<const char[]> m_name;
+ jmethodID m_jcreate_compaction_filter_methodid;
+};
+
+} //namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_COMPACTION_FILTER_FACTORY_JNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/compaction_job_info.cc b/src/rocksdb/java/rocksjni/compaction_job_info.cc
new file mode 100644
index 00000000..6af6efcb
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_job_info.cc
@@ -0,0 +1,222 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionJobInfo.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompactionJobInfo.h"
+#include "rocksdb/listener.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: newCompactionJobInfo
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompactionJobInfo_newCompactionJobInfo(
+ JNIEnv*, jclass) {
+ auto* compact_job_info = new rocksdb::CompactionJobInfo();
+ return reinterpret_cast<jlong>(compact_job_info);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactionJobInfo_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ delete compact_job_info;
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: columnFamilyName
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_CompactionJobInfo_columnFamilyName(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return rocksdb::JniUtil::copyBytes(
+ env, compact_job_info->cf_name);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: status
+ * Signature: (J)Lorg/rocksdb/Status;
+ */
+jobject Java_org_rocksdb_CompactionJobInfo_status(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return rocksdb::StatusJni::construct(
+ env, compact_job_info->status);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: threadId
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobInfo_threadId(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return static_cast<jlong>(compact_job_info->thread_id);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: jobId
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionJobInfo_jobId(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return static_cast<jint>(compact_job_info->job_id);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: baseInputLevel
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionJobInfo_baseInputLevel(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return static_cast<jint>(compact_job_info->base_input_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: outputLevel
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionJobInfo_outputLevel(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return static_cast<jint>(compact_job_info->output_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: inputFiles
+ * Signature: (J)[Ljava/lang/String;
+ */
+jobjectArray Java_org_rocksdb_CompactionJobInfo_inputFiles(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return rocksdb::JniUtil::toJavaStrings(
+ env, &compact_job_info->input_files);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: outputFiles
+ * Signature: (J)[Ljava/lang/String;
+ */
+jobjectArray Java_org_rocksdb_CompactionJobInfo_outputFiles(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return rocksdb::JniUtil::toJavaStrings(
+ env, &compact_job_info->output_files);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: tableProperties
+ * Signature: (J)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_CompactionJobInfo_tableProperties(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ auto* map = &compact_job_info->table_properties;
+
+ jobject jhash_map = rocksdb::HashMapJni::construct(
+ env, static_cast<uint32_t>(map->size()));
+ if (jhash_map == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const std::string, std::shared_ptr<const rocksdb::TableProperties>, jobject, jobject> fn_map_kv =
+ [env](const std::pair<const std::string, std::shared_ptr<const rocksdb::TableProperties>>& kv) {
+ jstring jkey = rocksdb::JniUtil::toJavaString(env, &(kv.first), false);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ jobject jtable_properties = rocksdb::TablePropertiesJni::fromCppTableProperties(
+ env, *(kv.second.get()));
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ env->DeleteLocalRef(jkey);
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ return std::unique_ptr<std::pair<jobject, jobject>>(
+ new std::pair<jobject, jobject>(static_cast<jobject>(jkey), jtable_properties));
+ };
+
+ if (!rocksdb::HashMapJni::putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jhash_map;
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: compactionReason
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_CompactionJobInfo_compactionReason(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return rocksdb::CompactionReasonJni::toJavaCompactionReason(
+ compact_job_info->compaction_reason);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: compression
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_CompactionJobInfo_compression(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ return rocksdb::CompressionTypeJni::toJavaCompressionType(
+ compact_job_info->compression);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobInfo
+ * Method: stats
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobInfo_stats(
+ JNIEnv *, jclass, jlong jhandle) {
+ auto* compact_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jhandle);
+ auto* stats = new rocksdb::CompactionJobStats();
+ stats->Add(compact_job_info->stats);
+ return reinterpret_cast<jlong>(stats);
+}
diff --git a/src/rocksdb/java/rocksjni/compaction_job_stats.cc b/src/rocksdb/java/rocksjni/compaction_job_stats.cc
new file mode 100644
index 00000000..7d13dd12
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_job_stats.cc
@@ -0,0 +1,361 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionJobStats.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompactionJobStats.h"
+#include "rocksdb/compaction_job_stats.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: newCompactionJobStats
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_newCompactionJobStats(
+ JNIEnv*, jclass) {
+ auto* compact_job_stats = new rocksdb::CompactionJobStats();
+ return reinterpret_cast<jlong>(compact_job_stats);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactionJobStats_disposeInternal(
+ JNIEnv *, jobject, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ delete compact_job_stats;
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: reset
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactionJobStats_reset(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ compact_job_stats->Reset();
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: add
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_CompactionJobStats_add(
+ JNIEnv*, jclass, jlong jhandle, jlong jother_handle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ auto* other_compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jother_handle);
+ compact_job_stats->Add(*other_compact_job_stats);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: elapsedMicros
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_elapsedMicros(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(compact_job_stats->elapsed_micros);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numInputRecords
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numInputRecords(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(compact_job_stats->num_input_records);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numInputFiles
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numInputFiles(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(compact_job_stats->num_input_files);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numInputFilesAtOutputLevel
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numInputFilesAtOutputLevel(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_input_files_at_output_level);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numOutputRecords
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numOutputRecords(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_output_records);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numOutputFiles
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numOutputFiles(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_output_files);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: isManualCompaction
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompactionJobStats_isManualCompaction(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ if (compact_job_stats->is_manual_compaction) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: totalInputBytes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_totalInputBytes(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->total_input_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: totalOutputBytes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_totalOutputBytes(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->total_output_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numRecordsReplaced
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numRecordsReplaced(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_records_replaced);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: totalInputRawKeyBytes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_totalInputRawKeyBytes(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->total_input_raw_key_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: totalInputRawValueBytes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_totalInputRawValueBytes(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->total_input_raw_value_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numInputDeletionRecords
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numInputDeletionRecords(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_input_deletion_records);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numExpiredDeletionRecords
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numExpiredDeletionRecords(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_expired_deletion_records);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numCorruptKeys
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numCorruptKeys(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_corrupt_keys);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: fileWriteNanos
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_fileWriteNanos(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->file_write_nanos);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: fileRangeSyncNanos
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_fileRangeSyncNanos(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->file_range_sync_nanos);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: fileFsyncNanos
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_fileFsyncNanos(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->file_fsync_nanos);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: filePrepareWriteNanos
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_filePrepareWriteNanos(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->file_prepare_write_nanos);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: smallestOutputKeyPrefix
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_CompactionJobStats_smallestOutputKeyPrefix(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return rocksdb::JniUtil::copyBytes(env,
+ compact_job_stats->smallest_output_key_prefix);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: largestOutputKeyPrefix
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_CompactionJobStats_largestOutputKeyPrefix(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return rocksdb::JniUtil::copyBytes(env,
+ compact_job_stats->largest_output_key_prefix);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numSingleDelFallthru
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numSingleDelFallthru(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_single_del_fallthru);
+}
+
+/*
+ * Class: org_rocksdb_CompactionJobStats
+ * Method: numSingleDelMismatch
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionJobStats_numSingleDelMismatch(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_job_stats =
+ reinterpret_cast<rocksdb::CompactionJobStats*>(jhandle);
+ return static_cast<jlong>(
+ compact_job_stats->num_single_del_mismatch);
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/compaction_options.cc b/src/rocksdb/java/rocksjni/compaction_options.cc
new file mode 100644
index 00000000..6aaabea7
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_options.cc
@@ -0,0 +1,116 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionOptions.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompactionOptions.h"
+#include "rocksdb/options.h"
+#include "rocksjni/portal.h"
+
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: newCompactionOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompactionOptions_newCompactionOptions(
+ JNIEnv*, jclass) {
+ auto* compact_opts = new rocksdb::CompactionOptions();
+ return reinterpret_cast<jlong>(compact_opts);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactionOptions_disposeInternal(
+ JNIEnv *, jobject, jlong jhandle) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ delete compact_opts;
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: compression
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_CompactionOptions_compression(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ return rocksdb::CompressionTypeJni::toJavaCompressionType(
+ compact_opts->compression);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: setCompression
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_CompactionOptions_setCompression(
+ JNIEnv*, jclass, jlong jhandle, jbyte jcompression_type_value) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ compact_opts->compression =
+ rocksdb::CompressionTypeJni::toCppCompressionType(
+ jcompression_type_value);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: outputFileSizeLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionOptions_outputFileSizeLimit(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ return static_cast<jlong>(
+ compact_opts->output_file_size_limit);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: setOutputFileSizeLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_CompactionOptions_setOutputFileSizeLimit(
+ JNIEnv*, jclass, jlong jhandle, jlong joutput_file_size_limit) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ compact_opts->output_file_size_limit =
+ static_cast<uint64_t>(joutput_file_size_limit);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: maxSubcompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionOptions_maxSubcompactions(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ return static_cast<jint>(
+ compact_opts->max_subcompactions);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptions
+ * Method: setMaxSubcompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactionOptions_setMaxSubcompactions(
+ JNIEnv*, jclass, jlong jhandle, jint jmax_subcompactions) {
+ auto* compact_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jhandle);
+ compact_opts->max_subcompactions =
+ static_cast<uint32_t>(jmax_subcompactions);
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/compaction_options_fifo.cc b/src/rocksdb/java/rocksjni/compaction_options_fifo.cc
new file mode 100644
index 00000000..b7c445fd
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_options_fifo.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionOptionsFIFO.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompactionOptionsFIFO.h"
+#include "rocksdb/advanced_options.h"
+
+/*
+ * Class: org_rocksdb_CompactionOptionsFIFO
+ * Method: newCompactionOptionsFIFO
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompactionOptionsFIFO_newCompactionOptionsFIFO(
+ JNIEnv*, jclass) {
+ const auto* opt = new rocksdb::CompactionOptionsFIFO();
+ return reinterpret_cast<jlong>(opt);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsFIFO
+ * Method: setMaxTableFilesSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_CompactionOptionsFIFO_setMaxTableFilesSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_table_files_size) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(jhandle);
+ opt->max_table_files_size = static_cast<uint64_t>(jmax_table_files_size);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsFIFO
+ * Method: maxTableFilesSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_CompactionOptionsFIFO_maxTableFilesSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(jhandle);
+ return static_cast<jlong>(opt->max_table_files_size);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsFIFO
+ * Method: setAllowCompaction
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_CompactionOptionsFIFO_setAllowCompaction(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow_compaction) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(jhandle);
+ opt->allow_compaction = static_cast<bool>(allow_compaction);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsFIFO
+ * Method: allowCompaction
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompactionOptionsFIFO_allowCompaction(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(jhandle);
+ return static_cast<jboolean>(opt->allow_compaction);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsFIFO
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactionOptionsFIFO_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ delete reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/compaction_options_universal.cc b/src/rocksdb/java/rocksjni/compaction_options_universal.cc
new file mode 100644
index 00000000..7ca51988
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compaction_options_universal.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionOptionsUniversal.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompactionOptionsUniversal.h"
+#include "rocksdb/advanced_options.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: newCompactionOptionsUniversal
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompactionOptionsUniversal_newCompactionOptionsUniversal(
+ JNIEnv*, jclass) {
+ const auto* opt = new rocksdb::CompactionOptionsUniversal();
+ return reinterpret_cast<jlong>(opt);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setSizeRatio
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setSizeRatio(
+ JNIEnv*, jobject, jlong jhandle, jint jsize_ratio) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->size_ratio = static_cast<unsigned int>(jsize_ratio);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: sizeRatio
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionOptionsUniversal_sizeRatio(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return static_cast<jint>(opt->size_ratio);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setMinMergeWidth
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setMinMergeWidth(
+ JNIEnv*, jobject, jlong jhandle, jint jmin_merge_width) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->min_merge_width = static_cast<unsigned int>(jmin_merge_width);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: minMergeWidth
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionOptionsUniversal_minMergeWidth(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return static_cast<jint>(opt->min_merge_width);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setMaxMergeWidth
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setMaxMergeWidth(
+ JNIEnv*, jobject, jlong jhandle, jint jmax_merge_width) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->max_merge_width = static_cast<unsigned int>(jmax_merge_width);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: maxMergeWidth
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionOptionsUniversal_maxMergeWidth(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return static_cast<jint>(opt->max_merge_width);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setMaxSizeAmplificationPercent
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setMaxSizeAmplificationPercent(
+ JNIEnv*, jobject, jlong jhandle, jint jmax_size_amplification_percent) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->max_size_amplification_percent =
+ static_cast<unsigned int>(jmax_size_amplification_percent);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: maxSizeAmplificationPercent
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionOptionsUniversal_maxSizeAmplificationPercent(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return static_cast<jint>(opt->max_size_amplification_percent);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setCompressionSizePercent
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setCompressionSizePercent(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jcompression_size_percent) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->compression_size_percent =
+ static_cast<unsigned int>(jcompression_size_percent);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: compressionSizePercent
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompactionOptionsUniversal_compressionSizePercent(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return static_cast<jint>(opt->compression_size_percent);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setStopStyle
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setStopStyle(
+ JNIEnv*, jobject, jlong jhandle, jbyte jstop_style_value) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->stop_style = rocksdb::CompactionStopStyleJni::toCppCompactionStopStyle(
+ jstop_style_value);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: stopStyle
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_CompactionOptionsUniversal_stopStyle(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return rocksdb::CompactionStopStyleJni::toJavaCompactionStopStyle(
+ opt->stop_style);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: setAllowTrivialMove
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_setAllowTrivialMove(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_trivial_move) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ opt->allow_trivial_move = static_cast<bool>(jallow_trivial_move);
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: allowTrivialMove
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompactionOptionsUniversal_allowTrivialMove(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+ return opt->allow_trivial_move;
+}
+
+/*
+ * Class: org_rocksdb_CompactionOptionsUniversal
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompactionOptionsUniversal_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ delete reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/comparator.cc b/src/rocksdb/java/rocksjni/comparator.cc
new file mode 100644
index 00000000..13f8feb6
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/comparator.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::Comparator.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <functional>
+#include <string>
+
+#include "include/org_rocksdb_Comparator.h"
+#include "include/org_rocksdb_DirectComparator.h"
+#include "include/org_rocksdb_NativeComparatorWrapper.h"
+#include "rocksjni/comparatorjnicallback.h"
+#include "rocksjni/portal.h"
+
+// <editor-fold desc="org.rocksdb.Comparator>
+
+/*
+ * Class: org_rocksdb_Comparator
+ * Method: createNewComparator0
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_Comparator_createNewComparator0(JNIEnv* env,
+ jobject jobj,
+ jlong copt_handle) {
+ auto* copt =
+ reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(copt_handle);
+ auto* c = new rocksdb::ComparatorJniCallback(env, jobj, copt);
+ return reinterpret_cast<jlong>(c);
+}
+// </editor-fold>
+
+// <editor-fold desc="org.rocksdb.DirectComparator>
+
+/*
+ * Class: org_rocksdb_DirectComparator
+ * Method: createNewDirectComparator0
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_DirectComparator_createNewDirectComparator0(
+ JNIEnv* env, jobject jobj, jlong copt_handle) {
+ auto* copt =
+ reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(copt_handle);
+ auto* c = new rocksdb::DirectComparatorJniCallback(env, jobj, copt);
+ return reinterpret_cast<jlong>(c);
+}
+
+/*
+ * Class: org_rocksdb_NativeComparatorWrapper
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_NativeComparatorWrapper_disposeInternal(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jcomparator_handle) {
+ auto* comparator = reinterpret_cast<rocksdb::Comparator*>(jcomparator_handle);
+ delete comparator;
+}
+// </editor-fold>
diff --git a/src/rocksdb/java/rocksjni/comparatorjnicallback.cc b/src/rocksdb/java/rocksjni/comparatorjnicallback.cc
new file mode 100644
index 00000000..5b4d11b0
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/comparatorjnicallback.cc
@@ -0,0 +1,340 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Comparator.
+
+#include "rocksjni/comparatorjnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+BaseComparatorJniCallback::BaseComparatorJniCallback(
+ JNIEnv* env, jobject jComparator,
+ const ComparatorJniCallbackOptions* copt)
+ : JniCallback(env, jComparator),
+ mtx_compare(new port::Mutex(copt->use_adaptive_mutex)),
+ mtx_findShortestSeparator(new port::Mutex(copt->use_adaptive_mutex)) {
+
+ // Note: The name of a Comparator will not change during it's lifetime,
+ // so we cache it in a global var
+ jmethodID jNameMethodId = AbstractComparatorJni::getNameMethodId(env);
+ if(jNameMethodId == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+ jstring jsName = (jstring)env->CallObjectMethod(m_jcallback_obj, jNameMethodId);
+ if(env->ExceptionCheck()) {
+ // exception thrown
+ return;
+ }
+ jboolean has_exception = JNI_FALSE;
+ m_name = JniUtil::copyString(env, jsName,
+ &has_exception); // also releases jsName
+ if (has_exception == JNI_TRUE) {
+ // exception thrown
+ return;
+ }
+
+ m_jCompareMethodId = AbstractComparatorJni::getCompareMethodId(env);
+ if(m_jCompareMethodId == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ m_jFindShortestSeparatorMethodId =
+ AbstractComparatorJni::getFindShortestSeparatorMethodId(env);
+ if(m_jFindShortestSeparatorMethodId == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ m_jFindShortSuccessorMethodId =
+ AbstractComparatorJni::getFindShortSuccessorMethodId(env);
+ if(m_jFindShortSuccessorMethodId == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+}
+
+const char* BaseComparatorJniCallback::Name() const {
+ return m_name.get();
+}
+
+int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ // TODO(adamretter): slice objects can potentially be cached using thread
+ // local variables to avoid locking. Could make this configurable depending on
+ // performance.
+ mtx_compare.get()->Lock();
+
+ bool pending_exception =
+ AbstractSliceJni::setHandle(env, m_jSliceA, &a, JNI_FALSE);
+ if(pending_exception) {
+ if(env->ExceptionCheck()) {
+ // exception thrown from setHandle or descendant
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return 0;
+ }
+
+ pending_exception =
+ AbstractSliceJni::setHandle(env, m_jSliceB, &b, JNI_FALSE);
+ if(pending_exception) {
+ if(env->ExceptionCheck()) {
+ // exception thrown from setHandle or descendant
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return 0;
+ }
+
+ jint result =
+ env->CallIntMethod(m_jcallback_obj, m_jCompareMethodId, m_jSliceA,
+ m_jSliceB);
+
+ mtx_compare.get()->Unlock();
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallIntMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ result = 0; // we could not get a result from java callback so use 0
+ }
+
+ releaseJniEnv(attached_thread);
+
+ return result;
+}
+
+void BaseComparatorJniCallback::FindShortestSeparator(
+ std::string* start, const Slice& limit) const {
+ if (start == nullptr) {
+ return;
+ }
+
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ const char* startUtf = start->c_str();
+ jstring jsStart = env->NewStringUTF(startUtf);
+ if(jsStart == nullptr) {
+ // unable to construct string
+ if(env->ExceptionCheck()) {
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return;
+ }
+ if(env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jsStart);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ // TODO(adamretter): slice object can potentially be cached using thread local
+ // variable to avoid locking. Could make this configurable depending on
+ // performance.
+ mtx_findShortestSeparator.get()->Lock();
+
+ bool pending_exception =
+ AbstractSliceJni::setHandle(env, m_jSliceLimit, &limit, JNI_FALSE);
+ if(pending_exception) {
+ if(env->ExceptionCheck()) {
+ // exception thrown from setHandle or descendant
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ if(jsStart != nullptr) {
+ env->DeleteLocalRef(jsStart);
+ }
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ jstring jsResultStart =
+ (jstring)env->CallObjectMethod(m_jcallback_obj,
+ m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit);
+
+ mtx_findShortestSeparator.get()->Unlock();
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallObjectMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jsStart);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ env->DeleteLocalRef(jsStart);
+
+ if (jsResultStart != nullptr) {
+ // update start with result
+ jboolean has_exception = JNI_FALSE;
+ std::unique_ptr<const char[]> result_start = JniUtil::copyString(env, jsResultStart,
+ &has_exception); // also releases jsResultStart
+ if (has_exception == JNI_TRUE) {
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ start->assign(result_start.get());
+ }
+ releaseJniEnv(attached_thread);
+}
+
+void BaseComparatorJniCallback::FindShortSuccessor(
+ std::string* key) const {
+ if (key == nullptr) {
+ return;
+ }
+
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ const char* keyUtf = key->c_str();
+ jstring jsKey = env->NewStringUTF(keyUtf);
+ if(jsKey == nullptr) {
+ // unable to construct string
+ if(env->ExceptionCheck()) {
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return;
+ } else if(env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jsKey);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ jstring jsResultKey =
+ (jstring)env->CallObjectMethod(m_jcallback_obj,
+ m_jFindShortSuccessorMethodId, jsKey);
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallObjectMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jsKey);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ env->DeleteLocalRef(jsKey);
+
+ if (jsResultKey != nullptr) {
+ // updates key with result, also releases jsResultKey.
+ jboolean has_exception = JNI_FALSE;
+ std::unique_ptr<const char[]> result_key = JniUtil::copyString(env, jsResultKey,
+ &has_exception); // also releases jsResultKey
+ if (has_exception == JNI_TRUE) {
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ key->assign(result_key.get());
+ }
+
+ releaseJniEnv(attached_thread);
+}
+
+ComparatorJniCallback::ComparatorJniCallback(
+ JNIEnv* env, jobject jComparator,
+ const ComparatorJniCallbackOptions* copt) :
+ BaseComparatorJniCallback(env, jComparator, copt) {
+ m_jSliceA = env->NewGlobalRef(SliceJni::construct0(env));
+ if(m_jSliceA == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ m_jSliceB = env->NewGlobalRef(SliceJni::construct0(env));
+ if(m_jSliceB == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ m_jSliceLimit = env->NewGlobalRef(SliceJni::construct0(env));
+ if(m_jSliceLimit == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+}
+
+ComparatorJniCallback::~ComparatorJniCallback() {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ if(m_jSliceA != nullptr) {
+ env->DeleteGlobalRef(m_jSliceA);
+ }
+
+ if(m_jSliceB != nullptr) {
+ env->DeleteGlobalRef(m_jSliceB);
+ }
+
+ if(m_jSliceLimit != nullptr) {
+ env->DeleteGlobalRef(m_jSliceLimit);
+ }
+
+ releaseJniEnv(attached_thread);
+}
+
+DirectComparatorJniCallback::DirectComparatorJniCallback(
+ JNIEnv* env, jobject jComparator,
+ const ComparatorJniCallbackOptions* copt) :
+ BaseComparatorJniCallback(env, jComparator, copt) {
+ m_jSliceA = env->NewGlobalRef(DirectSliceJni::construct0(env));
+ if(m_jSliceA == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ m_jSliceB = env->NewGlobalRef(DirectSliceJni::construct0(env));
+ if(m_jSliceB == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ m_jSliceLimit = env->NewGlobalRef(DirectSliceJni::construct0(env));
+ if(m_jSliceLimit == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+}
+
+DirectComparatorJniCallback::~DirectComparatorJniCallback() {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ if(m_jSliceA != nullptr) {
+ env->DeleteGlobalRef(m_jSliceA);
+ }
+
+ if(m_jSliceB != nullptr) {
+ env->DeleteGlobalRef(m_jSliceB);
+ }
+
+ if(m_jSliceLimit != nullptr) {
+ env->DeleteGlobalRef(m_jSliceLimit);
+ }
+
+ releaseJniEnv(attached_thread);
+}
+} // namespace rocksdb
diff --git a/src/rocksdb/java/rocksjni/comparatorjnicallback.h b/src/rocksdb/java/rocksjni/comparatorjnicallback.h
new file mode 100644
index 00000000..0aa9cc0a
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/comparatorjnicallback.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Comparator and rocksdb::DirectComparator.
+
+#ifndef JAVA_ROCKSJNI_COMPARATORJNICALLBACK_H_
+#define JAVA_ROCKSJNI_COMPARATORJNICALLBACK_H_
+
+#include <jni.h>
+#include <memory>
+#include <string>
+#include "rocksjni/jnicallback.h"
+#include "rocksdb/comparator.h"
+#include "rocksdb/slice.h"
+#include "port/port.h"
+
+namespace rocksdb {
+
+struct ComparatorJniCallbackOptions {
+ // Use adaptive mutex, which spins in the user space before resorting
+ // to kernel. This could reduce context switch when the mutex is not
+ // heavily contended. However, if the mutex is hot, we could end up
+ // wasting spin time.
+ // Default: false
+ bool use_adaptive_mutex;
+
+ ComparatorJniCallbackOptions() : use_adaptive_mutex(false) {
+ }
+};
+
+/**
+ * This class acts as a bridge between C++
+ * and Java. The methods in this class will be
+ * called back from the RocksDB storage engine (C++)
+ * we then callback to the appropriate Java method
+ * this enables Comparators to be implemented in Java.
+ *
+ * The design of this Comparator caches the Java Slice
+ * objects that are used in the compare and findShortestSeparator
+ * method callbacks. Instead of creating new objects for each callback
+ * of those functions, by reuse via setHandle we are a lot
+ * faster; Unfortunately this means that we have to
+ * introduce independent locking in regions of each of those methods
+ * via the mutexs mtx_compare and mtx_findShortestSeparator respectively
+ */
+class BaseComparatorJniCallback : public JniCallback, public Comparator {
+ public:
+ BaseComparatorJniCallback(
+ JNIEnv* env, jobject jComparator,
+ const ComparatorJniCallbackOptions* copt);
+ virtual const char* Name() const;
+ virtual int Compare(const Slice& a, const Slice& b) const;
+ virtual void FindShortestSeparator(
+ std::string* start, const Slice& limit) const;
+ virtual void FindShortSuccessor(std::string* key) const;
+
+ private:
+ // used for synchronisation in compare method
+ std::unique_ptr<port::Mutex> mtx_compare;
+ // used for synchronisation in findShortestSeparator method
+ std::unique_ptr<port::Mutex> mtx_findShortestSeparator;
+ std::unique_ptr<const char[]> m_name;
+ jmethodID m_jCompareMethodId;
+ jmethodID m_jFindShortestSeparatorMethodId;
+ jmethodID m_jFindShortSuccessorMethodId;
+
+ protected:
+ jobject m_jSliceA;
+ jobject m_jSliceB;
+ jobject m_jSliceLimit;
+};
+
+class ComparatorJniCallback : public BaseComparatorJniCallback {
+ public:
+ ComparatorJniCallback(
+ JNIEnv* env, jobject jComparator,
+ const ComparatorJniCallbackOptions* copt);
+ ~ComparatorJniCallback();
+};
+
+class DirectComparatorJniCallback : public BaseComparatorJniCallback {
+ public:
+ DirectComparatorJniCallback(
+ JNIEnv* env, jobject jComparator,
+ const ComparatorJniCallbackOptions* copt);
+ ~DirectComparatorJniCallback();
+};
+} // namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_COMPARATORJNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/compression_options.cc b/src/rocksdb/java/rocksjni/compression_options.cc
new file mode 100644
index 00000000..f0155eb3
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/compression_options.cc
@@ -0,0 +1,164 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompressionOptions.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_CompressionOptions.h"
+#include "rocksdb/advanced_options.h"
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: newCompressionOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_CompressionOptions_newCompressionOptions(
+ JNIEnv*, jclass) {
+ const auto* opt = new rocksdb::CompressionOptions();
+ return reinterpret_cast<jlong>(opt);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: setWindowBits
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompressionOptions_setWindowBits(
+ JNIEnv*, jobject, jlong jhandle, jint jwindow_bits) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ opt->window_bits = static_cast<int>(jwindow_bits);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: windowBits
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompressionOptions_windowBits(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ return static_cast<jint>(opt->window_bits);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: setLevel
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompressionOptions_setLevel(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ opt->level = static_cast<int>(jlevel);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: level
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompressionOptions_level(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ return static_cast<jint>(opt->level);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: setStrategy
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompressionOptions_setStrategy(
+ JNIEnv*, jobject, jlong jhandle, jint jstrategy) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ opt->strategy = static_cast<int>(jstrategy);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: strategy
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompressionOptions_strategy(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ return static_cast<jint>(opt->strategy);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: setMaxDictBytes
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompressionOptions_setMaxDictBytes(
+ JNIEnv*, jobject, jlong jhandle, jint jmax_dict_bytes) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ opt->max_dict_bytes = static_cast<uint32_t>(jmax_dict_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: maxDictBytes
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompressionOptions_maxDictBytes(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ return static_cast<jint>(opt->max_dict_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: setZstdMaxTrainBytes
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_CompressionOptions_setZstdMaxTrainBytes(
+ JNIEnv*, jobject, jlong jhandle, jint jzstd_max_train_bytes) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ opt->zstd_max_train_bytes = static_cast<uint32_t>(jzstd_max_train_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: zstdMaxTrainBytes
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_CompressionOptions_zstdMaxTrainBytes(
+ JNIEnv *, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ return static_cast<jint>(opt->zstd_max_train_bytes);
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: setEnabled
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_CompressionOptions_setEnabled(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenabled) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ opt->enabled = jenabled == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: enabled
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_CompressionOptions_enabled(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+ return static_cast<bool>(opt->enabled);
+}
+/*
+ * Class: org_rocksdb_CompressionOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_CompressionOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ delete reinterpret_cast<rocksdb::CompressionOptions*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/env.cc b/src/rocksdb/java/rocksjni/env.cc
new file mode 100644
index 00000000..ed54bd36
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/env.cc
@@ -0,0 +1,234 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::Env methods from Java side.
+
+#include <jni.h>
+#include <vector>
+
+#include "portal.h"
+#include "rocksdb/env.h"
+#include "include/org_rocksdb_Env.h"
+#include "include/org_rocksdb_HdfsEnv.h"
+#include "include/org_rocksdb_RocksEnv.h"
+#include "include/org_rocksdb_RocksMemEnv.h"
+#include "include/org_rocksdb_TimedEnv.h"
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: getDefaultEnvInternal
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_Env_getDefaultEnvInternal(
+ JNIEnv*, jclass) {
+ return reinterpret_cast<jlong>(rocksdb::Env::Default());
+}
+
+/*
+ * Class: org_rocksdb_RocksEnv
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksEnv_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* e = reinterpret_cast<rocksdb::Env*>(jhandle);
+ assert(e != nullptr);
+ delete e;
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: setBackgroundThreads
+ * Signature: (JIB)V
+ */
+void Java_org_rocksdb_Env_setBackgroundThreads(
+ JNIEnv*, jobject, jlong jhandle, jint jnum, jbyte jpriority_value) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ rocks_env->SetBackgroundThreads(static_cast<int>(jnum),
+ rocksdb::PriorityJni::toCppPriority(jpriority_value));
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: getBackgroundThreads
+ * Signature: (JB)I
+ */
+jint Java_org_rocksdb_Env_getBackgroundThreads(
+ JNIEnv*, jobject, jlong jhandle, jbyte jpriority_value) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ const int num = rocks_env->GetBackgroundThreads(
+ rocksdb::PriorityJni::toCppPriority(jpriority_value));
+ return static_cast<jint>(num);
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: getThreadPoolQueueLen
+ * Signature: (JB)I
+ */
+jint Java_org_rocksdb_Env_getThreadPoolQueueLen(
+ JNIEnv*, jobject, jlong jhandle, jbyte jpriority_value) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ const int queue_len = rocks_env->GetThreadPoolQueueLen(
+ rocksdb::PriorityJni::toCppPriority(jpriority_value));
+ return static_cast<jint>(queue_len);
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: incBackgroundThreadsIfNeeded
+ * Signature: (JIB)V
+ */
+void Java_org_rocksdb_Env_incBackgroundThreadsIfNeeded(
+ JNIEnv*, jobject, jlong jhandle, jint jnum, jbyte jpriority_value) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ rocks_env->IncBackgroundThreadsIfNeeded(static_cast<int>(jnum),
+ rocksdb::PriorityJni::toCppPriority(jpriority_value));
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: lowerThreadPoolIOPriority
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Env_lowerThreadPoolIOPriority(
+ JNIEnv*, jobject, jlong jhandle, jbyte jpriority_value) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ rocks_env->LowerThreadPoolIOPriority(
+ rocksdb::PriorityJni::toCppPriority(jpriority_value));
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: lowerThreadPoolCPUPriority
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Env_lowerThreadPoolCPUPriority(
+ JNIEnv*, jobject, jlong jhandle, jbyte jpriority_value) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ rocks_env->LowerThreadPoolCPUPriority(
+ rocksdb::PriorityJni::toCppPriority(jpriority_value));
+}
+
+/*
+ * Class: org_rocksdb_Env
+ * Method: getThreadList
+ * Signature: (J)[Lorg/rocksdb/ThreadStatus;
+ */
+jobjectArray Java_org_rocksdb_Env_getThreadList(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
+ std::vector<rocksdb::ThreadStatus> thread_status;
+ rocksdb::Status s = rocks_env->GetThreadList(&thread_status);
+ if (!s.ok()) {
+ // error, throw exception
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ // object[]
+ const jsize len = static_cast<jsize>(thread_status.size());
+ jobjectArray jthread_status =
+ env->NewObjectArray(len, rocksdb::ThreadStatusJni::getJClass(env), nullptr);
+ if (jthread_status == nullptr) {
+ // an exception occurred
+ return nullptr;
+ }
+ for (jsize i = 0; i < len; ++i) {
+ jobject jts =
+ rocksdb::ThreadStatusJni::construct(env, &(thread_status[i]));
+ env->SetObjectArrayElement(jthread_status, i, jts);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ env->DeleteLocalRef(jthread_status);
+ return nullptr;
+ }
+ }
+
+ return jthread_status;
+}
+
+/*
+ * Class: org_rocksdb_RocksMemEnv
+ * Method: createMemEnv
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RocksMemEnv_createMemEnv(
+ JNIEnv*, jclass, jlong jbase_env_handle) {
+ auto* base_env = reinterpret_cast<rocksdb::Env*>(jbase_env_handle);
+ return reinterpret_cast<jlong>(rocksdb::NewMemEnv(base_env));
+}
+
+/*
+ * Class: org_rocksdb_RocksMemEnv
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksMemEnv_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* e = reinterpret_cast<rocksdb::Env*>(jhandle);
+ assert(e != nullptr);
+ delete e;
+}
+
+/*
+ * Class: org_rocksdb_HdfsEnv
+ * Method: createHdfsEnv
+ * Signature: (Ljava/lang/String;)J
+ */
+jlong Java_org_rocksdb_HdfsEnv_createHdfsEnv(
+ JNIEnv* env, jclass, jstring jfsname) {
+ jboolean has_exception = JNI_FALSE;
+ auto fsname = rocksdb::JniUtil::copyStdString(env, jfsname, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return 0;
+ }
+ rocksdb::Env* hdfs_env;
+ rocksdb::Status s = rocksdb::NewHdfsEnv(&hdfs_env, fsname);
+ if (!s.ok()) {
+ // error occurred
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+ }
+ return reinterpret_cast<jlong>(hdfs_env);
+}
+
+/*
+ * Class: org_rocksdb_HdfsEnv
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_HdfsEnv_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* e = reinterpret_cast<rocksdb::Env*>(jhandle);
+ assert(e != nullptr);
+ delete e;
+}
+
+/*
+ * Class: org_rocksdb_TimedEnv
+ * Method: createTimedEnv
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TimedEnv_createTimedEnv(
+ JNIEnv*, jclass, jlong jbase_env_handle) {
+ auto* base_env = reinterpret_cast<rocksdb::Env*>(jbase_env_handle);
+ return reinterpret_cast<jlong>(rocksdb::NewTimedEnv(base_env));
+}
+
+/*
+ * Class: org_rocksdb_TimedEnv
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TimedEnv_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* e = reinterpret_cast<rocksdb::Env*>(jhandle);
+ assert(e != nullptr);
+ delete e;
+}
+
diff --git a/src/rocksdb/java/rocksjni/env_options.cc b/src/rocksdb/java/rocksjni/env_options.cc
new file mode 100644
index 00000000..9ed33018
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/env_options.cc
@@ -0,0 +1,297 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling C++ rocksdb::EnvOptions methods
+// from Java side.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_EnvOptions.h"
+#include "rocksdb/env.h"
+
+#define ENV_OPTIONS_SET_BOOL(_jhandle, _opt) \
+ reinterpret_cast<rocksdb::EnvOptions *>(_jhandle)->_opt = \
+ static_cast<bool>(_opt)
+
+#define ENV_OPTIONS_SET_SIZE_T(_jhandle, _opt) \
+ reinterpret_cast<rocksdb::EnvOptions *>(_jhandle)->_opt = \
+ static_cast<size_t>(_opt)
+
+#define ENV_OPTIONS_SET_UINT64_T(_jhandle, _opt) \
+ reinterpret_cast<rocksdb::EnvOptions *>(_jhandle)->_opt = \
+ static_cast<uint64_t>(_opt)
+
+#define ENV_OPTIONS_GET(_jhandle, _opt) \
+ reinterpret_cast<rocksdb::EnvOptions *>(_jhandle)->_opt
+
+/*
+ * Class: org_rocksdb_EnvOptions
+ * Method: newEnvOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_EnvOptions_newEnvOptions__(
+ JNIEnv*, jclass) {
+ auto *env_opt = new rocksdb::EnvOptions();
+ return reinterpret_cast<jlong>(env_opt);
+}
+
+/*
+ * Class: org_rocksdb_EnvOptions
+ * Method: newEnvOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_EnvOptions_newEnvOptions__J(
+ JNIEnv*, jclass, jlong jdboptions_handle) {
+ auto* db_options =
+ reinterpret_cast<rocksdb::DBOptions*>(jdboptions_handle);
+ auto* env_opt = new rocksdb::EnvOptions(*db_options);
+ return reinterpret_cast<jlong>(env_opt);
+}
+
+/*
+ * Class: org_rocksdb_EnvOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_EnvOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto *eo = reinterpret_cast<rocksdb::EnvOptions *>(jhandle);
+ assert(eo != nullptr);
+ delete eo;
+}
+
+/*
+ * Class: org_rocksdb_EnvOptions
+ * Method: setUseMmapReads
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_EnvOptions_setUseMmapReads(
+ JNIEnv*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, 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*, jobject, jlong jhandle, jlong rl_handle) {
+ auto *sptr_rate_limiter =
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter> *>(rl_handle);
+ auto *env_opt = reinterpret_cast<rocksdb::EnvOptions *>(jhandle);
+ env_opt->rate_limiter = sptr_rate_limiter->get();
+}
diff --git a/src/rocksdb/java/rocksjni/filter.cc b/src/rocksdb/java/rocksjni/filter.cc
new file mode 100644
index 00000000..5e9c6364
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/filter.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::FilterPolicy.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+#include "include/org_rocksdb_BloomFilter.h"
+#include "include/org_rocksdb_Filter.h"
+#include "rocksdb/filter_policy.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_BloomFilter
+ * Method: createBloomFilter
+ * Signature: (IZ)J
+ */
+jlong Java_org_rocksdb_BloomFilter_createNewBloomFilter(
+ JNIEnv* /*env*/, jclass /*jcls*/, jint bits_per_key,
+ jboolean use_block_base_builder) {
+ auto* sptr_filter = new std::shared_ptr<const rocksdb::FilterPolicy>(
+ rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder));
+ return reinterpret_cast<jlong>(sptr_filter);
+}
+
+/*
+ * Class: org_rocksdb_Filter
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Filter_disposeInternal(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* handle =
+ reinterpret_cast<std::shared_ptr<const rocksdb::FilterPolicy>*>(jhandle);
+ delete handle; // delete std::shared_ptr
+}
diff --git a/src/rocksdb/java/rocksjni/ingest_external_file_options.cc b/src/rocksdb/java/rocksjni/ingest_external_file_options.cc
new file mode 100644
index 00000000..e0871ff8
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/ingest_external_file_options.cc
@@ -0,0 +1,196 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::FilterPolicy.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_IngestExternalFileOptions.h"
+#include "rocksdb/options.h"
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: newIngestExternalFileOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_IngestExternalFileOptions_newIngestExternalFileOptions__(
+ JNIEnv*, jclass) {
+ auto* options = new rocksdb::IngestExternalFileOptions();
+ return reinterpret_cast<jlong>(options);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: newIngestExternalFileOptions
+ * Signature: (ZZZZ)J
+ */
+jlong Java_org_rocksdb_IngestExternalFileOptions_newIngestExternalFileOptions__ZZZZ(
+ JNIEnv*, jclass, jboolean jmove_files,
+ jboolean jsnapshot_consistency, jboolean jallow_global_seqno,
+ jboolean jallow_blocking_flush) {
+ auto* options = new rocksdb::IngestExternalFileOptions();
+ options->move_files = static_cast<bool>(jmove_files);
+ options->snapshot_consistency = static_cast<bool>(jsnapshot_consistency);
+ options->allow_global_seqno = static_cast<bool>(jallow_global_seqno);
+ options->allow_blocking_flush = static_cast<bool>(jallow_blocking_flush);
+ return reinterpret_cast<jlong>(options);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: moveFiles
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_IngestExternalFileOptions_moveFiles(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ return static_cast<jboolean>(options->move_files);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: setMoveFiles
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_IngestExternalFileOptions_setMoveFiles(
+ JNIEnv*, jobject, jlong jhandle, jboolean jmove_files) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ options->move_files = static_cast<bool>(jmove_files);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: snapshotConsistency
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_IngestExternalFileOptions_snapshotConsistency(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ return static_cast<jboolean>(options->snapshot_consistency);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: setSnapshotConsistency
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_IngestExternalFileOptions_setSnapshotConsistency(
+ JNIEnv*, jobject, jlong jhandle, jboolean jsnapshot_consistency) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ options->snapshot_consistency = static_cast<bool>(jsnapshot_consistency);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: allowGlobalSeqNo
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_IngestExternalFileOptions_allowGlobalSeqNo(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ return static_cast<jboolean>(options->allow_global_seqno);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: setAllowGlobalSeqNo
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_IngestExternalFileOptions_setAllowGlobalSeqNo(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_global_seqno) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ options->allow_global_seqno = static_cast<bool>(jallow_global_seqno);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: allowBlockingFlush
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_IngestExternalFileOptions_allowBlockingFlush(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ return static_cast<jboolean>(options->allow_blocking_flush);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: setAllowBlockingFlush
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_IngestExternalFileOptions_setAllowBlockingFlush(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_blocking_flush) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ options->allow_blocking_flush = static_cast<bool>(jallow_blocking_flush);
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: ingestBehind
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_IngestExternalFileOptions_ingestBehind(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ return options->ingest_behind == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: setIngestBehind
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_IngestExternalFileOptions_setIngestBehind(
+ JNIEnv*, jobject, jlong jhandle, jboolean jingest_behind) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ options->ingest_behind = jingest_behind == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: writeGlobalSeqno
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_IngestExternalFileOptions_writeGlobalSeqno(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ return options->write_global_seqno == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: setWriteGlobalSeqno
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_org_rocksdb_IngestExternalFileOptions_setWriteGlobalSeqno(
+ JNIEnv*, jobject, jlong jhandle, jboolean jwrite_global_seqno) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ options->write_global_seqno = jwrite_global_seqno == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_IngestExternalFileOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_IngestExternalFileOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options =
+ reinterpret_cast<rocksdb::IngestExternalFileOptions*>(jhandle);
+ delete options;
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/iterator.cc b/src/rocksdb/java/rocksjni/iterator.cc
new file mode 100644
index 00000000..18daeb81
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/iterator.cc
@@ -0,0 +1,186 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::Iterator methods from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "include/org_rocksdb_RocksIterator.h"
+#include "rocksdb/iterator.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksIterator_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
+ assert(it != nullptr);
+ delete it;
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: isValid0
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_RocksIterator_isValid0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<rocksdb::Iterator*>(handle)->Valid();
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: seekToFirst0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksIterator_seekToFirst0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::Iterator*>(handle)->SeekToFirst();
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: seekToLast0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksIterator_seekToLast0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::Iterator*>(handle)->SeekToLast();
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: next0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksIterator_next0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::Iterator*>(handle)->Next();
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: prev0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksIterator_prev0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::Iterator*>(handle)->Prev();
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: seek0
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_RocksIterator_seek0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle, jbyteArray jtarget,
+ jint jtarget_len) {
+ jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
+ if (target == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice target_slice(reinterpret_cast<char*>(target), jtarget_len);
+
+ auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
+ it->Seek(target_slice);
+
+ env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: seekForPrev0
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_RocksIterator_seekForPrev0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle,
+ jbyteArray jtarget,
+ jint jtarget_len) {
+ jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
+ if (target == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice target_slice(reinterpret_cast<char*>(target), jtarget_len);
+
+ auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
+ it->SeekForPrev(target_slice);
+
+ env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: status0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksIterator_status0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
+ rocksdb::Status s = it->status();
+
+ if (s.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: key0
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_RocksIterator_key0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
+ rocksdb::Slice key_slice = it->key();
+
+ jbyteArray jkey = env->NewByteArray(static_cast<jsize>(key_slice.size()));
+ if (jkey == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetByteArrayRegion(
+ jkey, 0, static_cast<jsize>(key_slice.size()),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(key_slice.data())));
+ return jkey;
+}
+
+/*
+ * Class: org_rocksdb_RocksIterator
+ * Method: value0
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_RocksIterator_value0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::Iterator*>(handle);
+ rocksdb::Slice value_slice = it->value();
+
+ jbyteArray jkeyValue =
+ env->NewByteArray(static_cast<jsize>(value_slice.size()));
+ if (jkeyValue == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetByteArrayRegion(
+ jkeyValue, 0, static_cast<jsize>(value_slice.size()),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value_slice.data())));
+ return jkeyValue;
+}
diff --git a/src/rocksdb/java/rocksjni/jnicallback.cc b/src/rocksdb/java/rocksjni/jnicallback.cc
new file mode 100644
index 00000000..f72eecd4
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/jnicallback.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// JNI Callbacks from C++ to sub-classes or org.rocksdb.RocksCallbackObject
+
+#include <assert.h>
+#include "rocksjni/jnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+JniCallback::JniCallback(JNIEnv* env, jobject jcallback_obj) {
+ // Note: jcallback_obj may be accessed by multiple threads,
+ // so we ref the jvm not the env
+ const jint rs = env->GetJavaVM(&m_jvm);
+ if(rs != JNI_OK) {
+ // exception thrown
+ return;
+ }
+
+ // Note: we may want to access the Java callback object instance
+ // across multiple method calls, so we create a global ref
+ assert(jcallback_obj != nullptr);
+ m_jcallback_obj = env->NewGlobalRef(jcallback_obj);
+ if(jcallback_obj == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+}
+
+JNIEnv* JniCallback::getJniEnv(jboolean* attached) const {
+ return JniUtil::getJniEnv(m_jvm, attached);
+}
+
+void JniCallback::releaseJniEnv(jboolean& attached) const {
+ JniUtil::releaseJniEnv(m_jvm, attached);
+}
+
+JniCallback::~JniCallback() {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ if(m_jcallback_obj != nullptr) {
+ env->DeleteGlobalRef(m_jcallback_obj);
+ }
+
+ releaseJniEnv(attached_thread);
+}
+// @lint-ignore TXT4 T25377293 Grandfathered in
+} // namespace rocksdb \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/jnicallback.h b/src/rocksdb/java/rocksjni/jnicallback.h
new file mode 100644
index 00000000..940ecf06
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/jnicallback.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// JNI Callbacks from C++ to sub-classes or org.rocksdb.RocksCallbackObject
+
+#ifndef JAVA_ROCKSJNI_JNICALLBACK_H_
+#define JAVA_ROCKSJNI_JNICALLBACK_H_
+
+#include <jni.h>
+
+namespace rocksdb {
+ class JniCallback {
+ public:
+ JniCallback(JNIEnv* env, jobject jcallback_obj);
+ virtual ~JniCallback();
+
+ protected:
+ JavaVM* m_jvm;
+ jobject m_jcallback_obj;
+ JNIEnv* getJniEnv(jboolean* attached) const;
+ void releaseJniEnv(jboolean& attached) const;
+ };
+}
+
+// @lint-ignore TXT4 T25377293 Grandfathered in
+#endif // JAVA_ROCKSJNI_JNICALLBACK_H_ \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/loggerjnicallback.cc b/src/rocksdb/java/rocksjni/loggerjnicallback.cc
new file mode 100644
index 00000000..61571e98
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/loggerjnicallback.cc
@@ -0,0 +1,294 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Logger.
+
+#include "include/org_rocksdb_Logger.h"
+
+#include <cstdarg>
+#include <cstdio>
+#include "rocksjni/loggerjnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+
+LoggerJniCallback::LoggerJniCallback(JNIEnv* env, jobject jlogger)
+ : JniCallback(env, jlogger) {
+ m_jLogMethodId = LoggerJni::getLogMethodId(env);
+ if (m_jLogMethodId == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ jobject jdebug_level = InfoLogLevelJni::DEBUG_LEVEL(env);
+ if (jdebug_level == nullptr) {
+ // exception thrown: NoSuchFieldError, ExceptionInInitializerError
+ // or OutOfMemoryError
+ return;
+ }
+ m_jdebug_level = env->NewGlobalRef(jdebug_level);
+ if (m_jdebug_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jobject jinfo_level = InfoLogLevelJni::INFO_LEVEL(env);
+ if (jinfo_level == nullptr) {
+ // exception thrown: NoSuchFieldError, ExceptionInInitializerError
+ // or OutOfMemoryError
+ return;
+ }
+ m_jinfo_level = env->NewGlobalRef(jinfo_level);
+ if (m_jinfo_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jobject jwarn_level = InfoLogLevelJni::WARN_LEVEL(env);
+ if (jwarn_level == nullptr) {
+ // exception thrown: NoSuchFieldError, ExceptionInInitializerError
+ // or OutOfMemoryError
+ return;
+ }
+ m_jwarn_level = env->NewGlobalRef(jwarn_level);
+ if (m_jwarn_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jobject jerror_level = InfoLogLevelJni::ERROR_LEVEL(env);
+ if (jerror_level == nullptr) {
+ // exception thrown: NoSuchFieldError, ExceptionInInitializerError
+ // or OutOfMemoryError
+ return;
+ }
+ m_jerror_level = env->NewGlobalRef(jerror_level);
+ if (m_jerror_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jobject jfatal_level = InfoLogLevelJni::FATAL_LEVEL(env);
+ if (jfatal_level == nullptr) {
+ // exception thrown: NoSuchFieldError, ExceptionInInitializerError
+ // or OutOfMemoryError
+ return;
+ }
+ m_jfatal_level = env->NewGlobalRef(jfatal_level);
+ if (m_jfatal_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jobject jheader_level = InfoLogLevelJni::HEADER_LEVEL(env);
+ if (jheader_level == nullptr) {
+ // exception thrown: NoSuchFieldError, ExceptionInInitializerError
+ // or OutOfMemoryError
+ return;
+ }
+ m_jheader_level = env->NewGlobalRef(jheader_level);
+ if (m_jheader_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+}
+
+void LoggerJniCallback::Logv(const char* /*format*/, va_list /*ap*/) {
+ // We implement this method because it is virtual but we don't
+ // use it because we need to know about the log level.
+}
+
+void LoggerJniCallback::Logv(const InfoLogLevel log_level, const char* format,
+ va_list ap) {
+ if (GetInfoLogLevel() <= log_level) {
+ // determine InfoLogLevel java enum instance
+ jobject jlog_level;
+ switch (log_level) {
+ case rocksdb::InfoLogLevel::DEBUG_LEVEL:
+ jlog_level = m_jdebug_level;
+ break;
+ case rocksdb::InfoLogLevel::INFO_LEVEL:
+ jlog_level = m_jinfo_level;
+ break;
+ case rocksdb::InfoLogLevel::WARN_LEVEL:
+ jlog_level = m_jwarn_level;
+ break;
+ case rocksdb::InfoLogLevel::ERROR_LEVEL:
+ jlog_level = m_jerror_level;
+ break;
+ case rocksdb::InfoLogLevel::FATAL_LEVEL:
+ jlog_level = m_jfatal_level;
+ break;
+ case rocksdb::InfoLogLevel::HEADER_LEVEL:
+ jlog_level = m_jheader_level;
+ break;
+ default:
+ jlog_level = m_jfatal_level;
+ break;
+ }
+
+ assert(format != nullptr);
+ assert(ap != nullptr);
+ const std::unique_ptr<char[]> msg = format_str(format, ap);
+
+ // pass msg to java callback handler
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ jstring jmsg = env->NewStringUTF(msg.get());
+ if (jmsg == nullptr) {
+ // unable to construct string
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+ releaseJniEnv(attached_thread);
+ return;
+ }
+ if (env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jmsg);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ env->CallVoidMethod(m_jcallback_obj, m_jLogMethodId, jlog_level, jmsg);
+ if (env->ExceptionCheck()) {
+ // exception thrown
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jmsg);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ env->DeleteLocalRef(jmsg);
+ releaseJniEnv(attached_thread);
+ }
+}
+
+std::unique_ptr<char[]> LoggerJniCallback::format_str(const char* format,
+ va_list ap) const {
+ va_list ap_copy;
+
+ va_copy(ap_copy, ap);
+ const size_t required =
+ vsnprintf(nullptr, 0, format, ap_copy) + 1; // Extra space for '\0'
+ va_end(ap_copy);
+
+ std::unique_ptr<char[]> buf(new char[required]);
+
+ va_copy(ap_copy, ap);
+ vsnprintf(buf.get(), required, format, ap_copy);
+ va_end(ap_copy);
+
+ return buf;
+}
+LoggerJniCallback::~LoggerJniCallback() {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ if (m_jdebug_level != nullptr) {
+ env->DeleteGlobalRef(m_jdebug_level);
+ }
+
+ if (m_jinfo_level != nullptr) {
+ env->DeleteGlobalRef(m_jinfo_level);
+ }
+
+ if (m_jwarn_level != nullptr) {
+ env->DeleteGlobalRef(m_jwarn_level);
+ }
+
+ if (m_jerror_level != nullptr) {
+ env->DeleteGlobalRef(m_jerror_level);
+ }
+
+ if (m_jfatal_level != nullptr) {
+ env->DeleteGlobalRef(m_jfatal_level);
+ }
+
+ if (m_jheader_level != nullptr) {
+ env->DeleteGlobalRef(m_jheader_level);
+ }
+
+ releaseJniEnv(attached_thread);
+}
+
+} // namespace rocksdb
+
+/*
+ * Class: org_rocksdb_Logger
+ * Method: createNewLoggerOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Logger_createNewLoggerOptions(JNIEnv* env, jobject jobj,
+ jlong joptions) {
+ auto* sptr_logger = new std::shared_ptr<rocksdb::LoggerJniCallback>(
+ new rocksdb::LoggerJniCallback(env, jobj));
+
+ // set log level
+ auto* options = reinterpret_cast<rocksdb::Options*>(joptions);
+ sptr_logger->get()->SetInfoLogLevel(options->info_log_level);
+
+ return reinterpret_cast<jlong>(sptr_logger);
+}
+
+/*
+ * Class: org_rocksdb_Logger
+ * Method: createNewLoggerDbOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Logger_createNewLoggerDbOptions(JNIEnv* env,
+ jobject jobj,
+ jlong jdb_options) {
+ auto* sptr_logger = new std::shared_ptr<rocksdb::LoggerJniCallback>(
+ new rocksdb::LoggerJniCallback(env, jobj));
+
+ // set log level
+ auto* db_options = reinterpret_cast<rocksdb::DBOptions*>(jdb_options);
+ sptr_logger->get()->SetInfoLogLevel(db_options->info_log_level);
+
+ return reinterpret_cast<jlong>(sptr_logger);
+}
+
+/*
+ * Class: org_rocksdb_Logger
+ * Method: setInfoLogLevel
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Logger_setInfoLogLevel(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle, jbyte jlog_level) {
+ auto* handle =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(jhandle);
+ handle->get()->SetInfoLogLevel(
+ static_cast<rocksdb::InfoLogLevel>(jlog_level));
+}
+
+/*
+ * Class: org_rocksdb_Logger
+ * Method: infoLogLevel
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Logger_infoLogLevel(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* handle =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(jhandle);
+ return static_cast<jbyte>(handle->get()->GetInfoLogLevel());
+}
+
+/*
+ * Class: org_rocksdb_Logger
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Logger_disposeInternal(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* handle =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(jhandle);
+ delete handle; // delete std::shared_ptr
+}
diff --git a/src/rocksdb/java/rocksjni/loggerjnicallback.h b/src/rocksdb/java/rocksjni/loggerjnicallback.h
new file mode 100644
index 00000000..80c5a198
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/loggerjnicallback.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Logger
+
+#ifndef JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_
+#define JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_
+
+#include <jni.h>
+#include <memory>
+#include <string>
+#include "rocksjni/jnicallback.h"
+#include "port/port.h"
+#include "rocksdb/env.h"
+
+namespace rocksdb {
+
+ class LoggerJniCallback : public JniCallback, public Logger {
+ public:
+ LoggerJniCallback(JNIEnv* env, jobject jLogger);
+ ~LoggerJniCallback();
+
+ using Logger::SetInfoLogLevel;
+ using Logger::GetInfoLogLevel;
+ // Write an entry to the log file with the specified format.
+ virtual void Logv(const char* format, va_list ap);
+ // Write an entry to the log file with the specified log level
+ // and format. Any log with level under the internal log level
+ // of *this (see @SetInfoLogLevel and @GetInfoLogLevel) will not be
+ // printed.
+ virtual void Logv(const InfoLogLevel log_level,
+ const char* format, va_list ap);
+
+ private:
+ jmethodID m_jLogMethodId;
+ jobject m_jdebug_level;
+ jobject m_jinfo_level;
+ jobject m_jwarn_level;
+ jobject m_jerror_level;
+ jobject m_jfatal_level;
+ jobject m_jheader_level;
+ std::unique_ptr<char[]> format_str(const char* format, va_list ap) const;
+ };
+} // namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/lru_cache.cc b/src/rocksdb/java/rocksjni/lru_cache.cc
new file mode 100644
index 00000000..2424bc8e
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/lru_cache.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::LRUCache.
+
+#include <jni.h>
+
+#include "cache/lru_cache.h"
+#include "include/org_rocksdb_LRUCache.h"
+
+/*
+ * Class: org_rocksdb_LRUCache
+ * Method: newLRUCache
+ * Signature: (JIZD)J
+ */
+jlong Java_org_rocksdb_LRUCache_newLRUCache(JNIEnv* /*env*/, jclass /*jcls*/,
+ jlong jcapacity,
+ jint jnum_shard_bits,
+ jboolean jstrict_capacity_limit,
+ jdouble jhigh_pri_pool_ratio) {
+ auto* sptr_lru_cache =
+ new std::shared_ptr<rocksdb::Cache>(rocksdb::NewLRUCache(
+ static_cast<size_t>(jcapacity), static_cast<int>(jnum_shard_bits),
+ static_cast<bool>(jstrict_capacity_limit),
+ static_cast<double>(jhigh_pri_pool_ratio)));
+ return reinterpret_cast<jlong>(sptr_lru_cache);
+}
+
+/*
+ * Class: org_rocksdb_LRUCache
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_LRUCache_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_lru_cache =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache>*>(jhandle);
+ delete sptr_lru_cache; // delete std::shared_ptr
+}
diff --git a/src/rocksdb/java/rocksjni/memory_util.cc b/src/rocksdb/java/rocksjni/memory_util.cc
new file mode 100644
index 00000000..04385021
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/memory_util.cc
@@ -0,0 +1,100 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+#include <map>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "include/org_rocksdb_MemoryUtil.h"
+
+#include "rocksjni/portal.h"
+
+#include "rocksdb/utilities/memory_util.h"
+
+
+/*
+ * Class: org_rocksdb_MemoryUtil
+ * Method: getApproximateMemoryUsageByType
+ * Signature: ([J[J)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_MemoryUtil_getApproximateMemoryUsageByType(
+ JNIEnv *env, jclass /*jclazz*/, jlongArray jdb_handles, jlongArray jcache_handles) {
+
+ std::vector<rocksdb::DB*> dbs;
+ jsize db_handle_count = env->GetArrayLength(jdb_handles);
+ if(db_handle_count > 0) {
+ jlong *ptr_jdb_handles = env->GetLongArrayElements(jdb_handles, nullptr);
+ if (ptr_jdb_handles == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ for (jsize i = 0; i < db_handle_count; i++) {
+ dbs.push_back(reinterpret_cast<rocksdb::DB *>(ptr_jdb_handles[i]));
+ }
+ env->ReleaseLongArrayElements(jdb_handles, ptr_jdb_handles, JNI_ABORT);
+ }
+
+ std::unordered_set<const rocksdb::Cache*> cache_set;
+ jsize cache_handle_count = env->GetArrayLength(jcache_handles);
+ if(cache_handle_count > 0) {
+ jlong *ptr_jcache_handles = env->GetLongArrayElements(jcache_handles, nullptr);
+ if (ptr_jcache_handles == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ for (jsize i = 0; i < cache_handle_count; i++) {
+ auto *cache_ptr =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache> *>(ptr_jcache_handles[i]);
+ cache_set.insert(cache_ptr->get());
+ }
+ env->ReleaseLongArrayElements(jcache_handles, ptr_jcache_handles, JNI_ABORT);
+ }
+
+ std::map<rocksdb::MemoryUtil::UsageType, uint64_t> usage_by_type;
+ if(rocksdb::MemoryUtil::GetApproximateMemoryUsageByType(dbs, cache_set, &usage_by_type) != rocksdb::Status::OK()) {
+ // Non-OK status
+ return nullptr;
+ }
+
+ jobject jusage_by_type = rocksdb::HashMapJni::construct(
+ env, static_cast<uint32_t>(usage_by_type.size()));
+ if (jusage_by_type == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ const rocksdb::HashMapJni::FnMapKV<const rocksdb::MemoryUtil::UsageType, const uint64_t, jobject, jobject>
+ fn_map_kv =
+ [env](const std::pair<rocksdb::MemoryUtil::UsageType, uint64_t>& pair) {
+ // Construct key
+ const jobject jusage_type =
+ rocksdb::ByteJni::valueOf(env, rocksdb::MemoryUsageTypeJni::toJavaMemoryUsageType(pair.first));
+ if (jusage_type == nullptr) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+ // Construct value
+ const jobject jusage_value =
+ rocksdb::LongJni::valueOf(env, pair.second);
+ if (jusage_value == nullptr) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+ // Construct and return pointer to pair of jobjects
+ return std::unique_ptr<std::pair<jobject, jobject>>(
+ new std::pair<jobject, jobject>(jusage_type,
+ jusage_value));
+ };
+
+ if (!rocksdb::HashMapJni::putAll(env, jusage_by_type, usage_by_type.begin(),
+ usage_by_type.end(), fn_map_kv)) {
+ // exception occcurred
+ jusage_by_type = nullptr;
+ }
+
+ return jusage_by_type;
+
+}
diff --git a/src/rocksdb/java/rocksjni/memtablejni.cc b/src/rocksdb/java/rocksjni/memtablejni.cc
new file mode 100644
index 00000000..ad704c3b
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/memtablejni.cc
@@ -0,0 +1,89 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for MemTables.
+
+#include "include/org_rocksdb_HashLinkedListMemTableConfig.h"
+#include "include/org_rocksdb_HashSkipListMemTableConfig.h"
+#include "include/org_rocksdb_SkipListMemTableConfig.h"
+#include "include/org_rocksdb_VectorMemTableConfig.h"
+#include "rocksdb/memtablerep.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_HashSkipListMemTableConfig
+ * Method: newMemTableFactoryHandle
+ * Signature: (JII)J
+ */
+jlong Java_org_rocksdb_HashSkipListMemTableConfig_newMemTableFactoryHandle(
+ JNIEnv* env, jobject /*jobj*/, jlong jbucket_count, jint jheight,
+ jint jbranching_factor) {
+ rocksdb::Status s = rocksdb::JniUtil::check_if_jlong_fits_size_t(jbucket_count);
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(rocksdb::NewHashSkipListRepFactory(
+ static_cast<size_t>(jbucket_count), static_cast<int32_t>(jheight),
+ static_cast<int32_t>(jbranching_factor)));
+ }
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ return 0;
+}
+
+/*
+ * Class: org_rocksdb_HashLinkedListMemTableConfig
+ * Method: newMemTableFactoryHandle
+ * Signature: (JJIZI)J
+ */
+jlong Java_org_rocksdb_HashLinkedListMemTableConfig_newMemTableFactoryHandle(
+ JNIEnv* env, jobject /*jobj*/, jlong jbucket_count,
+ jlong jhuge_page_tlb_size, jint jbucket_entries_logging_threshold,
+ jboolean jif_log_bucket_dist_when_flash, jint jthreshold_use_skiplist) {
+ rocksdb::Status statusBucketCount =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jbucket_count);
+ rocksdb::Status statusHugePageTlb =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jhuge_page_tlb_size);
+ if (statusBucketCount.ok() && statusHugePageTlb.ok()) {
+ return reinterpret_cast<jlong>(rocksdb::NewHashLinkListRepFactory(
+ static_cast<size_t>(jbucket_count),
+ static_cast<size_t>(jhuge_page_tlb_size),
+ static_cast<int32_t>(jbucket_entries_logging_threshold),
+ static_cast<bool>(jif_log_bucket_dist_when_flash),
+ static_cast<int32_t>(jthreshold_use_skiplist)));
+ }
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(
+ env, !statusBucketCount.ok() ? statusBucketCount : statusHugePageTlb);
+ return 0;
+}
+
+/*
+ * Class: org_rocksdb_VectorMemTableConfig
+ * Method: newMemTableFactoryHandle
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_VectorMemTableConfig_newMemTableFactoryHandle(
+ JNIEnv* env, jobject /*jobj*/, jlong jreserved_size) {
+ rocksdb::Status s = rocksdb::JniUtil::check_if_jlong_fits_size_t(jreserved_size);
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(
+ new rocksdb::VectorRepFactory(static_cast<size_t>(jreserved_size)));
+ }
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ return 0;
+}
+
+/*
+ * Class: org_rocksdb_SkipListMemTableConfig
+ * Method: newMemTableFactoryHandle0
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_SkipListMemTableConfig_newMemTableFactoryHandle0(
+ JNIEnv* env, jobject /*jobj*/, jlong jlookahead) {
+ rocksdb::Status s = rocksdb::JniUtil::check_if_jlong_fits_size_t(jlookahead);
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(
+ new rocksdb::SkipListFactory(static_cast<size_t>(jlookahead)));
+ }
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ return 0;
+}
diff --git a/src/rocksdb/java/rocksjni/merge_operator.cc b/src/rocksdb/java/rocksjni/merge_operator.cc
new file mode 100644
index 00000000..e06a06f7
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/merge_operator.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2014, Vlad Balan (vlad.gm@gmail.com). All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::MergeOperator.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory>
+#include <string>
+
+#include "include/org_rocksdb_StringAppendOperator.h"
+#include "include/org_rocksdb_UInt64AddOperator.h"
+#include "rocksdb/db.h"
+#include "rocksdb/memtablerep.h"
+#include "rocksdb/merge_operator.h"
+#include "rocksdb/options.h"
+#include "rocksdb/slice_transform.h"
+#include "rocksdb/statistics.h"
+#include "rocksdb/table.h"
+#include "rocksjni/portal.h"
+#include "utilities/merge_operators.h"
+
+/*
+ * Class: org_rocksdb_StringAppendOperator
+ * Method: newSharedStringAppendOperator
+ * Signature: (C)J
+ */
+jlong Java_org_rocksdb_StringAppendOperator_newSharedStringAppendOperator(
+ JNIEnv* /*env*/, jclass /*jclazz*/, jchar jdelim) {
+ auto* sptr_string_append_op = new std::shared_ptr<rocksdb::MergeOperator>(
+ rocksdb::MergeOperators::CreateStringAppendOperator((char)jdelim));
+ return reinterpret_cast<jlong>(sptr_string_append_op);
+}
+
+/*
+ * Class: org_rocksdb_StringAppendOperator
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_StringAppendOperator_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_string_append_op =
+ reinterpret_cast<std::shared_ptr<rocksdb::MergeOperator>*>(jhandle);
+ delete sptr_string_append_op; // delete std::shared_ptr
+}
+
+/*
+ * Class: org_rocksdb_UInt64AddOperator
+ * Method: newSharedUInt64AddOperator
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_UInt64AddOperator_newSharedUInt64AddOperator(
+ JNIEnv* /*env*/, jclass /*jclazz*/) {
+ auto* sptr_uint64_add_op = new std::shared_ptr<rocksdb::MergeOperator>(
+ rocksdb::MergeOperators::CreateUInt64AddOperator());
+ return reinterpret_cast<jlong>(sptr_uint64_add_op);
+}
+
+/*
+ * Class: org_rocksdb_UInt64AddOperator
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_UInt64AddOperator_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_uint64_add_op =
+ reinterpret_cast<std::shared_ptr<rocksdb::MergeOperator>*>(jhandle);
+ delete sptr_uint64_add_op; // delete std::shared_ptr
+}
diff --git a/src/rocksdb/java/rocksjni/native_comparator_wrapper_test.cc b/src/rocksdb/java/rocksjni/native_comparator_wrapper_test.cc
new file mode 100644
index 00000000..829019f9
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/native_comparator_wrapper_test.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+#include <string>
+
+#include "rocksdb/comparator.h"
+#include "rocksdb/slice.h"
+
+#include "include/org_rocksdb_NativeComparatorWrapperTest_NativeStringComparatorWrapper.h"
+
+namespace rocksdb {
+
+class NativeComparatorWrapperTestStringComparator : public Comparator {
+ const char* Name() const {
+ return "NativeComparatorWrapperTestStringComparator";
+ }
+
+ int Compare(const Slice& a, const Slice& b) const {
+ return a.ToString().compare(b.ToString());
+ }
+
+ void FindShortestSeparator(std::string* /*start*/,
+ const Slice& /*limit*/) const {
+ return;
+ }
+
+ void FindShortSuccessor(std::string* /*key*/) const { return; }
+};
+} // namespace rocksdb
+
+/*
+ * Class: org_rocksdb_NativeComparatorWrapperTest_NativeStringComparatorWrapper
+ * Method: newStringComparator
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_NativeComparatorWrapperTest_00024NativeStringComparatorWrapper_newStringComparator(
+ JNIEnv* /*env*/, jobject /*jobj*/) {
+ auto* comparator = new rocksdb::NativeComparatorWrapperTestStringComparator();
+ return reinterpret_cast<jlong>(comparator);
+}
diff --git a/src/rocksdb/java/rocksjni/optimistic_transaction_db.cc b/src/rocksdb/java/rocksjni/optimistic_transaction_db.cc
new file mode 100644
index 00000000..1505ff98
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/optimistic_transaction_db.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::TransactionDB.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_OptimisticTransactionDB.h"
+
+#include "rocksdb/options.h"
+#include "rocksdb/utilities/optimistic_transaction_db.h"
+#include "rocksdb/utilities/transaction.h"
+
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: open
+ * Signature: (JLjava/lang/String;)J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2(
+ JNIEnv* env, jclass, jlong joptions_handle, jstring jdb_path) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ auto* options = reinterpret_cast<rocksdb::Options*>(joptions_handle);
+ rocksdb::OptimisticTransactionDB* otdb = nullptr;
+ rocksdb::Status s =
+ rocksdb::OptimisticTransactionDB::Open(*options, db_path, &otdb);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(otdb);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+ }
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: open
+ * Signature: (JLjava/lang/String;[[B[J)[J
+ */
+jlongArray
+Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2_3_3B_3J(
+ JNIEnv* env, jclass, jlong jdb_options_handle, jstring jdb_path,
+ jobjectArray jcolumn_names, jlongArray jcolumn_options_handles) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
+ const jsize len_cols = env->GetArrayLength(jcolumn_names);
+ if (len_cols > 0) {
+ if (env->EnsureLocalCapacity(len_cols) != 0) {
+ // out of memory
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ jlong* jco = env->GetLongArrayElements(jcolumn_options_handles, nullptr);
+ if (jco == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ for (int i = 0; i < len_cols; i++) {
+ const jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ const jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
+ const jsize jcf_name_len = env->GetArrayLength(jcn_ba);
+ if (env->EnsureLocalCapacity(jcf_name_len) != 0) {
+ // out of memory
+ env->DeleteLocalRef(jcn);
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, nullptr);
+ if (jcf_name == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jcn);
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ const std::string cf_name(reinterpret_cast<char*>(jcf_name),
+ jcf_name_len);
+ const rocksdb::ColumnFamilyOptions* cf_options =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[i]);
+ column_families.push_back(
+ rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
+
+ env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
+ env->DeleteLocalRef(jcn);
+ }
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ }
+
+ auto* db_options = reinterpret_cast<rocksdb::DBOptions*>(jdb_options_handle);
+ std::vector<rocksdb::ColumnFamilyHandle*> handles;
+ rocksdb::OptimisticTransactionDB* otdb = nullptr;
+ const rocksdb::Status s = rocksdb::OptimisticTransactionDB::Open(
+ *db_options, db_path, column_families, &handles, &otdb);
+
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ // check if open operation was successful
+ if (s.ok()) {
+ const jsize resultsLen = 1 + len_cols; // db handle + column family handles
+ std::unique_ptr<jlong[]> results =
+ std::unique_ptr<jlong[]>(new jlong[resultsLen]);
+ results[0] = reinterpret_cast<jlong>(otdb);
+ for (int i = 1; i <= len_cols; i++) {
+ results[i] = reinterpret_cast<jlong>(handles[i - 1]);
+ }
+
+ jlongArray jresults = env->NewLongArray(resultsLen);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ return nullptr;
+ }
+ return jresults;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_OptimisticTransactionDB_disposeInternal(
+ JNIEnv *, jobject, jlong jhandle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ assert(optimistic_txn_db != nullptr);
+ delete optimistic_txn_db;
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: closeDatabase
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_OptimisticTransactionDB_closeDatabase(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ assert(optimistic_txn_db != nullptr);
+ rocksdb::Status s = optimistic_txn_db->Close();
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: beginTransaction
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ rocksdb::Transaction* txn =
+ optimistic_txn_db->BeginTransaction(*write_options);
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: beginTransaction
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJJ(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jwrite_options_handle, jlong joptimistic_txn_options_handle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* optimistic_txn_options =
+ reinterpret_cast<rocksdb::OptimisticTransactionOptions*>(
+ joptimistic_txn_options_handle);
+ rocksdb::Transaction* txn = optimistic_txn_db->BeginTransaction(
+ *write_options, *optimistic_txn_options);
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: beginTransaction_withOld
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle,
+ jlong jold_txn_handle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* old_txn = reinterpret_cast<rocksdb::Transaction*>(jold_txn_handle);
+ rocksdb::OptimisticTransactionOptions optimistic_txn_options;
+ rocksdb::Transaction* txn = optimistic_txn_db->BeginTransaction(
+ *write_options, optimistic_txn_options, old_txn);
+
+ // RocksJava relies on the assumption that
+ // we do not allocate a new Transaction object
+ // when providing an old_optimistic_txn
+ assert(txn == old_txn);
+
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: beginTransaction_withOld
+ * Signature: (JJJJ)J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle,
+ jlong joptimistic_txn_options_handle, jlong jold_txn_handle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* optimistic_txn_options =
+ reinterpret_cast<rocksdb::OptimisticTransactionOptions*>(
+ joptimistic_txn_options_handle);
+ auto* old_txn = reinterpret_cast<rocksdb::Transaction*>(jold_txn_handle);
+ rocksdb::Transaction* txn = optimistic_txn_db->BeginTransaction(
+ *write_options, *optimistic_txn_options, old_txn);
+
+ // RocksJava relies on the assumption that
+ // we do not allocate a new Transaction object
+ // when providing an old_optimisic_txn
+ assert(txn == old_txn);
+
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionDB
+ * Method: getBaseDB
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionDB_getBaseDB(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* optimistic_txn_db =
+ reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle);
+ return reinterpret_cast<jlong>(optimistic_txn_db->GetBaseDB());
+}
diff --git a/src/rocksdb/java/rocksjni/optimistic_transaction_options.cc b/src/rocksdb/java/rocksjni/optimistic_transaction_options.cc
new file mode 100644
index 00000000..3eee4466
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/optimistic_transaction_options.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::OptimisticTransactionOptions.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_OptimisticTransactionOptions.h"
+
+#include "rocksdb/comparator.h"
+#include "rocksdb/utilities/optimistic_transaction_db.h"
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionOptions
+ * Method: newOptimisticTransactionOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_OptimisticTransactionOptions_newOptimisticTransactionOptions(
+ JNIEnv* /*env*/, jclass /*jcls*/) {
+ rocksdb::OptimisticTransactionOptions* opts =
+ new rocksdb::OptimisticTransactionOptions();
+ return reinterpret_cast<jlong>(opts);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionOptions
+ * Method: isSetSnapshot
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_OptimisticTransactionOptions_isSetSnapshot(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* opts =
+ reinterpret_cast<rocksdb::OptimisticTransactionOptions*>(jhandle);
+ return opts->set_snapshot;
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionOptions
+ * Method: setSetSnapshot
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_OptimisticTransactionOptions_setSetSnapshot(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean jset_snapshot) {
+ auto* opts =
+ reinterpret_cast<rocksdb::OptimisticTransactionOptions*>(jhandle);
+ opts->set_snapshot = jset_snapshot;
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionOptions
+ * Method: setComparator
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_OptimisticTransactionOptions_setComparator(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jcomparator_handle) {
+ auto* opts =
+ reinterpret_cast<rocksdb::OptimisticTransactionOptions*>(jhandle);
+ opts->cmp = reinterpret_cast<rocksdb::Comparator*>(jcomparator_handle);
+}
+
+/*
+ * Class: org_rocksdb_OptimisticTransactionOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_OptimisticTransactionOptions_disposeInternal(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ delete reinterpret_cast<rocksdb::OptimisticTransactionOptions*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/options.cc b/src/rocksdb/java/rocksjni/options.cc
new file mode 100644
index 00000000..12f44b5e
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/options.cc
@@ -0,0 +1,6800 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for rocksdb::Options.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory>
+#include <vector>
+
+#include "include/org_rocksdb_ColumnFamilyOptions.h"
+#include "include/org_rocksdb_ComparatorOptions.h"
+#include "include/org_rocksdb_DBOptions.h"
+#include "include/org_rocksdb_FlushOptions.h"
+#include "include/org_rocksdb_Options.h"
+#include "include/org_rocksdb_ReadOptions.h"
+#include "include/org_rocksdb_WriteOptions.h"
+
+#include "rocksjni/comparatorjnicallback.h"
+#include "rocksjni/portal.h"
+#include "rocksjni/statisticsjni.h"
+#include "rocksjni/table_filter_jnicallback.h"
+
+#include "rocksdb/comparator.h"
+#include "rocksdb/convenience.h"
+#include "rocksdb/db.h"
+#include "rocksdb/memtablerep.h"
+#include "rocksdb/merge_operator.h"
+#include "rocksdb/options.h"
+#include "rocksdb/rate_limiter.h"
+#include "rocksdb/slice_transform.h"
+#include "rocksdb/statistics.h"
+#include "rocksdb/table.h"
+#include "utilities/merge_operators.h"
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: newOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_Options_newOptions__(
+ JNIEnv*, jclass) {
+ auto* op = new rocksdb::Options();
+ return reinterpret_cast<jlong>(op);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: newOptions
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_Options_newOptions__JJ(
+ JNIEnv*, jclass, jlong jdboptions, jlong jcfoptions) {
+ auto* dbOpt = reinterpret_cast<const rocksdb::DBOptions*>(jdboptions);
+ auto* cfOpt =
+ reinterpret_cast<const rocksdb::ColumnFamilyOptions*>(jcfoptions);
+ auto* op = new rocksdb::Options(*dbOpt, *cfOpt);
+ return reinterpret_cast<jlong>(op);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: copyOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_copyOptions(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto new_opt =
+ new rocksdb::Options(*(reinterpret_cast<rocksdb::Options*>(jhandle)));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Options_disposeInternal(
+ JNIEnv*, jobject, jlong handle) {
+ auto* op = reinterpret_cast<rocksdb::Options*>(handle);
+ assert(op != nullptr);
+ delete op;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setIncreaseParallelism
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setIncreaseParallelism(
+ JNIEnv*, jobject, jlong jhandle, jint totalThreads) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->IncreaseParallelism(
+ static_cast<int>(totalThreads));
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCreateIfMissing
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setCreateIfMissing(
+ JNIEnv*, jobject, jlong jhandle, jboolean flag) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->create_if_missing = flag;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: createIfMissing
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_createIfMissing(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->create_if_missing;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCreateMissingColumnFamilies
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setCreateMissingColumnFamilies(
+ JNIEnv*, jobject, jlong jhandle, jboolean flag) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->create_missing_column_families =
+ flag;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: createMissingColumnFamilies
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_createMissingColumnFamilies(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->create_missing_column_families;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setComparatorHandle
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setComparatorHandle__JI(
+ JNIEnv*, jobject, jlong jhandle, jint builtinComparator) {
+ switch (builtinComparator) {
+ case 1:
+ reinterpret_cast<rocksdb::Options*>(jhandle)->comparator =
+ rocksdb::ReverseBytewiseComparator();
+ break;
+ default:
+ reinterpret_cast<rocksdb::Options*>(jhandle)->comparator =
+ rocksdb::BytewiseComparator();
+ break;
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setComparatorHandle
+ * Signature: (JJB)V
+ */
+void Java_org_rocksdb_Options_setComparatorHandle__JJB(
+ JNIEnv*, jobject, jlong jopt_handle, jlong jcomparator_handle,
+ jbyte jcomparator_type) {
+ rocksdb::Comparator* comparator = nullptr;
+ switch (jcomparator_type) {
+ // JAVA_COMPARATOR
+ case 0x0:
+ comparator =
+ reinterpret_cast<rocksdb::ComparatorJniCallback*>(jcomparator_handle);
+ break;
+
+ // JAVA_DIRECT_COMPARATOR
+ case 0x1:
+ comparator = reinterpret_cast<rocksdb::DirectComparatorJniCallback*>(
+ jcomparator_handle);
+ break;
+
+ // JAVA_NATIVE_COMPARATOR_WRAPPER
+ case 0x2:
+ comparator = reinterpret_cast<rocksdb::Comparator*>(jcomparator_handle);
+ break;
+ }
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
+ opt->comparator = comparator;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMergeOperatorName
+ * Signature: (JJjava/lang/String)V
+ */
+void Java_org_rocksdb_Options_setMergeOperatorName(
+ JNIEnv* env, jobject, jlong jhandle, jstring jop_name) {
+ const char* op_name = env->GetStringUTFChars(jop_name, nullptr);
+ if (op_name == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ options->merge_operator =
+ rocksdb::MergeOperators::CreateFromStringId(op_name);
+
+ env->ReleaseStringUTFChars(jop_name, op_name);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMergeOperator
+ * Signature: (JJjava/lang/String)V
+ */
+void Java_org_rocksdb_Options_setMergeOperator(
+ JNIEnv*, jobject, jlong jhandle, jlong mergeOperatorHandle) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->merge_operator =
+ *(reinterpret_cast<std::shared_ptr<rocksdb::MergeOperator>*>(
+ mergeOperatorHandle));
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionFilterHandle
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setCompactionFilterHandle(
+ JNIEnv*, jobject, jlong jopt_handle,
+ jlong jcompactionfilter_handle) {
+ reinterpret_cast<rocksdb::Options*>(jopt_handle)->
+ compaction_filter = reinterpret_cast<rocksdb::CompactionFilter*>
+ (jcompactionfilter_handle);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionFilterFactoryHandle
+ * Signature: (JJ)V
+ */
+void JNICALL Java_org_rocksdb_Options_setCompactionFilterFactoryHandle(
+ JNIEnv*, jobject, jlong jopt_handle,
+ jlong jcompactionfilterfactory_handle) {
+ auto* cff_factory =
+ reinterpret_cast<std::shared_ptr<rocksdb::CompactionFilterFactory> *>(
+ jcompactionfilterfactory_handle);
+ reinterpret_cast<rocksdb::Options*>(jopt_handle)->
+ compaction_filter_factory = *cff_factory;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWriteBufferSize
+ * Signature: (JJ)I
+ */
+void Java_org_rocksdb_Options_setWriteBufferSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong jwrite_buffer_size) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jwrite_buffer_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->write_buffer_size =
+ jwrite_buffer_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWriteBufferManager
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWriteBufferManager(
+ JNIEnv*, jobject, jlong joptions_handle,
+ jlong jwrite_buffer_manager_handle) {
+ auto* write_buffer_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::WriteBufferManager> *>(jwrite_buffer_manager_handle);
+ reinterpret_cast<rocksdb::Options*>(joptions_handle)->write_buffer_manager =
+ *write_buffer_manager;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: writeBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_writeBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->write_buffer_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxWriteBufferNumber
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxWriteBufferNumber(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jmax_write_buffer_number) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_write_buffer_number =
+ jmax_write_buffer_number;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setStatistics
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setStatistics(
+ JNIEnv*, jobject, jlong jhandle, jlong jstatistics_handle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* pSptr = reinterpret_cast<std::shared_ptr<rocksdb::StatisticsJni>*>(
+ jstatistics_handle);
+ opt->statistics = *pSptr;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: statistics
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_statistics(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ std::shared_ptr<rocksdb::Statistics> sptr = opt->statistics;
+ if (sptr == nullptr) {
+ return 0;
+ } else {
+ std::shared_ptr<rocksdb::Statistics>* pSptr =
+ new std::shared_ptr<rocksdb::Statistics>(sptr);
+ return reinterpret_cast<jlong>(pSptr);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxWriteBufferNumber
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxWriteBufferNumber(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_write_buffer_number;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: errorIfExists
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_errorIfExists(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->error_if_exists;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setErrorIfExists
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setErrorIfExists(
+ JNIEnv*, jobject, jlong jhandle, jboolean error_if_exists) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->error_if_exists =
+ static_cast<bool>(error_if_exists);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: paranoidChecks
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_paranoidChecks(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->paranoid_checks;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setParanoidChecks
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setParanoidChecks(
+ JNIEnv*, jobject, jlong jhandle, jboolean paranoid_checks) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->paranoid_checks =
+ static_cast<bool>(paranoid_checks);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setEnv
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setEnv(
+ JNIEnv*, jobject, jlong jhandle, jlong jenv) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->env =
+ reinterpret_cast<rocksdb::Env*>(jenv);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxTotalWalSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxTotalWalSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_total_wal_size) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_total_wal_size =
+ static_cast<jlong>(jmax_total_wal_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxTotalWalSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxTotalWalSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_total_wal_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxOpenFiles
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxOpenFiles(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_open_files;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxOpenFiles
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxOpenFiles(
+ JNIEnv*, jobject, jlong jhandle, jint max_open_files) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_open_files =
+ static_cast<int>(max_open_files);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxFileOpeningThreads
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxFileOpeningThreads(
+ JNIEnv*, jobject, jlong jhandle, jint jmax_file_opening_threads) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_file_opening_threads =
+ static_cast<int>(jmax_file_opening_threads);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxFileOpeningThreads
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxFileOpeningThreads(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<int>(opt->max_file_opening_threads);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: useFsync
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_useFsync(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->use_fsync;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setUseFsync
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setUseFsync(
+ JNIEnv*, jobject, jlong jhandle, jboolean use_fsync) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->use_fsync =
+ static_cast<bool>(use_fsync);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDbPaths
+ * Signature: (J[Ljava/lang/String;[J)V
+ */
+void Java_org_rocksdb_Options_setDbPaths(
+ JNIEnv* env, jobject, jlong jhandle, jobjectArray jpaths,
+ jlongArray jtarget_sizes) {
+ std::vector<rocksdb::DbPath> db_paths;
+ jlong* ptr_jtarget_size = env->GetLongArrayElements(jtarget_sizes, nullptr);
+ if (ptr_jtarget_size == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jboolean has_exception = JNI_FALSE;
+ const jsize len = env->GetArrayLength(jpaths);
+ for (jsize i = 0; i < len; i++) {
+ jobject jpath =
+ reinterpret_cast<jstring>(env->GetObjectArrayElement(jpaths, i));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+ std::string path = rocksdb::JniUtil::copyStdString(
+ env, static_cast<jstring>(jpath), &has_exception);
+ env->DeleteLocalRef(jpath);
+
+ if (has_exception == JNI_TRUE) {
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+
+ jlong jtarget_size = ptr_jtarget_size[i];
+
+ db_paths.push_back(
+ rocksdb::DbPath(path, static_cast<uint64_t>(jtarget_size)));
+ }
+
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->db_paths = db_paths;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: dbPathsLen
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_dbPathsLen(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->db_paths.size());
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: dbPaths
+ * Signature: (J[Ljava/lang/String;[J)V
+ */
+void Java_org_rocksdb_Options_dbPaths(
+ JNIEnv* env, jobject, jlong jhandle, jobjectArray jpaths,
+ jlongArray jtarget_sizes) {
+ jlong* ptr_jtarget_size = env->GetLongArrayElements(jtarget_sizes, nullptr);
+ if (ptr_jtarget_size == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ const jsize len = env->GetArrayLength(jpaths);
+ for (jsize i = 0; i < len; i++) {
+ rocksdb::DbPath db_path = opt->db_paths[i];
+
+ jstring jpath = env->NewStringUTF(db_path.path.c_str());
+ if (jpath == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+ env->SetObjectArrayElement(jpaths, i, jpath);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jpath);
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+
+ ptr_jtarget_size[i] = static_cast<jint>(db_path.target_size);
+ }
+
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_COMMIT);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: dbLogDir
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_Options_dbLogDir(
+ JNIEnv* env, jobject, jlong jhandle) {
+ return env->NewStringUTF(
+ reinterpret_cast<rocksdb::Options*>(jhandle)->db_log_dir.c_str());
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDbLogDir
+ * Signature: (JLjava/lang/String)V
+ */
+void Java_org_rocksdb_Options_setDbLogDir(
+ JNIEnv* env, jobject, jlong jhandle, jstring jdb_log_dir) {
+ const char* log_dir = env->GetStringUTFChars(jdb_log_dir, nullptr);
+ if (log_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ reinterpret_cast<rocksdb::Options*>(jhandle)->db_log_dir.assign(log_dir);
+ env->ReleaseStringUTFChars(jdb_log_dir, log_dir);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: walDir
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_Options_walDir(
+ JNIEnv* env, jobject, jlong jhandle) {
+ return env->NewStringUTF(
+ reinterpret_cast<rocksdb::Options*>(jhandle)->wal_dir.c_str());
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWalDir
+ * Signature: (JLjava/lang/String)V
+ */
+void Java_org_rocksdb_Options_setWalDir(
+ JNIEnv* env, jobject, jlong jhandle, jstring jwal_dir) {
+ const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
+ if (wal_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ reinterpret_cast<rocksdb::Options*>(jhandle)->wal_dir.assign(wal_dir);
+ env->ReleaseStringUTFChars(jwal_dir, wal_dir);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: deleteObsoleteFilesPeriodMicros
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_deleteObsoleteFilesPeriodMicros(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->delete_obsolete_files_period_micros;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDeleteObsoleteFilesPeriodMicros
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setDeleteObsoleteFilesPeriodMicros(
+ JNIEnv*, jobject, jlong jhandle, jlong micros) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->delete_obsolete_files_period_micros = static_cast<int64_t>(micros);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setBaseBackgroundCompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setBaseBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle, jint max) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->base_background_compactions =
+ static_cast<int>(max);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: baseBackgroundCompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_baseBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->base_background_compactions;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxBackgroundCompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_background_compactions;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxBackgroundCompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle, jint max) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_background_compactions =
+ static_cast<int>(max);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxSubcompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxSubcompactions(
+ JNIEnv*, jobject, jlong jhandle, jint max) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_subcompactions =
+ static_cast<int32_t>(max);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxSubcompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxSubcompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_subcompactions;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxBackgroundFlushes
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxBackgroundFlushes(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_background_flushes;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxBackgroundFlushes
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxBackgroundFlushes(
+ JNIEnv*, jobject, jlong jhandle, jint max_background_flushes) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_background_flushes =
+ static_cast<int>(max_background_flushes);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxBackgroundJobs
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxBackgroundJobs(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_background_jobs;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxBackgroundJobs
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxBackgroundJobs(
+ JNIEnv*, jobject, jlong jhandle, jint max_background_jobs) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_background_jobs =
+ static_cast<int>(max_background_jobs);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxLogFileSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxLogFileSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_log_file_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxLogFileSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxLogFileSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong max_log_file_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(max_log_file_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_log_file_size =
+ max_log_file_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: logFileTimeToRoll
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_logFileTimeToRoll(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->log_file_time_to_roll;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLogFileTimeToRoll
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setLogFileTimeToRoll(
+ JNIEnv* env, jobject, jlong jhandle, jlong log_file_time_to_roll) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(log_file_time_to_roll);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->log_file_time_to_roll =
+ log_file_time_to_roll;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: keepLogFileNum
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_keepLogFileNum(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->keep_log_file_num;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setKeepLogFileNum
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setKeepLogFileNum(
+ JNIEnv* env, jobject, jlong jhandle, jlong keep_log_file_num) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(keep_log_file_num);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->keep_log_file_num =
+ keep_log_file_num;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: recycleLogFileNum
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_recycleLogFileNum(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->recycle_log_file_num;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setRecycleLogFileNum
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setRecycleLogFileNum(
+ JNIEnv* env, jobject, jlong jhandle, jlong recycle_log_file_num) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(recycle_log_file_num);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->recycle_log_file_num =
+ recycle_log_file_num;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxManifestFileSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxManifestFileSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_manifest_file_size;
+}
+
+/*
+ * Method: memTableFactoryName
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_Options_memTableFactoryName(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ rocksdb::MemTableRepFactory* tf = opt->memtable_factory.get();
+
+ // Should never be nullptr.
+ // Default memtable factory is SkipListFactory
+ assert(tf);
+
+ // temporarly fix for the historical typo
+ if (strcmp(tf->Name(), "HashLinkListRepFactory") == 0) {
+ return env->NewStringUTF("HashLinkedListRepFactory");
+ }
+
+ return env->NewStringUTF(tf->Name());
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxManifestFileSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxManifestFileSize(
+ JNIEnv*, jobject, jlong jhandle, jlong max_manifest_file_size) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_manifest_file_size =
+ static_cast<int64_t>(max_manifest_file_size);
+}
+
+/*
+ * Method: setMemTableFactory
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMemTableFactory(
+ JNIEnv*, jobject, jlong jhandle, jlong jfactory_handle) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->memtable_factory.reset(
+ reinterpret_cast<rocksdb::MemTableRepFactory*>(jfactory_handle));
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setRateLimiter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setRateLimiter(
+ JNIEnv*, jobject, jlong jhandle, jlong jrate_limiter_handle) {
+ std::shared_ptr<rocksdb::RateLimiter>* pRateLimiter =
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(
+ jrate_limiter_handle);
+ reinterpret_cast<rocksdb::Options*>(jhandle)->rate_limiter = *pRateLimiter;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setSstFileManager
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setSstFileManager(
+ JNIEnv*, jobject, jlong jhandle, jlong jsst_file_manager_handle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(
+ jsst_file_manager_handle);
+ reinterpret_cast<rocksdb::Options*>(jhandle)->sst_file_manager =
+ *sptr_sst_file_manager;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLogger
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setLogger(
+ JNIEnv*, jobject, jlong jhandle, jlong jlogger_handle) {
+ std::shared_ptr<rocksdb::LoggerJniCallback>* pLogger =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(
+ jlogger_handle);
+ reinterpret_cast<rocksdb::Options*>(jhandle)->info_log = *pLogger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setInfoLogLevel
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setInfoLogLevel(
+ JNIEnv*, jobject, jlong jhandle, jbyte jlog_level) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->info_log_level =
+ static_cast<rocksdb::InfoLogLevel>(jlog_level);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: infoLogLevel
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_infoLogLevel(
+ JNIEnv*, jobject, jlong jhandle) {
+ return static_cast<jbyte>(
+ reinterpret_cast<rocksdb::Options*>(jhandle)->info_log_level);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: tableCacheNumshardbits
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_tableCacheNumshardbits(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->table_cache_numshardbits;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setTableCacheNumshardbits
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setTableCacheNumshardbits(
+ JNIEnv*, jobject, jlong jhandle, jint table_cache_numshardbits) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->table_cache_numshardbits =
+ static_cast<int>(table_cache_numshardbits);
+}
+
+/*
+ * Method: useFixedLengthPrefixExtractor
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_useFixedLengthPrefixExtractor(
+ JNIEnv*, jobject, jlong jhandle, jint jprefix_length) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->prefix_extractor.reset(
+ rocksdb::NewFixedPrefixTransform(static_cast<int>(jprefix_length)));
+}
+
+/*
+ * Method: useCappedPrefixExtractor
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_useCappedPrefixExtractor(
+ JNIEnv*, jobject, jlong jhandle, jint jprefix_length) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->prefix_extractor.reset(
+ rocksdb::NewCappedPrefixTransform(static_cast<int>(jprefix_length)));
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: walTtlSeconds
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_walTtlSeconds(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->WAL_ttl_seconds;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWalTtlSeconds
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWalTtlSeconds(
+ JNIEnv*, jobject, jlong jhandle, jlong WAL_ttl_seconds) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->WAL_ttl_seconds =
+ static_cast<int64_t>(WAL_ttl_seconds);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: walTtlSeconds
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_walSizeLimitMB(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->WAL_size_limit_MB;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWalSizeLimitMB
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWalSizeLimitMB(
+ JNIEnv*, jobject, jlong jhandle, jlong WAL_size_limit_MB) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->WAL_size_limit_MB =
+ static_cast<int64_t>(WAL_size_limit_MB);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: manifestPreallocationSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_manifestPreallocationSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->manifest_preallocation_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setManifestPreallocationSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setManifestPreallocationSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong preallocation_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(preallocation_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->manifest_preallocation_size =
+ preallocation_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Method: setTableFactory
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setTableFactory(
+ JNIEnv*, jobject, jlong jhandle, jlong jtable_factory_handle) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* table_factory =
+ reinterpret_cast<rocksdb::TableFactory*>(jtable_factory_handle);
+ options->table_factory.reset(table_factory);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: allowMmapReads
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_allowMmapReads(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->allow_mmap_reads;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAllowMmapReads
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAllowMmapReads(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow_mmap_reads) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->allow_mmap_reads =
+ static_cast<bool>(allow_mmap_reads);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: allowMmapWrites
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_allowMmapWrites(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->allow_mmap_writes;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAllowMmapWrites
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAllowMmapWrites(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow_mmap_writes) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->allow_mmap_writes =
+ static_cast<bool>(allow_mmap_writes);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: useDirectReads
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_useDirectReads(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->use_direct_reads;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setUseDirectReads
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setUseDirectReads(
+ JNIEnv*, jobject, jlong jhandle, jboolean use_direct_reads) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->use_direct_reads =
+ static_cast<bool>(use_direct_reads);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: useDirectIoForFlushAndCompaction
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_useDirectIoForFlushAndCompaction(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->use_direct_io_for_flush_and_compaction;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setUseDirectIoForFlushAndCompaction
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setUseDirectIoForFlushAndCompaction(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean use_direct_io_for_flush_and_compaction) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->use_direct_io_for_flush_and_compaction =
+ static_cast<bool>(use_direct_io_for_flush_and_compaction);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAllowFAllocate
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAllowFAllocate(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_fallocate) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->allow_fallocate =
+ static_cast<bool>(jallow_fallocate);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: allowFAllocate
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_allowFAllocate(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->allow_fallocate);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: isFdCloseOnExec
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_isFdCloseOnExec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->is_fd_close_on_exec;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setIsFdCloseOnExec
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setIsFdCloseOnExec(
+ JNIEnv*, jobject, jlong jhandle, jboolean is_fd_close_on_exec) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->is_fd_close_on_exec =
+ static_cast<bool>(is_fd_close_on_exec);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: statsDumpPeriodSec
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_statsDumpPeriodSec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->stats_dump_period_sec;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setStatsDumpPeriodSec
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setStatsDumpPeriodSec(
+ JNIEnv*, jobject, jlong jhandle,
+ jint stats_dump_period_sec) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->stats_dump_period_sec =
+ static_cast<int>(stats_dump_period_sec);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: adviseRandomOnOpen
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_adviseRandomOnOpen(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->advise_random_on_open;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAdviseRandomOnOpen
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAdviseRandomOnOpen(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean advise_random_on_open) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->advise_random_on_open =
+ static_cast<bool>(advise_random_on_open);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDbWriteBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setDbWriteBufferSize(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jdb_write_buffer_size) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->db_write_buffer_size = static_cast<size_t>(jdb_write_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: dbWriteBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_dbWriteBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->db_write_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAccessHintOnCompactionStart
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setAccessHintOnCompactionStart(
+ JNIEnv*, jobject, jlong jhandle,
+ jbyte jaccess_hint_value) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->access_hint_on_compaction_start =
+ rocksdb::AccessHintJni::toCppAccessHint(jaccess_hint_value);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: accessHintOnCompactionStart
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_accessHintOnCompactionStart(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb::AccessHintJni::toJavaAccessHint(
+ opt->access_hint_on_compaction_start);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setNewTableReaderForCompactionInputs
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setNewTableReaderForCompactionInputs(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean jnew_table_reader_for_compaction_inputs) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->new_table_reader_for_compaction_inputs =
+ static_cast<bool>(jnew_table_reader_for_compaction_inputs);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: newTableReaderForCompactionInputs
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_newTableReaderForCompactionInputs(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<bool>(opt->new_table_reader_for_compaction_inputs);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionReadaheadSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setCompactionReadaheadSize(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jcompaction_readahead_size) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->compaction_readahead_size =
+ static_cast<size_t>(jcompaction_readahead_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: compactionReadaheadSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_compactionReadaheadSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->compaction_readahead_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setRandomAccessMaxBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setRandomAccessMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jrandom_access_max_buffer_size) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->random_access_max_buffer_size =
+ static_cast<size_t>(jrandom_access_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: randomAccessMaxBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_randomAccessMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->random_access_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWritableFileMaxBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWritableFileMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jwritable_file_max_buffer_size) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->writable_file_max_buffer_size =
+ static_cast<size_t>(jwritable_file_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: writableFileMaxBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_writableFileMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->writable_file_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: useAdaptiveMutex
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_useAdaptiveMutex(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->use_adaptive_mutex;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setUseAdaptiveMutex
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setUseAdaptiveMutex(
+ JNIEnv*, jobject, jlong jhandle, jboolean use_adaptive_mutex) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->use_adaptive_mutex =
+ static_cast<bool>(use_adaptive_mutex);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: bytesPerSync
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_bytesPerSync(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->bytes_per_sync;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setBytesPerSync
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setBytesPerSync(
+ JNIEnv*, jobject, jlong jhandle, jlong bytes_per_sync) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->bytes_per_sync =
+ static_cast<int64_t>(bytes_per_sync);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWalBytesPerSync
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWalBytesPerSync(
+ JNIEnv*, jobject, jlong jhandle, jlong jwal_bytes_per_sync) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->wal_bytes_per_sync =
+ static_cast<int64_t>(jwal_bytes_per_sync);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: walBytesPerSync
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_walBytesPerSync(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->wal_bytes_per_sync);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setEnableThreadTracking
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setEnableThreadTracking(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenable_thread_tracking) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->enable_thread_tracking = static_cast<bool>(jenable_thread_tracking);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: enableThreadTracking
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_enableThreadTracking(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->enable_thread_tracking);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDelayedWriteRate
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setDelayedWriteRate(
+ JNIEnv*, jobject, jlong jhandle, jlong jdelayed_write_rate) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->delayed_write_rate = static_cast<uint64_t>(jdelayed_write_rate);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: delayedWriteRate
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_delayedWriteRate(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opt->delayed_write_rate);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setEnablePipelinedWrite
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setEnablePipelinedWrite(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenable_pipelined_write) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->enable_pipelined_write = jenable_pipelined_write == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: enablePipelinedWrite
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_enablePipelinedWrite(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->enable_pipelined_write);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAllowConcurrentMemtableWrite
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAllowConcurrentMemtableWrite(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->allow_concurrent_memtable_write = static_cast<bool>(allow);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: allowConcurrentMemtableWrite
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_allowConcurrentMemtableWrite(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->allow_concurrent_memtable_write;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setEnableWriteThreadAdaptiveYield
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setEnableWriteThreadAdaptiveYield(
+ JNIEnv*, jobject, jlong jhandle, jboolean yield) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->enable_write_thread_adaptive_yield = static_cast<bool>(yield);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: enableWriteThreadAdaptiveYield
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_enableWriteThreadAdaptiveYield(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->enable_write_thread_adaptive_yield;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWriteThreadMaxYieldUsec
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWriteThreadMaxYieldUsec(
+ JNIEnv*, jobject, jlong jhandle, jlong max) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->write_thread_max_yield_usec =
+ static_cast<int64_t>(max);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: writeThreadMaxYieldUsec
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_writeThreadMaxYieldUsec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->write_thread_max_yield_usec;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWriteThreadSlowYieldUsec
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWriteThreadSlowYieldUsec(
+ JNIEnv*, jobject, jlong jhandle, jlong slow) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->write_thread_slow_yield_usec =
+ static_cast<int64_t>(slow);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: writeThreadSlowYieldUsec
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_writeThreadSlowYieldUsec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->write_thread_slow_yield_usec;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setSkipStatsUpdateOnDbOpen
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setSkipStatsUpdateOnDbOpen(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean jskip_stats_update_on_db_open) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->skip_stats_update_on_db_open =
+ static_cast<bool>(jskip_stats_update_on_db_open);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: skipStatsUpdateOnDbOpen
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_skipStatsUpdateOnDbOpen(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->skip_stats_update_on_db_open);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWalRecoveryMode
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setWalRecoveryMode(
+ JNIEnv*, jobject, jlong jhandle,
+ jbyte jwal_recovery_mode_value) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->wal_recovery_mode = rocksdb::WALRecoveryModeJni::toCppWALRecoveryMode(
+ jwal_recovery_mode_value);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: walRecoveryMode
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_walRecoveryMode(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb::WALRecoveryModeJni::toJavaWALRecoveryMode(
+ opt->wal_recovery_mode);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAllow2pc
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAllow2pc(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_2pc) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->allow_2pc = static_cast<bool>(jallow_2pc);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: allow2pc
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_allow2pc(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->allow_2pc);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setRowCache
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setRowCache(
+ JNIEnv*, jobject, jlong jhandle, jlong jrow_cache_handle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* row_cache =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache>*>(jrow_cache_handle);
+ opt->row_cache = *row_cache;
+}
+
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setWalFilter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setWalFilter(
+ JNIEnv*, jobject, jlong jhandle, jlong jwal_filter_handle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* wal_filter =
+ reinterpret_cast<rocksdb::WalFilterJniCallback*>(jwal_filter_handle);
+ opt->wal_filter = wal_filter;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setFailIfOptionsFileError
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setFailIfOptionsFileError(
+ JNIEnv*, jobject, jlong jhandle, jboolean jfail_if_options_file_error) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->fail_if_options_file_error =
+ static_cast<bool>(jfail_if_options_file_error);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: failIfOptionsFileError
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_failIfOptionsFileError(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->fail_if_options_file_error);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDumpMallocStats
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setDumpMallocStats(
+ JNIEnv*, jobject, jlong jhandle, jboolean jdump_malloc_stats) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->dump_malloc_stats = static_cast<bool>(jdump_malloc_stats);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: dumpMallocStats
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_dumpMallocStats(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->dump_malloc_stats);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAvoidFlushDuringRecovery
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAvoidFlushDuringRecovery(
+ JNIEnv*, jobject, jlong jhandle, jboolean javoid_flush_during_recovery) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->avoid_flush_during_recovery =
+ static_cast<bool>(javoid_flush_during_recovery);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: avoidFlushDuringRecovery
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_avoidFlushDuringRecovery(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->avoid_flush_during_recovery);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAvoidFlushDuringShutdown
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAvoidFlushDuringShutdown(
+ JNIEnv*, jobject, jlong jhandle, jboolean javoid_flush_during_shutdown) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->avoid_flush_during_shutdown =
+ static_cast<bool>(javoid_flush_during_shutdown);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: avoidFlushDuringShutdown
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_avoidFlushDuringShutdown(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->avoid_flush_during_shutdown);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAllowIngestBehind
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAllowIngestBehind(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_ingest_behind) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->allow_ingest_behind = jallow_ingest_behind == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: allowIngestBehind
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_allowIngestBehind(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->allow_ingest_behind);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setPreserveDeletes
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setPreserveDeletes(
+ JNIEnv*, jobject, jlong jhandle, jboolean jpreserve_deletes) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->preserve_deletes = jpreserve_deletes == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: preserveDeletes
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_preserveDeletes(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->preserve_deletes);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setTwoWriteQueues
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setTwoWriteQueues(
+ JNIEnv*, jobject, jlong jhandle, jboolean jtwo_write_queues) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->two_write_queues = jtwo_write_queues == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: twoWriteQueues
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_twoWriteQueues(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->two_write_queues);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setManualWalFlush
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setManualWalFlush(
+ JNIEnv*, jobject, jlong jhandle, jboolean jmanual_wal_flush) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->manual_wal_flush = jmanual_wal_flush == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: manualWalFlush
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_manualWalFlush(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->manual_wal_flush);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setAtomicFlush
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setAtomicFlush(
+ JNIEnv*, jobject, jlong jhandle, jboolean jatomic_flush) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->atomic_flush = jatomic_flush == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: atomicFlush
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_atomicFlush(
+ JNIEnv *, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jboolean>(opt->atomic_flush);
+}
+
+/*
+ * Method: tableFactoryName
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_Options_tableFactoryName(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ rocksdb::TableFactory* tf = opt->table_factory.get();
+
+ // Should never be nullptr.
+ // Default memtable factory is SkipListFactory
+ assert(tf);
+
+ return env->NewStringUTF(tf->Name());
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: minWriteBufferNumberToMerge
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_minWriteBufferNumberToMerge(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->min_write_buffer_number_to_merge;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMinWriteBufferNumberToMerge
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMinWriteBufferNumberToMerge(
+ JNIEnv*, jobject, jlong jhandle, jint jmin_write_buffer_number_to_merge) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->min_write_buffer_number_to_merge =
+ static_cast<int>(jmin_write_buffer_number_to_merge);
+}
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxWriteBufferNumberToMaintain
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_maxWriteBufferNumberToMaintain(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_write_buffer_number_to_maintain;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxWriteBufferNumberToMaintain
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxWriteBufferNumberToMaintain(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jmax_write_buffer_number_to_maintain) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_write_buffer_number_to_maintain =
+ static_cast<int>(jmax_write_buffer_number_to_maintain);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompressionType
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setCompressionType(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompression_type_value) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opts->compression = rocksdb::CompressionTypeJni::toCppCompressionType(
+ jcompression_type_value);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: compressionType
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_compressionType(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb::CompressionTypeJni::toJavaCompressionType(opts->compression);
+}
+
+/**
+ * Helper method to convert a Java byte array of compression levels
+ * to a C++ vector of rocksdb::CompressionType
+ *
+ * @param env A pointer to the Java environment
+ * @param jcompression_levels A reference to a java byte array
+ * where each byte indicates a compression level
+ *
+ * @return A std::unique_ptr to the vector, or std::unique_ptr(nullptr) if a JNI
+ * exception occurs
+ */
+std::unique_ptr<std::vector<rocksdb::CompressionType>>rocksdb_compression_vector_helper(
+ JNIEnv* env, jbyteArray jcompression_levels) {
+ jsize len = env->GetArrayLength(jcompression_levels);
+ jbyte* jcompression_level =
+ env->GetByteArrayElements(jcompression_levels, nullptr);
+ if (jcompression_level == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return std::unique_ptr<std::vector<rocksdb::CompressionType>>();
+ }
+
+ auto* compression_levels = new std::vector<rocksdb::CompressionType>();
+ std::unique_ptr<std::vector<rocksdb::CompressionType>>
+ uptr_compression_levels(compression_levels);
+
+ for (jsize i = 0; i < len; i++) {
+ jbyte jcl = jcompression_level[i];
+ compression_levels->push_back(static_cast<rocksdb::CompressionType>(jcl));
+ }
+
+ env->ReleaseByteArrayElements(jcompression_levels, jcompression_level,
+ JNI_ABORT);
+
+ return uptr_compression_levels;
+}
+
+/**
+ * Helper method to convert a C++ vector of rocksdb::CompressionType
+ * to a Java byte array of compression levels
+ *
+ * @param env A pointer to the Java environment
+ * @param jcompression_levels A reference to a java byte array
+ * where each byte indicates a compression level
+ *
+ * @return A jbytearray or nullptr if an exception occurs
+ */
+jbyteArray rocksdb_compression_list_helper(
+ JNIEnv* env, std::vector<rocksdb::CompressionType> compression_levels) {
+ const size_t len = compression_levels.size();
+ jbyte* jbuf = new jbyte[len];
+
+ for (size_t i = 0; i < len; i++) {
+ jbuf[i] = compression_levels[i];
+ }
+
+ // insert in java array
+ jbyteArray jcompression_levels = env->NewByteArray(static_cast<jsize>(len));
+ if (jcompression_levels == nullptr) {
+ // exception thrown: OutOfMemoryError
+ delete[] jbuf;
+ return nullptr;
+ }
+ env->SetByteArrayRegion(jcompression_levels, 0, static_cast<jsize>(len),
+ jbuf);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jcompression_levels);
+ delete[] jbuf;
+ return nullptr;
+ }
+
+ delete[] jbuf;
+
+ return jcompression_levels;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompressionPerLevel
+ * Signature: (J[B)V
+ */
+void Java_org_rocksdb_Options_setCompressionPerLevel(
+ JNIEnv* env, jobject, jlong jhandle, jbyteArray jcompressionLevels) {
+ auto uptr_compression_levels =
+ rocksdb_compression_vector_helper(env, jcompressionLevels);
+ if (!uptr_compression_levels) {
+ // exception occurred
+ return;
+ }
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ options->compression_per_level = *(uptr_compression_levels.get());
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: compressionPerLevel
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_Options_compressionPerLevel(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb_compression_list_helper(env, options->compression_per_level);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setBottommostCompressionType
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setBottommostCompressionType(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompression_type_value) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ options->bottommost_compression =
+ rocksdb::CompressionTypeJni::toCppCompressionType(
+ jcompression_type_value);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: bottommostCompressionType
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_bottommostCompressionType(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb::CompressionTypeJni::toJavaCompressionType(
+ options->bottommost_compression);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setBottommostCompressionOptions
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setBottommostCompressionOptions(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jbottommost_compression_options_handle) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* bottommost_compression_options =
+ reinterpret_cast<rocksdb::CompressionOptions*>(
+ jbottommost_compression_options_handle);
+ options->bottommost_compression_opts = *bottommost_compression_options;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompressionOptions
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setCompressionOptions(
+ JNIEnv*, jobject, jlong jhandle, jlong jcompression_options_handle) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* compression_options = reinterpret_cast<rocksdb::CompressionOptions*>(
+ jcompression_options_handle);
+ options->compression_opts = *compression_options;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionStyle
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setCompactionStyle(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompaction_style) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ options->compaction_style =
+ rocksdb::CompactionStyleJni::toCppCompactionStyle(
+ jcompaction_style);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: compactionStyle
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_compactionStyle(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb::CompactionStyleJni::toJavaCompactionStyle(
+ options->compaction_style);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxTableFilesSizeFIFO
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxTableFilesSizeFIFO(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_table_files_size) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->compaction_options_fifo.max_table_files_size =
+ static_cast<uint64_t>(jmax_table_files_size);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxTableFilesSizeFIFO
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxTableFilesSizeFIFO(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->compaction_options_fifo.max_table_files_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: numLevels
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_numLevels(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->num_levels;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setNumLevels
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setNumLevels(
+ JNIEnv*, jobject, jlong jhandle, jint jnum_levels) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->num_levels =
+ static_cast<int>(jnum_levels);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: levelZeroFileNumCompactionTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_levelZeroFileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_file_num_compaction_trigger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevelZeroFileNumCompactionTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setLevelZeroFileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jlevel0_file_num_compaction_trigger) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_file_num_compaction_trigger =
+ static_cast<int>(jlevel0_file_num_compaction_trigger);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: levelZeroSlowdownWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_levelZeroSlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_slowdown_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevelSlowdownWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setLevelZeroSlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_slowdown_writes_trigger) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->level0_slowdown_writes_trigger =
+ static_cast<int>(jlevel0_slowdown_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: levelZeroStopWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_levelZeroStopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_stop_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevelStopWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setLevelZeroStopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_stop_writes_trigger) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->level0_stop_writes_trigger =
+ static_cast<int>(jlevel0_stop_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: targetFileSizeBase
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_targetFileSizeBase(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->target_file_size_base;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setTargetFileSizeBase
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setTargetFileSizeBase(
+ JNIEnv*, jobject, jlong jhandle, jlong jtarget_file_size_base) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->target_file_size_base =
+ static_cast<uint64_t>(jtarget_file_size_base);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: targetFileSizeMultiplier
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_targetFileSizeMultiplier(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->target_file_size_multiplier;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setTargetFileSizeMultiplier
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setTargetFileSizeMultiplier(
+ JNIEnv*, jobject, jlong jhandle, jint jtarget_file_size_multiplier) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->target_file_size_multiplier =
+ static_cast<int>(jtarget_file_size_multiplier);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxBytesForLevelBase
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxBytesForLevelBase(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_bytes_for_level_base;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxBytesForLevelBase
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxBytesForLevelBase(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_bytes_for_level_base) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_bytes_for_level_base =
+ static_cast<int64_t>(jmax_bytes_for_level_base);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: levelCompactionDynamicLevelBytes
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_levelCompactionDynamicLevelBytes(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level_compaction_dynamic_level_bytes;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevelCompactionDynamicLevelBytes
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setLevelCompactionDynamicLevelBytes(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenable_dynamic_level_bytes) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level_compaction_dynamic_level_bytes = (jenable_dynamic_level_bytes);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxBytesForLevelMultiplier
+ * Signature: (J)D
+ */
+jdouble Java_org_rocksdb_Options_maxBytesForLevelMultiplier(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_bytes_for_level_multiplier;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxBytesForLevelMultiplier
+ * Signature: (JD)V
+ */
+void Java_org_rocksdb_Options_setMaxBytesForLevelMultiplier(
+ JNIEnv*, jobject, jlong jhandle, jdouble jmax_bytes_for_level_multiplier) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_bytes_for_level_multiplier =
+ static_cast<double>(jmax_bytes_for_level_multiplier);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxCompactionBytes
+ * Signature: (J)I
+ */
+jlong Java_org_rocksdb_Options_maxCompactionBytes(
+ JNIEnv*, jobject, jlong jhandle) {
+ return static_cast<jlong>(
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_compaction_bytes);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxCompactionBytes
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMaxCompactionBytes(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_compaction_bytes) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_compaction_bytes =
+ static_cast<uint64_t>(jmax_compaction_bytes);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: arenaBlockSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_arenaBlockSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->arena_block_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setArenaBlockSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setArenaBlockSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong jarena_block_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(jarena_block_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->arena_block_size =
+ jarena_block_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: disableAutoCompactions
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_disableAutoCompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->disable_auto_compactions;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setDisableAutoCompactions
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setDisableAutoCompactions(
+ JNIEnv*, jobject, jlong jhandle, jboolean jdisable_auto_compactions) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->disable_auto_compactions =
+ static_cast<bool>(jdisable_auto_compactions);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxSequentialSkipInIterations
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxSequentialSkipInIterations(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_sequential_skip_in_iterations;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxSequentialSkipInIterations
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxSequentialSkipInIterations(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jmax_sequential_skip_in_iterations) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_sequential_skip_in_iterations =
+ static_cast<int64_t>(jmax_sequential_skip_in_iterations);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: inplaceUpdateSupport
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_inplaceUpdateSupport(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->inplace_update_support;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setInplaceUpdateSupport
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setInplaceUpdateSupport(
+ JNIEnv*, jobject, jlong jhandle, jboolean jinplace_update_support) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->inplace_update_support =
+ static_cast<bool>(jinplace_update_support);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: inplaceUpdateNumLocks
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_inplaceUpdateNumLocks(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->inplace_update_num_locks;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setInplaceUpdateNumLocks
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setInplaceUpdateNumLocks(
+ JNIEnv* env, jobject, jlong jhandle, jlong jinplace_update_num_locks) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jinplace_update_num_locks);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->inplace_update_num_locks =
+ jinplace_update_num_locks;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: memtablePrefixBloomSizeRatio
+ * Signature: (J)I
+ */
+jdouble Java_org_rocksdb_Options_memtablePrefixBloomSizeRatio(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->memtable_prefix_bloom_size_ratio;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMemtablePrefixBloomSizeRatio
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setMemtablePrefixBloomSizeRatio(
+ JNIEnv*, jobject, jlong jhandle,
+ jdouble jmemtable_prefix_bloom_size_ratio) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->memtable_prefix_bloom_size_ratio =
+ static_cast<double>(jmemtable_prefix_bloom_size_ratio);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: bloomLocality
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_bloomLocality(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->bloom_locality;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setBloomLocality
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setBloomLocality(
+ JNIEnv*, jobject, jlong jhandle, jint jbloom_locality) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->bloom_locality =
+ static_cast<int32_t>(jbloom_locality);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxSuccessiveMerges
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_maxSuccessiveMerges(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->max_successive_merges;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxSuccessiveMerges
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMaxSuccessiveMerges(
+ JNIEnv* env, jobject, jlong jhandle, jlong jmax_successive_merges) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jmax_successive_merges);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->max_successive_merges =
+ jmax_successive_merges;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: optimizeFiltersForHits
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_optimizeFiltersForHits(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->optimize_filters_for_hits;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setOptimizeFiltersForHits
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setOptimizeFiltersForHits(
+ JNIEnv*, jobject, jlong jhandle, jboolean joptimize_filters_for_hits) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->optimize_filters_for_hits =
+ static_cast<bool>(joptimize_filters_for_hits);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: optimizeForSmallDb
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Options_optimizeForSmallDb(
+ JNIEnv*, jobject, jlong jhandle) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->OptimizeForSmallDb();
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: optimizeForPointLookup
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_optimizeForPointLookup(
+ JNIEnv*, jobject, jlong jhandle, jlong block_cache_size_mb) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->OptimizeForPointLookup(
+ block_cache_size_mb);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: optimizeLevelStyleCompaction
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_optimizeLevelStyleCompaction(
+ JNIEnv*, jobject, jlong jhandle, jlong memtable_memory_budget) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->OptimizeLevelStyleCompaction(
+ memtable_memory_budget);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: optimizeUniversalStyleCompaction
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_optimizeUniversalStyleCompaction(
+ JNIEnv*, jobject, jlong jhandle, jlong memtable_memory_budget) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->OptimizeUniversalStyleCompaction(memtable_memory_budget);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: prepareForBulkLoad
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Options_prepareForBulkLoad(
+ JNIEnv*, jobject, jlong jhandle) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->PrepareForBulkLoad();
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: memtableHugePageSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_memtableHugePageSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->memtable_huge_page_size;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMemtableHugePageSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setMemtableHugePageSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong jmemtable_huge_page_size) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jmemtable_huge_page_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->memtable_huge_page_size =
+ jmemtable_huge_page_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: softPendingCompactionBytesLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_softPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->soft_pending_compaction_bytes_limit;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setSoftPendingCompactionBytesLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setSoftPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jsoft_pending_compaction_bytes_limit) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->soft_pending_compaction_bytes_limit =
+ static_cast<int64_t>(jsoft_pending_compaction_bytes_limit);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: softHardCompactionBytesLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_hardPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->hard_pending_compaction_bytes_limit;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setHardPendingCompactionBytesLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setHardPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jhard_pending_compaction_bytes_limit) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->hard_pending_compaction_bytes_limit =
+ static_cast<int64_t>(jhard_pending_compaction_bytes_limit);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: level0FileNumCompactionTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_level0FileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_file_num_compaction_trigger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevel0FileNumCompactionTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setLevel0FileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jlevel0_file_num_compaction_trigger) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_file_num_compaction_trigger =
+ static_cast<int32_t>(jlevel0_file_num_compaction_trigger);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: level0SlowdownWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_level0SlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_slowdown_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevel0SlowdownWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setLevel0SlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_slowdown_writes_trigger) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->level0_slowdown_writes_trigger =
+ static_cast<int32_t>(jlevel0_slowdown_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: level0StopWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_Options_level0StopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->level0_stop_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setLevel0StopWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Options_setLevel0StopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_stop_writes_trigger) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->level0_stop_writes_trigger =
+ static_cast<int32_t>(jlevel0_stop_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: maxBytesForLevelMultiplierAdditional
+ * Signature: (J)[I
+ */
+jintArray Java_org_rocksdb_Options_maxBytesForLevelMultiplierAdditional(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto mbflma = reinterpret_cast<rocksdb::Options*>(jhandle)
+ ->max_bytes_for_level_multiplier_additional;
+
+ const size_t size = mbflma.size();
+
+ jint* additionals = new jint[size];
+ for (size_t i = 0; i < size; i++) {
+ additionals[i] = static_cast<jint>(mbflma[i]);
+ }
+
+ jsize jlen = static_cast<jsize>(size);
+ jintArray result = env->NewIntArray(jlen);
+ if (result == nullptr) {
+ // exception thrown: OutOfMemoryError
+ delete[] additionals;
+ return nullptr;
+ }
+
+ env->SetIntArrayRegion(result, 0, jlen, additionals);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(result);
+ delete[] additionals;
+ return nullptr;
+ }
+
+ delete[] additionals;
+
+ return result;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setMaxBytesForLevelMultiplierAdditional
+ * Signature: (J[I)V
+ */
+void Java_org_rocksdb_Options_setMaxBytesForLevelMultiplierAdditional(
+ JNIEnv* env, jobject, jlong jhandle,
+ jintArray jmax_bytes_for_level_multiplier_additional) {
+ jsize len = env->GetArrayLength(jmax_bytes_for_level_multiplier_additional);
+ jint* additionals = env->GetIntArrayElements(
+ jmax_bytes_for_level_multiplier_additional, nullptr);
+ if (additionals == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opt->max_bytes_for_level_multiplier_additional.clear();
+ for (jsize i = 0; i < len; i++) {
+ opt->max_bytes_for_level_multiplier_additional.push_back(
+ static_cast<int32_t>(additionals[i]));
+ }
+
+ env->ReleaseIntArrayElements(jmax_bytes_for_level_multiplier_additional,
+ additionals, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: paranoidFileChecks
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_paranoidFileChecks(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::Options*>(jhandle)->paranoid_file_checks;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setParanoidFileChecks
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setParanoidFileChecks(
+ JNIEnv*, jobject, jlong jhandle, jboolean jparanoid_file_checks) {
+ reinterpret_cast<rocksdb::Options*>(jhandle)->paranoid_file_checks =
+ static_cast<bool>(jparanoid_file_checks);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionPriority
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Options_setCompactionPriority(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompaction_priority_value) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opts->compaction_pri =
+ rocksdb::CompactionPriorityJni::toCppCompactionPriority(
+ jcompaction_priority_value);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: compactionPriority
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Options_compactionPriority(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return rocksdb::CompactionPriorityJni::toJavaCompactionPriority(
+ opts->compaction_pri);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setReportBgIoStats
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setReportBgIoStats(
+ JNIEnv*, jobject, jlong jhandle, jboolean jreport_bg_io_stats) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opts->report_bg_io_stats = static_cast<bool>(jreport_bg_io_stats);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: reportBgIoStats
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_reportBgIoStats(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<bool>(opts->report_bg_io_stats);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setTtl
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setTtl(
+ JNIEnv*, jobject, jlong jhandle, jlong jttl) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opts->ttl = static_cast<uint64_t>(jttl);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: ttl
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Options_ttl(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<jlong>(opts->ttl);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionOptionsUniversal
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setCompactionOptionsUniversal(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jcompaction_options_universal_handle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* opts_uni = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(
+ jcompaction_options_universal_handle);
+ opts->compaction_options_universal = *opts_uni;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setCompactionOptionsFIFO
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Options_setCompactionOptionsFIFO(
+ JNIEnv*, jobject, jlong jhandle, jlong jcompaction_options_fifo_handle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ auto* opts_fifo = reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(
+ jcompaction_options_fifo_handle);
+ opts->compaction_options_fifo = *opts_fifo;
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: setForceConsistencyChecks
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_Options_setForceConsistencyChecks(
+ JNIEnv*, jobject, jlong jhandle, jboolean jforce_consistency_checks) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ opts->force_consistency_checks = static_cast<bool>(jforce_consistency_checks);
+}
+
+/*
+ * Class: org_rocksdb_Options
+ * Method: forceConsistencyChecks
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Options_forceConsistencyChecks(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::Options*>(jhandle);
+ return static_cast<bool>(opts->force_consistency_checks);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::ColumnFamilyOptions
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: newColumnFamilyOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptions(
+ JNIEnv*, jclass) {
+ auto* op = new rocksdb::ColumnFamilyOptions();
+ return reinterpret_cast<jlong>(op);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: copyColumnFamilyOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_copyColumnFamilyOptions(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto new_opt = new rocksdb::ColumnFamilyOptions(
+ *(reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: newColumnFamilyOptionsFromOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_newColumnFamilyOptionsFromOptions(
+ JNIEnv*, jclass, jlong joptions_handle) {
+ auto new_opt = new rocksdb::ColumnFamilyOptions(
+ *reinterpret_cast<rocksdb::Options*>(joptions_handle));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: getColumnFamilyOptionsFromProps
+ * Signature: (Ljava/util/String;)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_getColumnFamilyOptionsFromProps(
+ JNIEnv* env, jclass, jstring jopt_string) {
+ const char* opt_string = env->GetStringUTFChars(jopt_string, nullptr);
+ if (opt_string == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ auto* cf_options = new rocksdb::ColumnFamilyOptions();
+ rocksdb::Status status = rocksdb::GetColumnFamilyOptionsFromString(
+ rocksdb::ColumnFamilyOptions(), opt_string, cf_options);
+
+ env->ReleaseStringUTFChars(jopt_string, opt_string);
+
+ // Check if ColumnFamilyOptions creation was possible.
+ jlong ret_value = 0;
+ if (status.ok()) {
+ ret_value = reinterpret_cast<jlong>(cf_options);
+ } else {
+ // if operation failed the ColumnFamilyOptions need to be deleted
+ // again to prevent a memory leak.
+ delete cf_options;
+ }
+ return ret_value;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_disposeInternal(
+ JNIEnv*, jobject, jlong handle) {
+ auto* cfo = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(handle);
+ assert(cfo != nullptr);
+ delete cfo;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: optimizeForSmallDb
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_optimizeForSmallDb(
+ JNIEnv*, jobject, jlong jhandle) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->OptimizeForSmallDb();
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: optimizeForPointLookup
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_optimizeForPointLookup(
+ JNIEnv*, jobject, jlong jhandle, jlong block_cache_size_mb) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->OptimizeForPointLookup(block_cache_size_mb);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: optimizeLevelStyleCompaction
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_optimizeLevelStyleCompaction(
+ JNIEnv*, jobject, jlong jhandle, jlong memtable_memory_budget) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->OptimizeLevelStyleCompaction(memtable_memory_budget);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: optimizeUniversalStyleCompaction
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_optimizeUniversalStyleCompaction(
+ JNIEnv*, jobject, jlong jhandle, jlong memtable_memory_budget) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->OptimizeUniversalStyleCompaction(memtable_memory_budget);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setComparatorHandle
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setComparatorHandle__JI(
+ JNIEnv*, jobject, jlong jhandle, jint builtinComparator) {
+ switch (builtinComparator) {
+ case 1:
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->comparator =
+ rocksdb::ReverseBytewiseComparator();
+ break;
+ default:
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->comparator =
+ rocksdb::BytewiseComparator();
+ break;
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setComparatorHandle
+ * Signature: (JJB)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setComparatorHandle__JJB(
+ JNIEnv*, jobject, jlong jopt_handle, jlong jcomparator_handle,
+ jbyte jcomparator_type) {
+ rocksdb::Comparator* comparator = nullptr;
+ switch (jcomparator_type) {
+ // JAVA_COMPARATOR
+ case 0x0:
+ comparator =
+ reinterpret_cast<rocksdb::ComparatorJniCallback*>(jcomparator_handle);
+ break;
+
+ // JAVA_DIRECT_COMPARATOR
+ case 0x1:
+ comparator = reinterpret_cast<rocksdb::DirectComparatorJniCallback*>(
+ jcomparator_handle);
+ break;
+
+ // JAVA_NATIVE_COMPARATOR_WRAPPER
+ case 0x2:
+ comparator = reinterpret_cast<rocksdb::Comparator*>(jcomparator_handle);
+ break;
+ }
+ auto* opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jopt_handle);
+ opt->comparator = comparator;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMergeOperatorName
+ * Signature: (JJjava/lang/String)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMergeOperatorName(
+ JNIEnv* env, jobject, jlong jhandle, jstring jop_name) {
+ auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ const char* op_name = env->GetStringUTFChars(jop_name, nullptr);
+ if (op_name == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ options->merge_operator =
+ rocksdb::MergeOperators::CreateFromStringId(op_name);
+ env->ReleaseStringUTFChars(jop_name, op_name);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMergeOperator
+ * Signature: (JJjava/lang/String)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMergeOperator(
+ JNIEnv*, jobject, jlong jhandle, jlong mergeOperatorHandle) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->merge_operator =
+ *(reinterpret_cast<std::shared_ptr<rocksdb::MergeOperator>*>(
+ mergeOperatorHandle));
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompactionFilterHandle
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompactionFilterHandle(
+ JNIEnv*, jobject, jlong jopt_handle, jlong jcompactionfilter_handle) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jopt_handle)
+ ->compaction_filter =
+ reinterpret_cast<rocksdb::CompactionFilter*>(jcompactionfilter_handle);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompactionFilterFactoryHandle
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompactionFilterFactoryHandle(
+ JNIEnv*, jobject, jlong jopt_handle,
+ jlong jcompactionfilterfactory_handle) {
+ auto* cff_factory =
+ reinterpret_cast<std::shared_ptr<rocksdb::CompactionFilterFactoryJniCallback>*>(
+ jcompactionfilterfactory_handle);
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jopt_handle)
+ ->compaction_filter_factory = *cff_factory;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setWriteBufferSize
+ * Signature: (JJ)I
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setWriteBufferSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong jwrite_buffer_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(jwrite_buffer_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->write_buffer_size = jwrite_buffer_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: writeBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_writeBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->write_buffer_size;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxWriteBufferNumber
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxWriteBufferNumber(
+ JNIEnv*, jobject, jlong jhandle, jint jmax_write_buffer_number) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_write_buffer_number = jmax_write_buffer_number;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxWriteBufferNumber
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_maxWriteBufferNumber(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_write_buffer_number;
+}
+
+/*
+ * Method: setMemTableFactory
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMemTableFactory(
+ JNIEnv*, jobject, jlong jhandle, jlong jfactory_handle) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->memtable_factory.reset(
+ reinterpret_cast<rocksdb::MemTableRepFactory*>(jfactory_handle));
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: memTableFactoryName
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_ColumnFamilyOptions_memTableFactoryName(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ rocksdb::MemTableRepFactory* tf = opt->memtable_factory.get();
+
+ // Should never be nullptr.
+ // Default memtable factory is SkipListFactory
+ assert(tf);
+
+ // temporarly fix for the historical typo
+ if (strcmp(tf->Name(), "HashLinkListRepFactory") == 0) {
+ return env->NewStringUTF("HashLinkedListRepFactory");
+ }
+
+ return env->NewStringUTF(tf->Name());
+}
+
+/*
+ * Method: useFixedLengthPrefixExtractor
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_useFixedLengthPrefixExtractor(
+ JNIEnv*, jobject, jlong jhandle, jint jprefix_length) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->prefix_extractor.reset(
+ rocksdb::NewFixedPrefixTransform(static_cast<int>(jprefix_length)));
+}
+
+/*
+ * Method: useCappedPrefixExtractor
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_useCappedPrefixExtractor(
+ JNIEnv*, jobject, jlong jhandle, jint jprefix_length) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->prefix_extractor.reset(
+ rocksdb::NewCappedPrefixTransform(static_cast<int>(jprefix_length)));
+}
+
+/*
+ * Method: setTableFactory
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setTableFactory(
+ JNIEnv*, jobject, jlong jhandle, jlong jfactory_handle) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->table_factory.reset(
+ reinterpret_cast<rocksdb::TableFactory*>(jfactory_handle));
+}
+
+/*
+ * Method: tableFactoryName
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_ColumnFamilyOptions_tableFactoryName(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ rocksdb::TableFactory* tf = opt->table_factory.get();
+
+ // Should never be nullptr.
+ // Default memtable factory is SkipListFactory
+ assert(tf);
+
+ return env->NewStringUTF(tf->Name());
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: minWriteBufferNumberToMerge
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_minWriteBufferNumberToMerge(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->min_write_buffer_number_to_merge;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMinWriteBufferNumberToMerge
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMinWriteBufferNumberToMerge(
+ JNIEnv*, jobject, jlong jhandle, jint jmin_write_buffer_number_to_merge) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->min_write_buffer_number_to_merge =
+ static_cast<int>(jmin_write_buffer_number_to_merge);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxWriteBufferNumberToMaintain
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_maxWriteBufferNumberToMaintain(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_write_buffer_number_to_maintain;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxWriteBufferNumberToMaintain
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxWriteBufferNumberToMaintain(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jmax_write_buffer_number_to_maintain) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_write_buffer_number_to_maintain =
+ static_cast<int>(jmax_write_buffer_number_to_maintain);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompressionType
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompressionType(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompression_type_value) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_opts->compression = rocksdb::CompressionTypeJni::toCppCompressionType(
+ jcompression_type_value);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: compressionType
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_ColumnFamilyOptions_compressionType(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return rocksdb::CompressionTypeJni::toJavaCompressionType(
+ cf_opts->compression);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompressionPerLevel
+ * Signature: (J[B)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompressionPerLevel(
+ JNIEnv* env, jobject, jlong jhandle, jbyteArray jcompressionLevels) {
+ auto* options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ auto uptr_compression_levels =
+ rocksdb_compression_vector_helper(env, jcompressionLevels);
+ if (!uptr_compression_levels) {
+ // exception occurred
+ return;
+ }
+ options->compression_per_level = *(uptr_compression_levels.get());
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: compressionPerLevel
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_ColumnFamilyOptions_compressionPerLevel(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return rocksdb_compression_list_helper(env,
+ cf_options->compression_per_level);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setBottommostCompressionType
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setBottommostCompressionType(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompression_type_value) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_options->bottommost_compression =
+ rocksdb::CompressionTypeJni::toCppCompressionType(
+ jcompression_type_value);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: bottommostCompressionType
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_ColumnFamilyOptions_bottommostCompressionType(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return rocksdb::CompressionTypeJni::toJavaCompressionType(
+ cf_options->bottommost_compression);
+}
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setBottommostCompressionOptions
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setBottommostCompressionOptions(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jbottommost_compression_options_handle) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ auto* bottommost_compression_options =
+ reinterpret_cast<rocksdb::CompressionOptions*>(
+ jbottommost_compression_options_handle);
+ cf_options->bottommost_compression_opts = *bottommost_compression_options;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompressionOptions
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompressionOptions(
+ JNIEnv*, jobject, jlong jhandle, jlong jcompression_options_handle) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ auto* compression_options = reinterpret_cast<rocksdb::CompressionOptions*>(
+ jcompression_options_handle);
+ cf_options->compression_opts = *compression_options;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompactionStyle
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompactionStyle(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompaction_style) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_options->compaction_style =
+ rocksdb::CompactionStyleJni::toCppCompactionStyle(jcompaction_style);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: compactionStyle
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_ColumnFamilyOptions_compactionStyle(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return rocksdb::CompactionStyleJni::toJavaCompactionStyle(
+ cf_options->compaction_style);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxTableFilesSizeFIFO
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxTableFilesSizeFIFO(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_table_files_size) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->compaction_options_fifo.max_table_files_size =
+ static_cast<uint64_t>(jmax_table_files_size);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxTableFilesSizeFIFO
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_maxTableFilesSizeFIFO(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->compaction_options_fifo.max_table_files_size;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: numLevels
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_numLevels(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->num_levels;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setNumLevels
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setNumLevels(
+ JNIEnv*, jobject, jlong jhandle, jint jnum_levels) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->num_levels =
+ static_cast<int>(jnum_levels);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: levelZeroFileNumCompactionTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_levelZeroFileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_file_num_compaction_trigger;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevelZeroFileNumCompactionTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevelZeroFileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jlevel0_file_num_compaction_trigger) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_file_num_compaction_trigger =
+ static_cast<int>(jlevel0_file_num_compaction_trigger);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: levelZeroSlowdownWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_levelZeroSlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_slowdown_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevelSlowdownWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevelZeroSlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_slowdown_writes_trigger) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_slowdown_writes_trigger =
+ static_cast<int>(jlevel0_slowdown_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: levelZeroStopWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_levelZeroStopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_stop_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevelStopWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevelZeroStopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_stop_writes_trigger) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_stop_writes_trigger =
+ static_cast<int>(jlevel0_stop_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: targetFileSizeBase
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_targetFileSizeBase(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->target_file_size_base;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setTargetFileSizeBase
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setTargetFileSizeBase(
+ JNIEnv*, jobject, jlong jhandle, jlong jtarget_file_size_base) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->target_file_size_base = static_cast<uint64_t>(jtarget_file_size_base);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: targetFileSizeMultiplier
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_targetFileSizeMultiplier(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->target_file_size_multiplier;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setTargetFileSizeMultiplier
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setTargetFileSizeMultiplier(
+ JNIEnv*, jobject, jlong jhandle, jint jtarget_file_size_multiplier) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->target_file_size_multiplier =
+ static_cast<int>(jtarget_file_size_multiplier);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxBytesForLevelBase
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_maxBytesForLevelBase(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_bytes_for_level_base;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxBytesForLevelBase
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxBytesForLevelBase(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_bytes_for_level_base) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_bytes_for_level_base =
+ static_cast<int64_t>(jmax_bytes_for_level_base);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: levelCompactionDynamicLevelBytes
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_levelCompactionDynamicLevelBytes(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level_compaction_dynamic_level_bytes;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevelCompactionDynamicLevelBytes
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevelCompactionDynamicLevelBytes(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenable_dynamic_level_bytes) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level_compaction_dynamic_level_bytes = (jenable_dynamic_level_bytes);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxBytesForLevelMultiplier
+ * Signature: (J)D
+ */
+jdouble Java_org_rocksdb_ColumnFamilyOptions_maxBytesForLevelMultiplier(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_bytes_for_level_multiplier;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxBytesForLevelMultiplier
+ * Signature: (JD)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxBytesForLevelMultiplier(
+ JNIEnv*, jobject, jlong jhandle, jdouble jmax_bytes_for_level_multiplier) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_bytes_for_level_multiplier =
+ static_cast<double>(jmax_bytes_for_level_multiplier);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxCompactionBytes
+ * Signature: (J)I
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_maxCompactionBytes(
+ JNIEnv*, jobject, jlong jhandle) {
+ return static_cast<jlong>(
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_compaction_bytes);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxCompactionBytes
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxCompactionBytes(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_compaction_bytes) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_compaction_bytes = static_cast<uint64_t>(jmax_compaction_bytes);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: arenaBlockSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_arenaBlockSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->arena_block_size;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setArenaBlockSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setArenaBlockSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong jarena_block_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(jarena_block_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->arena_block_size =
+ jarena_block_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: disableAutoCompactions
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_disableAutoCompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->disable_auto_compactions;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setDisableAutoCompactions
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setDisableAutoCompactions(
+ JNIEnv*, jobject, jlong jhandle, jboolean jdisable_auto_compactions) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->disable_auto_compactions = static_cast<bool>(jdisable_auto_compactions);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxSequentialSkipInIterations
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_maxSequentialSkipInIterations(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_sequential_skip_in_iterations;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxSequentialSkipInIterations
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxSequentialSkipInIterations(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jmax_sequential_skip_in_iterations) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_sequential_skip_in_iterations =
+ static_cast<int64_t>(jmax_sequential_skip_in_iterations);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: inplaceUpdateSupport
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_inplaceUpdateSupport(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->inplace_update_support;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setInplaceUpdateSupport
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setInplaceUpdateSupport(
+ JNIEnv*, jobject, jlong jhandle, jboolean jinplace_update_support) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->inplace_update_support = static_cast<bool>(jinplace_update_support);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: inplaceUpdateNumLocks
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_inplaceUpdateNumLocks(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->inplace_update_num_locks;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setInplaceUpdateNumLocks
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setInplaceUpdateNumLocks(
+ JNIEnv* env, jobject, jlong jhandle, jlong jinplace_update_num_locks) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jinplace_update_num_locks);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->inplace_update_num_locks = jinplace_update_num_locks;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: memtablePrefixBloomSizeRatio
+ * Signature: (J)I
+ */
+jdouble Java_org_rocksdb_ColumnFamilyOptions_memtablePrefixBloomSizeRatio(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->memtable_prefix_bloom_size_ratio;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMemtablePrefixBloomSizeRatio
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMemtablePrefixBloomSizeRatio(
+ JNIEnv*, jobject, jlong jhandle,
+ jdouble jmemtable_prefix_bloom_size_ratio) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->memtable_prefix_bloom_size_ratio =
+ static_cast<double>(jmemtable_prefix_bloom_size_ratio);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: bloomLocality
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_bloomLocality(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->bloom_locality;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setBloomLocality
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setBloomLocality(
+ JNIEnv*, jobject, jlong jhandle, jint jbloom_locality) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)->bloom_locality =
+ static_cast<int32_t>(jbloom_locality);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxSuccessiveMerges
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_maxSuccessiveMerges(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_successive_merges;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxSuccessiveMerges
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxSuccessiveMerges(
+ JNIEnv* env, jobject, jlong jhandle, jlong jmax_successive_merges) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jmax_successive_merges);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_successive_merges = jmax_successive_merges;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: optimizeFiltersForHits
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_optimizeFiltersForHits(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->optimize_filters_for_hits;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setOptimizeFiltersForHits
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setOptimizeFiltersForHits(
+ JNIEnv*, jobject, jlong jhandle, jboolean joptimize_filters_for_hits) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->optimize_filters_for_hits =
+ static_cast<bool>(joptimize_filters_for_hits);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: memtableHugePageSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_memtableHugePageSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->memtable_huge_page_size;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMemtableHugePageSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMemtableHugePageSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong jmemtable_huge_page_size) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(jmemtable_huge_page_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->memtable_huge_page_size = jmemtable_huge_page_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: softPendingCompactionBytesLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_softPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->soft_pending_compaction_bytes_limit;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setSoftPendingCompactionBytesLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setSoftPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jsoft_pending_compaction_bytes_limit) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->soft_pending_compaction_bytes_limit =
+ static_cast<int64_t>(jsoft_pending_compaction_bytes_limit);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: softHardCompactionBytesLimit
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ColumnFamilyOptions_hardPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->hard_pending_compaction_bytes_limit;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setHardPendingCompactionBytesLimit
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setHardPendingCompactionBytesLimit(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jhard_pending_compaction_bytes_limit) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->hard_pending_compaction_bytes_limit =
+ static_cast<int64_t>(jhard_pending_compaction_bytes_limit);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: level0FileNumCompactionTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_level0FileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_file_num_compaction_trigger;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevel0FileNumCompactionTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevel0FileNumCompactionTrigger(
+ JNIEnv*, jobject, jlong jhandle,
+ jint jlevel0_file_num_compaction_trigger) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_file_num_compaction_trigger =
+ static_cast<int32_t>(jlevel0_file_num_compaction_trigger);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: level0SlowdownWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_level0SlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_slowdown_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevel0SlowdownWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevel0SlowdownWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_slowdown_writes_trigger) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_slowdown_writes_trigger =
+ static_cast<int32_t>(jlevel0_slowdown_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: level0StopWritesTrigger
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_ColumnFamilyOptions_level0StopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_stop_writes_trigger;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setLevel0StopWritesTrigger
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setLevel0StopWritesTrigger(
+ JNIEnv*, jobject, jlong jhandle, jint jlevel0_stop_writes_trigger) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->level0_stop_writes_trigger =
+ static_cast<int32_t>(jlevel0_stop_writes_trigger);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: maxBytesForLevelMultiplierAdditional
+ * Signature: (J)[I
+ */
+jintArray Java_org_rocksdb_ColumnFamilyOptions_maxBytesForLevelMultiplierAdditional(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto mbflma = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->max_bytes_for_level_multiplier_additional;
+
+ const size_t size = mbflma.size();
+
+ jint* additionals = new jint[size];
+ for (size_t i = 0; i < size; i++) {
+ additionals[i] = static_cast<jint>(mbflma[i]);
+ }
+
+ jsize jlen = static_cast<jsize>(size);
+ jintArray result = env->NewIntArray(jlen);
+ if (result == nullptr) {
+ // exception thrown: OutOfMemoryError
+ delete[] additionals;
+ return nullptr;
+ }
+ env->SetIntArrayRegion(result, 0, jlen, additionals);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(result);
+ delete[] additionals;
+ return nullptr;
+ }
+
+ delete[] additionals;
+
+ return result;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setMaxBytesForLevelMultiplierAdditional
+ * Signature: (J[I)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setMaxBytesForLevelMultiplierAdditional(
+ JNIEnv* env, jobject, jlong jhandle,
+ jintArray jmax_bytes_for_level_multiplier_additional) {
+ jsize len = env->GetArrayLength(jmax_bytes_for_level_multiplier_additional);
+ jint* additionals =
+ env->GetIntArrayElements(jmax_bytes_for_level_multiplier_additional, 0);
+ if (additionals == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* cf_opt = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_opt->max_bytes_for_level_multiplier_additional.clear();
+ for (jsize i = 0; i < len; i++) {
+ cf_opt->max_bytes_for_level_multiplier_additional.push_back(
+ static_cast<int32_t>(additionals[i]));
+ }
+
+ env->ReleaseIntArrayElements(jmax_bytes_for_level_multiplier_additional,
+ additionals, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: paranoidFileChecks
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_paranoidFileChecks(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->paranoid_file_checks;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setParanoidFileChecks
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setParanoidFileChecks(
+ JNIEnv*, jobject, jlong jhandle, jboolean jparanoid_file_checks) {
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle)
+ ->paranoid_file_checks = static_cast<bool>(jparanoid_file_checks);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompactionPriority
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompactionPriority(
+ JNIEnv*, jobject, jlong jhandle, jbyte jcompaction_priority_value) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_opts->compaction_pri =
+ rocksdb::CompactionPriorityJni::toCppCompactionPriority(
+ jcompaction_priority_value);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: compactionPriority
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_ColumnFamilyOptions_compactionPriority(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return rocksdb::CompactionPriorityJni::toJavaCompactionPriority(
+ cf_opts->compaction_pri);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setReportBgIoStats
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setReportBgIoStats(
+ JNIEnv*, jobject, jlong jhandle, jboolean jreport_bg_io_stats) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_opts->report_bg_io_stats = static_cast<bool>(jreport_bg_io_stats);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: reportBgIoStats
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_reportBgIoStats(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return static_cast<bool>(cf_opts->report_bg_io_stats);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setTtl
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setTtl(
+ JNIEnv*, jobject, jlong jhandle, jlong jttl) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_opts->ttl = static_cast<uint64_t>(jttl);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: ttl
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_org_rocksdb_ColumnFamilyOptions_ttl(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return static_cast<jlong>(cf_opts->ttl);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompactionOptionsUniversal
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompactionOptionsUniversal(
+ JNIEnv*, jobject, jlong jhandle,
+ jlong jcompaction_options_universal_handle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ auto* opts_uni = reinterpret_cast<rocksdb::CompactionOptionsUniversal*>(
+ jcompaction_options_universal_handle);
+ cf_opts->compaction_options_universal = *opts_uni;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setCompactionOptionsFIFO
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setCompactionOptionsFIFO(
+ JNIEnv*, jobject, jlong jhandle, jlong jcompaction_options_fifo_handle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ auto* opts_fifo = reinterpret_cast<rocksdb::CompactionOptionsFIFO*>(
+ jcompaction_options_fifo_handle);
+ cf_opts->compaction_options_fifo = *opts_fifo;
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: setForceConsistencyChecks
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ColumnFamilyOptions_setForceConsistencyChecks(
+ JNIEnv*, jobject, jlong jhandle, jboolean jforce_consistency_checks) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ cf_opts->force_consistency_checks =
+ static_cast<bool>(jforce_consistency_checks);
+}
+
+/*
+ * Class: org_rocksdb_ColumnFamilyOptions
+ * Method: forceConsistencyChecks
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ColumnFamilyOptions_forceConsistencyChecks(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cf_opts = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jhandle);
+ return static_cast<bool>(cf_opts->force_consistency_checks);
+}
+
+/////////////////////////////////////////////////////////////////////
+// rocksdb::DBOptions
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: newDBOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_DBOptions_newDBOptions(
+ JNIEnv*, jclass) {
+ auto* dbop = new rocksdb::DBOptions();
+ return reinterpret_cast<jlong>(dbop);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: copyDBOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_copyDBOptions(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto new_opt =
+ new rocksdb::DBOptions(*(reinterpret_cast<rocksdb::DBOptions*>(jhandle)));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: newDBOptionsFromOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_newDBOptionsFromOptions(
+ JNIEnv*, jclass, jlong joptions_handle) {
+ auto new_opt =
+ new rocksdb::DBOptions(*reinterpret_cast<rocksdb::Options*>(joptions_handle));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: getDBOptionsFromProps
+ * Signature: (Ljava/util/String;)J
+ */
+jlong Java_org_rocksdb_DBOptions_getDBOptionsFromProps(
+ JNIEnv* env, jclass, jstring jopt_string) {
+ const char* opt_string = env->GetStringUTFChars(jopt_string, nullptr);
+ if (opt_string == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ auto* db_options = new rocksdb::DBOptions();
+ rocksdb::Status status = rocksdb::GetDBOptionsFromString(
+ rocksdb::DBOptions(), opt_string, db_options);
+
+ env->ReleaseStringUTFChars(jopt_string, opt_string);
+
+ // Check if DBOptions creation was possible.
+ jlong ret_value = 0;
+ if (status.ok()) {
+ ret_value = reinterpret_cast<jlong>(db_options);
+ } else {
+ // if operation failed the DBOptions need to be deleted
+ // again to prevent a memory leak.
+ delete db_options;
+ }
+ return ret_value;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_DBOptions_disposeInternal(
+ JNIEnv*, jobject, jlong handle) {
+ auto* dbo = reinterpret_cast<rocksdb::DBOptions*>(handle);
+ assert(dbo != nullptr);
+ delete dbo;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: optimizeForSmallDb
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_DBOptions_optimizeForSmallDb(
+ JNIEnv*, jobject, jlong jhandle) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->OptimizeForSmallDb();
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setEnv
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setEnv(
+ JNIEnv*, jobject, jlong jhandle, jlong jenv_handle) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->env =
+ reinterpret_cast<rocksdb::Env*>(jenv_handle);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setIncreaseParallelism
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setIncreaseParallelism(
+ JNIEnv*, jobject, jlong jhandle, jint totalThreads) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->IncreaseParallelism(
+ static_cast<int>(totalThreads));
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setCreateIfMissing
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setCreateIfMissing(
+ JNIEnv*, jobject, jlong jhandle, jboolean flag) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->create_if_missing = flag;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: createIfMissing
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_createIfMissing(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->create_if_missing;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setCreateMissingColumnFamilies
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setCreateMissingColumnFamilies(
+ JNIEnv*, jobject, jlong jhandle, jboolean flag) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->create_missing_column_families = flag;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: createMissingColumnFamilies
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_createMissingColumnFamilies(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->create_missing_column_families;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setErrorIfExists
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setErrorIfExists(
+ JNIEnv*, jobject, jlong jhandle, jboolean error_if_exists) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->error_if_exists =
+ static_cast<bool>(error_if_exists);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: errorIfExists
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_errorIfExists(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->error_if_exists;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setParanoidChecks
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setParanoidChecks(
+ JNIEnv*, jobject, jlong jhandle, jboolean paranoid_checks) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->paranoid_checks =
+ static_cast<bool>(paranoid_checks);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: paranoidChecks
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_paranoidChecks(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->paranoid_checks;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setRateLimiter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setRateLimiter(
+ JNIEnv*, jobject, jlong jhandle, jlong jrate_limiter_handle) {
+ std::shared_ptr<rocksdb::RateLimiter>* pRateLimiter =
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(
+ jrate_limiter_handle);
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->rate_limiter = *pRateLimiter;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setSstFileManager
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setSstFileManager(
+ JNIEnv*, jobject, jlong jhandle, jlong jsst_file_manager_handle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(
+ jsst_file_manager_handle);
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->sst_file_manager =
+ *sptr_sst_file_manager;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setLogger
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setLogger(
+ JNIEnv*, jobject, jlong jhandle, jlong jlogger_handle) {
+ std::shared_ptr<rocksdb::LoggerJniCallback>* pLogger =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(
+ jlogger_handle);
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->info_log = *pLogger;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setInfoLogLevel
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_DBOptions_setInfoLogLevel(
+ JNIEnv*, jobject, jlong jhandle, jbyte jlog_level) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->info_log_level =
+ static_cast<rocksdb::InfoLogLevel>(jlog_level);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: infoLogLevel
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_DBOptions_infoLogLevel(
+ JNIEnv*, jobject, jlong jhandle) {
+ return static_cast<jbyte>(
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->info_log_level);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxTotalWalSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxTotalWalSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_total_wal_size) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_total_wal_size =
+ static_cast<jlong>(jmax_total_wal_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxTotalWalSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_maxTotalWalSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_total_wal_size;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxOpenFiles
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxOpenFiles(
+ JNIEnv*, jobject, jlong jhandle, jint max_open_files) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_open_files =
+ static_cast<int>(max_open_files);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxOpenFiles
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_maxOpenFiles(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_open_files;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxFileOpeningThreads
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxFileOpeningThreads(
+ JNIEnv*, jobject, jlong jhandle, jint jmax_file_opening_threads) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_file_opening_threads =
+ static_cast<int>(jmax_file_opening_threads);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxFileOpeningThreads
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_maxFileOpeningThreads(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<int>(opt->max_file_opening_threads);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setStatistics
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setStatistics(
+ JNIEnv*, jobject, jlong jhandle, jlong jstatistics_handle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ auto* pSptr = reinterpret_cast<std::shared_ptr<rocksdb::StatisticsJni>*>(
+ jstatistics_handle);
+ opt->statistics = *pSptr;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: statistics
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_statistics(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ std::shared_ptr<rocksdb::Statistics> sptr = opt->statistics;
+ if (sptr == nullptr) {
+ return 0;
+ } else {
+ std::shared_ptr<rocksdb::Statistics>* pSptr =
+ new std::shared_ptr<rocksdb::Statistics>(sptr);
+ return reinterpret_cast<jlong>(pSptr);
+ }
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setUseFsync
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setUseFsync(
+ JNIEnv*, jobject, jlong jhandle, jboolean use_fsync) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->use_fsync =
+ static_cast<bool>(use_fsync);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: useFsync
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_useFsync(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->use_fsync;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setDbPaths
+ * Signature: (J[Ljava/lang/String;[J)V
+ */
+void Java_org_rocksdb_DBOptions_setDbPaths(
+ JNIEnv* env, jobject, jlong jhandle, jobjectArray jpaths,
+ jlongArray jtarget_sizes) {
+ std::vector<rocksdb::DbPath> db_paths;
+ jlong* ptr_jtarget_size = env->GetLongArrayElements(jtarget_sizes, nullptr);
+ if (ptr_jtarget_size == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ jboolean has_exception = JNI_FALSE;
+ const jsize len = env->GetArrayLength(jpaths);
+ for (jsize i = 0; i < len; i++) {
+ jobject jpath =
+ reinterpret_cast<jstring>(env->GetObjectArrayElement(jpaths, i));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+ std::string path = rocksdb::JniUtil::copyStdString(
+ env, static_cast<jstring>(jpath), &has_exception);
+ env->DeleteLocalRef(jpath);
+
+ if (has_exception == JNI_TRUE) {
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+
+ jlong jtarget_size = ptr_jtarget_size[i];
+
+ db_paths.push_back(
+ rocksdb::DbPath(path, static_cast<uint64_t>(jtarget_size)));
+ }
+
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->db_paths = db_paths;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: dbPathsLen
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_dbPathsLen(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->db_paths.size());
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: dbPaths
+ * Signature: (J[Ljava/lang/String;[J)V
+ */
+void Java_org_rocksdb_DBOptions_dbPaths(
+ JNIEnv* env, jobject, jlong jhandle, jobjectArray jpaths,
+ jlongArray jtarget_sizes) {
+ jlong* ptr_jtarget_size = env->GetLongArrayElements(jtarget_sizes, nullptr);
+ if (ptr_jtarget_size == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ const jsize len = env->GetArrayLength(jpaths);
+ for (jsize i = 0; i < len; i++) {
+ rocksdb::DbPath db_path = opt->db_paths[i];
+
+ jstring jpath = env->NewStringUTF(db_path.path.c_str());
+ if (jpath == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+ env->SetObjectArrayElement(jpaths, i, jpath);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jpath);
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_ABORT);
+ return;
+ }
+
+ ptr_jtarget_size[i] = static_cast<jint>(db_path.target_size);
+ }
+
+ env->ReleaseLongArrayElements(jtarget_sizes, ptr_jtarget_size, JNI_COMMIT);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setDbLogDir
+ * Signature: (JLjava/lang/String)V
+ */
+void Java_org_rocksdb_DBOptions_setDbLogDir(
+ JNIEnv* env, jobject, jlong jhandle, jstring jdb_log_dir) {
+ const char* log_dir = env->GetStringUTFChars(jdb_log_dir, nullptr);
+ if (log_dir == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->db_log_dir.assign(log_dir);
+ env->ReleaseStringUTFChars(jdb_log_dir, log_dir);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: dbLogDir
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_DBOptions_dbLogDir(
+ JNIEnv* env, jobject, jlong jhandle) {
+ return env->NewStringUTF(
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->db_log_dir.c_str());
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWalDir
+ * Signature: (JLjava/lang/String)V
+ */
+void Java_org_rocksdb_DBOptions_setWalDir(
+ JNIEnv* env, jobject, jlong jhandle, jstring jwal_dir) {
+ const char* wal_dir = env->GetStringUTFChars(jwal_dir, 0);
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->wal_dir.assign(wal_dir);
+ env->ReleaseStringUTFChars(jwal_dir, wal_dir);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: walDir
+ * Signature: (J)Ljava/lang/String
+ */
+jstring Java_org_rocksdb_DBOptions_walDir(
+ JNIEnv* env, jobject, jlong jhandle) {
+ return env->NewStringUTF(
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->wal_dir.c_str());
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setDeleteObsoleteFilesPeriodMicros
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setDeleteObsoleteFilesPeriodMicros(
+ JNIEnv*, jobject, jlong jhandle, jlong micros) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->delete_obsolete_files_period_micros = static_cast<int64_t>(micros);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: deleteObsoleteFilesPeriodMicros
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_deleteObsoleteFilesPeriodMicros(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->delete_obsolete_files_period_micros;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setBaseBackgroundCompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setBaseBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle, jint max) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->base_background_compactions =
+ static_cast<int>(max);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: baseBackgroundCompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_baseBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->base_background_compactions;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxBackgroundCompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle, jint max) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_background_compactions =
+ static_cast<int>(max);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxBackgroundCompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_maxBackgroundCompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->max_background_compactions;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxSubcompactions
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxSubcompactions(
+ JNIEnv*, jobject, jlong jhandle, jint max) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_subcompactions =
+ static_cast<int32_t>(max);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxSubcompactions
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_maxSubcompactions(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_subcompactions;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxBackgroundFlushes
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxBackgroundFlushes(
+ JNIEnv*, jobject, jlong jhandle, jint max_background_flushes) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_background_flushes =
+ static_cast<int>(max_background_flushes);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxBackgroundFlushes
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_maxBackgroundFlushes(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_background_flushes;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxBackgroundJobs
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxBackgroundJobs(
+ JNIEnv*, jobject, jlong jhandle, jint max_background_jobs) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_background_jobs =
+ static_cast<int>(max_background_jobs);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxBackgroundJobs
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_maxBackgroundJobs(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_background_jobs;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxLogFileSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxLogFileSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong max_log_file_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(max_log_file_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_log_file_size =
+ max_log_file_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxLogFileSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_maxLogFileSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_log_file_size;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setLogFileTimeToRoll
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setLogFileTimeToRoll(
+ JNIEnv* env, jobject, jlong jhandle, jlong log_file_time_to_roll) {
+ auto s =
+ rocksdb::JniUtil::check_if_jlong_fits_size_t(log_file_time_to_roll);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->log_file_time_to_roll =
+ log_file_time_to_roll;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: logFileTimeToRoll
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_logFileTimeToRoll(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->log_file_time_to_roll;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setKeepLogFileNum
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setKeepLogFileNum(
+ JNIEnv* env, jobject, jlong jhandle, jlong keep_log_file_num) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(keep_log_file_num);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->keep_log_file_num =
+ keep_log_file_num;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: keepLogFileNum
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_keepLogFileNum(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->keep_log_file_num;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setRecycleLogFileNum
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setRecycleLogFileNum(
+ JNIEnv* env, jobject, jlong jhandle, jlong recycle_log_file_num) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(recycle_log_file_num);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->recycle_log_file_num =
+ recycle_log_file_num;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: recycleLogFileNum
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_recycleLogFileNum(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->recycle_log_file_num;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setMaxManifestFileSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setMaxManifestFileSize(
+ JNIEnv*, jobject, jlong jhandle, jlong max_manifest_file_size) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_manifest_file_size =
+ static_cast<int64_t>(max_manifest_file_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: maxManifestFileSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_maxManifestFileSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->max_manifest_file_size;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setTableCacheNumshardbits
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setTableCacheNumshardbits(
+ JNIEnv*, jobject, jlong jhandle, jint table_cache_numshardbits) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->table_cache_numshardbits =
+ static_cast<int>(table_cache_numshardbits);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: tableCacheNumshardbits
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_tableCacheNumshardbits(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->table_cache_numshardbits;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWalTtlSeconds
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWalTtlSeconds(
+ JNIEnv*, jobject, jlong jhandle, jlong WAL_ttl_seconds) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->WAL_ttl_seconds =
+ static_cast<int64_t>(WAL_ttl_seconds);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: walTtlSeconds
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_walTtlSeconds(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->WAL_ttl_seconds;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWalSizeLimitMB
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWalSizeLimitMB(
+ JNIEnv*, jobject, jlong jhandle, jlong WAL_size_limit_MB) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->WAL_size_limit_MB =
+ static_cast<int64_t>(WAL_size_limit_MB);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: walTtlSeconds
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_walSizeLimitMB(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->WAL_size_limit_MB;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setManifestPreallocationSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setManifestPreallocationSize(
+ JNIEnv* env, jobject, jlong jhandle, jlong preallocation_size) {
+ auto s = rocksdb::JniUtil::check_if_jlong_fits_size_t(preallocation_size);
+ if (s.ok()) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->manifest_preallocation_size = preallocation_size;
+ } else {
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: manifestPreallocationSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_manifestPreallocationSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->manifest_preallocation_size;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: useDirectReads
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_useDirectReads(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->use_direct_reads;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setUseDirectReads
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setUseDirectReads(
+ JNIEnv*, jobject, jlong jhandle, jboolean use_direct_reads) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->use_direct_reads =
+ static_cast<bool>(use_direct_reads);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: useDirectIoForFlushAndCompaction
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_useDirectIoForFlushAndCompaction(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->use_direct_io_for_flush_and_compaction;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setUseDirectReads
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setUseDirectIoForFlushAndCompaction(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean use_direct_io_for_flush_and_compaction) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->use_direct_io_for_flush_and_compaction =
+ static_cast<bool>(use_direct_io_for_flush_and_compaction);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAllowFAllocate
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAllowFAllocate(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_fallocate) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->allow_fallocate =
+ static_cast<bool>(jallow_fallocate);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: allowFAllocate
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_allowFAllocate(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->allow_fallocate);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAllowMmapReads
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAllowMmapReads(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow_mmap_reads) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->allow_mmap_reads =
+ static_cast<bool>(allow_mmap_reads);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: allowMmapReads
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_allowMmapReads(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->allow_mmap_reads;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAllowMmapWrites
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAllowMmapWrites(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow_mmap_writes) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->allow_mmap_writes =
+ static_cast<bool>(allow_mmap_writes);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: allowMmapWrites
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_allowMmapWrites(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->allow_mmap_writes;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setIsFdCloseOnExec
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setIsFdCloseOnExec(
+ JNIEnv*, jobject, jlong jhandle, jboolean is_fd_close_on_exec) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->is_fd_close_on_exec =
+ static_cast<bool>(is_fd_close_on_exec);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: isFdCloseOnExec
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_isFdCloseOnExec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->is_fd_close_on_exec;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setStatsDumpPeriodSec
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DBOptions_setStatsDumpPeriodSec(
+ JNIEnv*, jobject, jlong jhandle, jint stats_dump_period_sec) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->stats_dump_period_sec =
+ static_cast<int>(stats_dump_period_sec);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: statsDumpPeriodSec
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_DBOptions_statsDumpPeriodSec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->stats_dump_period_sec;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAdviseRandomOnOpen
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAdviseRandomOnOpen(
+ JNIEnv*, jobject, jlong jhandle, jboolean advise_random_on_open) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->advise_random_on_open =
+ static_cast<bool>(advise_random_on_open);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: adviseRandomOnOpen
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_adviseRandomOnOpen(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->advise_random_on_open;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setDbWriteBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setDbWriteBufferSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jdb_write_buffer_size) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->db_write_buffer_size = static_cast<size_t>(jdb_write_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWriteBufferManager
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWriteBufferManager(
+ JNIEnv*, jobject, jlong jdb_options_handle,
+ jlong jwrite_buffer_manager_handle) {
+ auto* write_buffer_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::WriteBufferManager> *>(jwrite_buffer_manager_handle);
+ reinterpret_cast<rocksdb::DBOptions*>(jdb_options_handle)->write_buffer_manager =
+ *write_buffer_manager;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: dbWriteBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_dbWriteBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->db_write_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAccessHintOnCompactionStart
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_DBOptions_setAccessHintOnCompactionStart(
+ JNIEnv*, jobject, jlong jhandle, jbyte jaccess_hint_value) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->access_hint_on_compaction_start =
+ rocksdb::AccessHintJni::toCppAccessHint(jaccess_hint_value);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: accessHintOnCompactionStart
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_DBOptions_accessHintOnCompactionStart(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return rocksdb::AccessHintJni::toJavaAccessHint(
+ opt->access_hint_on_compaction_start);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setNewTableReaderForCompactionInputs
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setNewTableReaderForCompactionInputs(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean jnew_table_reader_for_compaction_inputs) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->new_table_reader_for_compaction_inputs =
+ static_cast<bool>(jnew_table_reader_for_compaction_inputs);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: newTableReaderForCompactionInputs
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_newTableReaderForCompactionInputs(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<bool>(opt->new_table_reader_for_compaction_inputs);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setCompactionReadaheadSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setCompactionReadaheadSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jcompaction_readahead_size) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->compaction_readahead_size =
+ static_cast<size_t>(jcompaction_readahead_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: compactionReadaheadSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_compactionReadaheadSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->compaction_readahead_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setRandomAccessMaxBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setRandomAccessMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jrandom_access_max_buffer_size) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->random_access_max_buffer_size =
+ static_cast<size_t>(jrandom_access_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: randomAccessMaxBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_randomAccessMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->random_access_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWritableFileMaxBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWritableFileMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jwritable_file_max_buffer_size) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->writable_file_max_buffer_size =
+ static_cast<size_t>(jwritable_file_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: writableFileMaxBufferSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_writableFileMaxBufferSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->writable_file_max_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setUseAdaptiveMutex
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setUseAdaptiveMutex(
+ JNIEnv*, jobject, jlong jhandle, jboolean use_adaptive_mutex) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->use_adaptive_mutex =
+ static_cast<bool>(use_adaptive_mutex);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: useAdaptiveMutex
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_useAdaptiveMutex(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->use_adaptive_mutex;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setBytesPerSync
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setBytesPerSync(
+ JNIEnv*, jobject, jlong jhandle, jlong bytes_per_sync) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->bytes_per_sync =
+ static_cast<int64_t>(bytes_per_sync);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: bytesPerSync
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_bytesPerSync(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)->bytes_per_sync;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWalBytesPerSync
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWalBytesPerSync(
+ JNIEnv*, jobject, jlong jhandle, jlong jwal_bytes_per_sync) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->wal_bytes_per_sync =
+ static_cast<int64_t>(jwal_bytes_per_sync);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: walBytesPerSync
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_walBytesPerSync(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->wal_bytes_per_sync);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setDelayedWriteRate
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setDelayedWriteRate(
+ JNIEnv*, jobject, jlong jhandle, jlong jdelayed_write_rate) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->delayed_write_rate = static_cast<uint64_t>(jdelayed_write_rate);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: delayedWriteRate
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_delayedWriteRate(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jlong>(opt->delayed_write_rate);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setEnablePipelinedWrite
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setEnablePipelinedWrite(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenable_pipelined_write) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->enable_pipelined_write = jenable_pipelined_write == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: enablePipelinedWrite
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_enablePipelinedWrite(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->enable_pipelined_write);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setEnableThreadTracking
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setEnableThreadTracking(
+ JNIEnv*, jobject, jlong jhandle, jboolean jenable_thread_tracking) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->enable_thread_tracking = jenable_thread_tracking == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: enableThreadTracking
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_enableThreadTracking(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->enable_thread_tracking);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAllowConcurrentMemtableWrite
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAllowConcurrentMemtableWrite(
+ JNIEnv*, jobject, jlong jhandle, jboolean allow) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->allow_concurrent_memtable_write = static_cast<bool>(allow);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: allowConcurrentMemtableWrite
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_allowConcurrentMemtableWrite(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->allow_concurrent_memtable_write;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setEnableWriteThreadAdaptiveYield
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setEnableWriteThreadAdaptiveYield(
+ JNIEnv*, jobject, jlong jhandle, jboolean yield) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->enable_write_thread_adaptive_yield = static_cast<bool>(yield);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: enableWriteThreadAdaptiveYield
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_enableWriteThreadAdaptiveYield(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->enable_write_thread_adaptive_yield;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWriteThreadMaxYieldUsec
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWriteThreadMaxYieldUsec(
+ JNIEnv*, jobject, jlong jhandle, jlong max) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->write_thread_max_yield_usec =
+ static_cast<int64_t>(max);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: writeThreadMaxYieldUsec
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_writeThreadMaxYieldUsec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->write_thread_max_yield_usec;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWriteThreadSlowYieldUsec
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWriteThreadSlowYieldUsec(
+ JNIEnv*, jobject, jlong jhandle, jlong slow) {
+ reinterpret_cast<rocksdb::DBOptions*>(jhandle)->write_thread_slow_yield_usec =
+ static_cast<int64_t>(slow);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: writeThreadSlowYieldUsec
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_DBOptions_writeThreadSlowYieldUsec(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::DBOptions*>(jhandle)
+ ->write_thread_slow_yield_usec;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setSkipStatsUpdateOnDbOpen
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setSkipStatsUpdateOnDbOpen(
+ JNIEnv*, jobject, jlong jhandle, jboolean jskip_stats_update_on_db_open) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->skip_stats_update_on_db_open =
+ static_cast<bool>(jskip_stats_update_on_db_open);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: skipStatsUpdateOnDbOpen
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_skipStatsUpdateOnDbOpen(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->skip_stats_update_on_db_open);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWalRecoveryMode
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_DBOptions_setWalRecoveryMode(
+ JNIEnv*, jobject, jlong jhandle, jbyte jwal_recovery_mode_value) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->wal_recovery_mode = rocksdb::WALRecoveryModeJni::toCppWALRecoveryMode(
+ jwal_recovery_mode_value);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: walRecoveryMode
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_DBOptions_walRecoveryMode(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return rocksdb::WALRecoveryModeJni::toJavaWALRecoveryMode(
+ opt->wal_recovery_mode);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAllow2pc
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAllow2pc(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_2pc) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->allow_2pc = static_cast<bool>(jallow_2pc);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: allow2pc
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_allow2pc(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->allow_2pc);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setRowCache
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setRowCache(
+ JNIEnv*, jobject, jlong jhandle, jlong jrow_cache_handle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ auto* row_cache =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache>*>(jrow_cache_handle);
+ opt->row_cache = *row_cache;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setWalFilter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DBOptions_setWalFilter(
+ JNIEnv*, jobject, jlong jhandle, jlong jwal_filter_handle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ auto* wal_filter =
+ reinterpret_cast<rocksdb::WalFilterJniCallback*>(jwal_filter_handle);
+ opt->wal_filter = wal_filter;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setFailIfOptionsFileError
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setFailIfOptionsFileError(
+ JNIEnv*, jobject, jlong jhandle, jboolean jfail_if_options_file_error) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->fail_if_options_file_error =
+ static_cast<bool>(jfail_if_options_file_error);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: failIfOptionsFileError
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_failIfOptionsFileError(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->fail_if_options_file_error);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setDumpMallocStats
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setDumpMallocStats(
+ JNIEnv*, jobject, jlong jhandle, jboolean jdump_malloc_stats) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->dump_malloc_stats = static_cast<bool>(jdump_malloc_stats);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: dumpMallocStats
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_dumpMallocStats(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->dump_malloc_stats);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAvoidFlushDuringRecovery
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAvoidFlushDuringRecovery(
+ JNIEnv*, jobject, jlong jhandle, jboolean javoid_flush_during_recovery) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->avoid_flush_during_recovery =
+ static_cast<bool>(javoid_flush_during_recovery);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: avoidFlushDuringRecovery
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_avoidFlushDuringRecovery(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->avoid_flush_during_recovery);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAllowIngestBehind
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAllowIngestBehind(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_ingest_behind) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->allow_ingest_behind = jallow_ingest_behind == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: allowIngestBehind
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_allowIngestBehind(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->allow_ingest_behind);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setPreserveDeletes
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setPreserveDeletes(
+ JNIEnv*, jobject, jlong jhandle, jboolean jpreserve_deletes) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->preserve_deletes = jpreserve_deletes == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: preserveDeletes
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_preserveDeletes(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->preserve_deletes);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setTwoWriteQueues
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setTwoWriteQueues(
+ JNIEnv*, jobject, jlong jhandle, jboolean jtwo_write_queues) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->two_write_queues = jtwo_write_queues == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: twoWriteQueues
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_twoWriteQueues(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->two_write_queues);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setManualWalFlush
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setManualWalFlush(
+ JNIEnv*, jobject, jlong jhandle, jboolean jmanual_wal_flush) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->manual_wal_flush = jmanual_wal_flush == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: manualWalFlush
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_manualWalFlush(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->manual_wal_flush);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAtomicFlush
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAtomicFlush(
+ JNIEnv*, jobject, jlong jhandle, jboolean jatomic_flush) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->atomic_flush = jatomic_flush == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: atomicFlush
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_atomicFlush(
+ JNIEnv *, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->atomic_flush);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: setAvoidFlushDuringShutdown
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_DBOptions_setAvoidFlushDuringShutdown(
+ JNIEnv*, jobject, jlong jhandle, jboolean javoid_flush_during_shutdown) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ opt->avoid_flush_during_shutdown =
+ static_cast<bool>(javoid_flush_during_shutdown);
+}
+
+/*
+ * Class: org_rocksdb_DBOptions
+ * Method: avoidFlushDuringShutdown
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_DBOptions_avoidFlushDuringShutdown(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jhandle);
+ return static_cast<jboolean>(opt->avoid_flush_during_shutdown);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::WriteOptions
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: newWriteOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_WriteOptions_newWriteOptions(
+ JNIEnv*, jclass) {
+ auto* op = new rocksdb::WriteOptions();
+ return reinterpret_cast<jlong>(op);
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: copyWriteOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_WriteOptions_copyWriteOptions(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto new_opt = new rocksdb::WriteOptions(
+ *(reinterpret_cast<rocksdb::WriteOptions*>(jhandle)));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: disposeInternal
+ * Signature: ()V
+ */
+void Java_org_rocksdb_WriteOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* write_options = reinterpret_cast<rocksdb::WriteOptions*>(jhandle);
+ assert(write_options != nullptr);
+ delete write_options;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: setSync
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_WriteOptions_setSync(
+ JNIEnv*, jobject, jlong jhandle, jboolean jflag) {
+ reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->sync = jflag;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: sync
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteOptions_sync(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->sync;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: setDisableWAL
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_WriteOptions_setDisableWAL(
+ JNIEnv*, jobject, jlong jhandle, jboolean jflag) {
+ reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->disableWAL = jflag;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: disableWAL
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteOptions_disableWAL(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->disableWAL;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: setIgnoreMissingColumnFamilies
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_WriteOptions_setIgnoreMissingColumnFamilies(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean jignore_missing_column_families) {
+ reinterpret_cast<rocksdb::WriteOptions*>(jhandle)
+ ->ignore_missing_column_families =
+ static_cast<bool>(jignore_missing_column_families);
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: ignoreMissingColumnFamilies
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteOptions_ignoreMissingColumnFamilies(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::WriteOptions*>(jhandle)
+ ->ignore_missing_column_families;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: setNoSlowdown
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_WriteOptions_setNoSlowdown(
+ JNIEnv*, jobject, jlong jhandle, jboolean jno_slowdown) {
+ reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->no_slowdown =
+ static_cast<bool>(jno_slowdown);
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: noSlowdown
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteOptions_noSlowdown(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->no_slowdown;
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: setLowPri
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_WriteOptions_setLowPri(
+ JNIEnv*, jobject, jlong jhandle, jboolean jlow_pri) {
+ reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->low_pri =
+ static_cast<bool>(jlow_pri);
+}
+
+/*
+ * Class: org_rocksdb_WriteOptions
+ * Method: lowPri
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteOptions_lowPri(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::WriteOptions*>(jhandle)->low_pri;
+}
+
+/////////////////////////////////////////////////////////////////////
+// rocksdb::ReadOptions
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: newReadOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_ReadOptions_newReadOptions__(
+ JNIEnv*, jclass) {
+ auto* read_options = new rocksdb::ReadOptions();
+ return reinterpret_cast<jlong>(read_options);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: newReadOptions
+ * Signature: (ZZ)J
+ */
+jlong Java_org_rocksdb_ReadOptions_newReadOptions__ZZ(
+ JNIEnv*, jclass, jboolean jverify_checksums, jboolean jfill_cache) {
+ auto* read_options =
+ new rocksdb::ReadOptions(static_cast<bool>(jverify_checksums),
+ static_cast<bool>(jfill_cache));
+ return reinterpret_cast<jlong>(read_options);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: copyReadOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_copyReadOptions(
+ JNIEnv*, jclass, jlong jhandle) {
+ auto new_opt = new rocksdb::ReadOptions(
+ *(reinterpret_cast<rocksdb::ReadOptions*>(jhandle)));
+ return reinterpret_cast<jlong>(new_opt);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_ReadOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* read_options = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ assert(read_options != nullptr);
+ delete read_options;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setVerifyChecksums
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setVerifyChecksums(
+ JNIEnv*, jobject, jlong jhandle, jboolean jverify_checksums) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->verify_checksums =
+ static_cast<bool>(jverify_checksums);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: verifyChecksums
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_verifyChecksums(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->verify_checksums;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setFillCache
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setFillCache(
+ JNIEnv*, jobject, jlong jhandle, jboolean jfill_cache) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->fill_cache =
+ static_cast<bool>(jfill_cache);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: fillCache
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_fillCache(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->fill_cache;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setTailing
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setTailing(
+ JNIEnv*, jobject, jlong jhandle, jboolean jtailing) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->tailing =
+ static_cast<bool>(jtailing);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: tailing
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_tailing(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->tailing;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: managed
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_managed(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->managed;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setManaged
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setManaged(
+ JNIEnv*, jobject, jlong jhandle, jboolean jmanaged) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->managed =
+ static_cast<bool>(jmanaged);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: totalOrderSeek
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_totalOrderSeek(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->total_order_seek;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setTotalOrderSeek
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setTotalOrderSeek(
+ JNIEnv*, jobject, jlong jhandle, jboolean jtotal_order_seek) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->total_order_seek =
+ static_cast<bool>(jtotal_order_seek);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: prefixSameAsStart
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_prefixSameAsStart(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->prefix_same_as_start;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setPrefixSameAsStart
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setPrefixSameAsStart(
+ JNIEnv*, jobject, jlong jhandle, jboolean jprefix_same_as_start) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->prefix_same_as_start =
+ static_cast<bool>(jprefix_same_as_start);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: pinData
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_pinData(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->pin_data;
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setPinData
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setPinData(
+ JNIEnv*, jobject, jlong jhandle, jboolean jpin_data) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->pin_data =
+ static_cast<bool>(jpin_data);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: backgroundPurgeOnIteratorCleanup
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_backgroundPurgeOnIteratorCleanup(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ return static_cast<jboolean>(opt->background_purge_on_iterator_cleanup);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setBackgroundPurgeOnIteratorCleanup
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setBackgroundPurgeOnIteratorCleanup(
+ JNIEnv*, jobject, jlong jhandle,
+ jboolean jbackground_purge_on_iterator_cleanup) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ opt->background_purge_on_iterator_cleanup =
+ static_cast<bool>(jbackground_purge_on_iterator_cleanup);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: readaheadSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_readaheadSize(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ return static_cast<jlong>(opt->readahead_size);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setReadaheadSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ReadOptions_setReadaheadSize(
+ JNIEnv*, jobject, jlong jhandle, jlong jreadahead_size) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ opt->readahead_size = static_cast<size_t>(jreadahead_size);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: maxSkippableInternalKeys
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_maxSkippableInternalKeys(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ return static_cast<jlong>(opt->max_skippable_internal_keys);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setMaxSkippableInternalKeys
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ReadOptions_setMaxSkippableInternalKeys(
+ JNIEnv*, jobject, jlong jhandle, jlong jmax_skippable_internal_keys) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ opt->max_skippable_internal_keys =
+ static_cast<uint64_t>(jmax_skippable_internal_keys);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: ignoreRangeDeletions
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ReadOptions_ignoreRangeDeletions(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ return static_cast<jboolean>(opt->ignore_range_deletions);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setIgnoreRangeDeletions
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ReadOptions_setIgnoreRangeDeletions(
+ JNIEnv*, jobject, jlong jhandle, jboolean jignore_range_deletions) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ opt->ignore_range_deletions = static_cast<bool>(jignore_range_deletions);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setSnapshot
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ReadOptions_setSnapshot(
+ JNIEnv*, jobject, jlong jhandle, jlong jsnapshot) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->snapshot =
+ reinterpret_cast<rocksdb::Snapshot*>(jsnapshot);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: snapshot
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_snapshot(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto& snapshot = reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->snapshot;
+ return reinterpret_cast<jlong>(snapshot);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: readTier
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_ReadOptions_readTier(
+ JNIEnv*, jobject, jlong jhandle) {
+ return static_cast<jbyte>(
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->read_tier);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setReadTier
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_ReadOptions_setReadTier(
+ JNIEnv*, jobject, jlong jhandle, jbyte jread_tier) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->read_tier =
+ static_cast<rocksdb::ReadTier>(jread_tier);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setIterateUpperBound
+ * Signature: (JJ)I
+ */
+void Java_org_rocksdb_ReadOptions_setIterateUpperBound(
+ JNIEnv*, jobject, jlong jhandle, jlong jupper_bound_slice_handle) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->iterate_upper_bound =
+ reinterpret_cast<rocksdb::Slice*>(jupper_bound_slice_handle);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: iterateUpperBound
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_iterateUpperBound(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto& upper_bound_slice_handle =
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->iterate_upper_bound;
+ return reinterpret_cast<jlong>(upper_bound_slice_handle);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setIterateLowerBound
+ * Signature: (JJ)I
+ */
+void Java_org_rocksdb_ReadOptions_setIterateLowerBound(
+ JNIEnv*, jobject, jlong jhandle, jlong jlower_bound_slice_handle) {
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->iterate_lower_bound =
+ reinterpret_cast<rocksdb::Slice*>(jlower_bound_slice_handle);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: iterateLowerBound
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_iterateLowerBound(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto& lower_bound_slice_handle =
+ reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->iterate_lower_bound;
+ return reinterpret_cast<jlong>(lower_bound_slice_handle);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setTableFilter
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ReadOptions_setTableFilter(
+ JNIEnv*, jobject, jlong jhandle, jlong jjni_table_filter_handle) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ auto* jni_table_filter =
+ reinterpret_cast<rocksdb::TableFilterJniCallback*>(jjni_table_filter_handle);
+ opt->table_filter = jni_table_filter->GetTableFilterFunction();
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: setIterStartSeqnum
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_ReadOptions_setIterStartSeqnum(
+ JNIEnv*, jobject, jlong jhandle, jlong jiter_start_seqnum) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ opt->iter_start_seqnum = static_cast<uint64_t>(jiter_start_seqnum);
+}
+
+/*
+ * Class: org_rocksdb_ReadOptions
+ * Method: iterStartSeqnum
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_ReadOptions_iterStartSeqnum(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* opt = reinterpret_cast<rocksdb::ReadOptions*>(jhandle);
+ return static_cast<jlong>(opt->iter_start_seqnum);
+}
+
+/////////////////////////////////////////////////////////////////////
+// rocksdb::ComparatorOptions
+
+/*
+ * Class: org_rocksdb_ComparatorOptions
+ * Method: newComparatorOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_ComparatorOptions_newComparatorOptions(
+ JNIEnv*, jclass) {
+ auto* comparator_opt = new rocksdb::ComparatorJniCallbackOptions();
+ return reinterpret_cast<jlong>(comparator_opt);
+}
+
+/*
+ * Class: org_rocksdb_ComparatorOptions
+ * Method: useAdaptiveMutex
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_ComparatorOptions_useAdaptiveMutex(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle)
+ ->use_adaptive_mutex;
+}
+
+/*
+ * Class: org_rocksdb_ComparatorOptions
+ * Method: setUseAdaptiveMutex
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_ComparatorOptions_setUseAdaptiveMutex(
+ JNIEnv*, jobject, jlong jhandle, jboolean juse_adaptive_mutex) {
+ reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle)
+ ->use_adaptive_mutex = static_cast<bool>(juse_adaptive_mutex);
+}
+
+/*
+ * Class: org_rocksdb_ComparatorOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_ComparatorOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* comparator_opt =
+ reinterpret_cast<rocksdb::ComparatorJniCallbackOptions*>(jhandle);
+ assert(comparator_opt != nullptr);
+ delete comparator_opt;
+}
+
+/////////////////////////////////////////////////////////////////////
+// rocksdb::FlushOptions
+
+/*
+ * Class: org_rocksdb_FlushOptions
+ * Method: newFlushOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_FlushOptions_newFlushOptions(
+ JNIEnv*, jclass) {
+ auto* flush_opt = new rocksdb::FlushOptions();
+ return reinterpret_cast<jlong>(flush_opt);
+}
+
+/*
+ * Class: org_rocksdb_FlushOptions
+ * Method: setWaitForFlush
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_FlushOptions_setWaitForFlush(
+ JNIEnv*, jobject, jlong jhandle, jboolean jwait) {
+ reinterpret_cast<rocksdb::FlushOptions*>(jhandle)->wait =
+ static_cast<bool>(jwait);
+}
+
+/*
+ * Class: org_rocksdb_FlushOptions
+ * Method: waitForFlush
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_FlushOptions_waitForFlush(
+ JNIEnv*, jobject, jlong jhandle) {
+ return reinterpret_cast<rocksdb::FlushOptions*>(jhandle)->wait;
+}
+
+/*
+ * Class: org_rocksdb_FlushOptions
+ * Method: setAllowWriteStall
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_FlushOptions_setAllowWriteStall(
+ JNIEnv*, jobject, jlong jhandle, jboolean jallow_write_stall) {
+ auto* flush_options = reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
+ flush_options->allow_write_stall = jallow_write_stall == JNI_TRUE;
+}
+
+/*
+ * Class: org_rocksdb_FlushOptions
+ * Method: allowWriteStall
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_FlushOptions_allowWriteStall(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* flush_options = reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
+ return static_cast<jboolean>(flush_options->allow_write_stall);
+}
+
+/*
+ * Class: org_rocksdb_FlushOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_FlushOptions_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* flush_opt = reinterpret_cast<rocksdb::FlushOptions*>(jhandle);
+ assert(flush_opt != nullptr);
+ delete flush_opt;
+}
diff --git a/src/rocksdb/java/rocksjni/options_util.cc b/src/rocksdb/java/rocksjni/options_util.cc
new file mode 100644
index 00000000..7dd00784
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/options_util.cc
@@ -0,0 +1,130 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling C++ rocksdb::OptionsUtil methods from Java side.
+
+#include <jni.h>
+#include <string>
+
+#include "include/org_rocksdb_OptionsUtil.h"
+
+#include "rocksdb/db.h"
+#include "rocksdb/env.h"
+#include "rocksdb/utilities/options_util.h"
+#include "rocksjni/portal.h"
+
+void build_column_family_descriptor_list(
+ JNIEnv* env, jobject jcfds,
+ std::vector<rocksdb::ColumnFamilyDescriptor>& cf_descs) {
+ jmethodID add_mid = rocksdb::ListJni::getListAddMethodId(env);
+ if (add_mid == nullptr) {
+ // exception occurred accessing method
+ return;
+ }
+
+ // Column family descriptor
+ for (rocksdb::ColumnFamilyDescriptor& cfd : cf_descs) {
+ // Construct a ColumnFamilyDescriptor java object
+ jobject jcfd = rocksdb::ColumnFamilyDescriptorJni::construct(env, &cfd);
+ if (env->ExceptionCheck()) {
+ // exception occurred constructing object
+ if (jcfd != nullptr) {
+ env->DeleteLocalRef(jcfd);
+ }
+ return;
+ }
+
+ // Add the object to java list.
+ jboolean rs = env->CallBooleanMethod(jcfds, add_mid, jcfd);
+ if (env->ExceptionCheck() || rs == JNI_FALSE) {
+ // exception occurred calling method, or could not add
+ if (jcfd != nullptr) {
+ env->DeleteLocalRef(jcfd);
+ }
+ return;
+ }
+ }
+}
+
+/*
+ * Class: org_rocksdb_OptionsUtil
+ * Method: loadLatestOptions
+ * Signature: (Ljava/lang/String;JLjava/util/List;Z)V
+ */
+void Java_org_rocksdb_OptionsUtil_loadLatestOptions(
+ JNIEnv* env, jclass /*jcls*/, jstring jdbpath, jlong jenv_handle,
+ jlong jdb_opts_handle, jobject jcfds, jboolean ignore_unknown_options) {
+ jboolean has_exception = JNI_FALSE;
+ auto db_path = rocksdb::JniUtil::copyStdString(env, jdbpath, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+ std::vector<rocksdb::ColumnFamilyDescriptor> cf_descs;
+ rocksdb::Status s = rocksdb::LoadLatestOptions(
+ db_path, reinterpret_cast<rocksdb::Env*>(jenv_handle),
+ reinterpret_cast<rocksdb::DBOptions*>(jdb_opts_handle), &cf_descs,
+ ignore_unknown_options);
+ if (!s.ok()) {
+ // error, raise an exception
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ } else {
+ build_column_family_descriptor_list(env, jcfds, cf_descs);
+ }
+}
+
+/*
+ * Class: org_rocksdb_OptionsUtil
+ * Method: loadOptionsFromFile
+ * Signature: (Ljava/lang/String;JJLjava/util/List;Z)V
+ */
+void Java_org_rocksdb_OptionsUtil_loadOptionsFromFile(
+ JNIEnv* env, jclass /*jcls*/, jstring jopts_file_name, jlong jenv_handle,
+ jlong jdb_opts_handle, jobject jcfds, jboolean ignore_unknown_options) {
+ jboolean has_exception = JNI_FALSE;
+ auto opts_file_name = rocksdb::JniUtil::copyStdString(env, jopts_file_name, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+ std::vector<rocksdb::ColumnFamilyDescriptor> cf_descs;
+ rocksdb::Status s = rocksdb::LoadOptionsFromFile(
+ opts_file_name, reinterpret_cast<rocksdb::Env*>(jenv_handle),
+ reinterpret_cast<rocksdb::DBOptions*>(jdb_opts_handle), &cf_descs,
+ ignore_unknown_options);
+ if (!s.ok()) {
+ // error, raise an exception
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ } else {
+ build_column_family_descriptor_list(env, jcfds, cf_descs);
+ }
+}
+
+/*
+ * Class: org_rocksdb_OptionsUtil
+ * Method: getLatestOptionsFileName
+ * Signature: (Ljava/lang/String;J)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_OptionsUtil_getLatestOptionsFileName(
+ JNIEnv* env, jclass /*jcls*/, jstring jdbpath, jlong jenv_handle) {
+ jboolean has_exception = JNI_FALSE;
+ auto db_path = rocksdb::JniUtil::copyStdString(env, jdbpath, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return nullptr;
+ }
+ std::string options_file_name;
+ rocksdb::Status s = rocksdb::GetLatestOptionsFileName(
+ db_path, reinterpret_cast<rocksdb::Env*>(jenv_handle),
+ &options_file_name);
+ if (!s.ok()) {
+ // error, raise an exception
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ } else {
+ return env->NewStringUTF(options_file_name.c_str());
+ }
+}
diff --git a/src/rocksdb/java/rocksjni/persistent_cache.cc b/src/rocksdb/java/rocksjni/persistent_cache.cc
new file mode 100644
index 00000000..2b6fc60b
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/persistent_cache.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::PersistentCache.
+
+#include <jni.h>
+#include <string>
+
+#include "include/org_rocksdb_PersistentCache.h"
+#include "rocksdb/persistent_cache.h"
+#include "loggerjnicallback.h"
+#include "portal.h"
+
+/*
+ * Class: org_rocksdb_PersistentCache
+ * Method: newPersistentCache
+ * Signature: (JLjava/lang/String;JJZ)J
+ */
+jlong Java_org_rocksdb_PersistentCache_newPersistentCache(
+ JNIEnv* env, jclass, jlong jenv_handle, jstring jpath,
+ jlong jsz, jlong jlogger_handle, jboolean joptimized_for_nvm) {
+ auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jenv_handle);
+ jboolean has_exception = JNI_FALSE;
+ std::string path = rocksdb::JniUtil::copyStdString(env, jpath, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ return 0;
+ }
+ auto* logger =
+ reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback>*>(jlogger_handle);
+ auto* cache = new std::shared_ptr<rocksdb::PersistentCache>(nullptr);
+ rocksdb::Status s = rocksdb::NewPersistentCache(
+ rocks_env, path, static_cast<uint64_t>(jsz), *logger,
+ static_cast<bool>(joptimized_for_nvm), cache);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+ return reinterpret_cast<jlong>(cache);
+}
+
+/*
+ * Class: org_rocksdb_PersistentCache
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_PersistentCache_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* cache =
+ reinterpret_cast<std::shared_ptr<rocksdb::PersistentCache>*>(jhandle);
+ delete cache; // delete std::shared_ptr
+}
diff --git a/src/rocksdb/java/rocksjni/portal.h b/src/rocksdb/java/rocksjni/portal.h
new file mode 100644
index 00000000..70e67653
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/portal.h
@@ -0,0 +1,7092 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+// This file is designed for caching those frequently used IDs and provide
+// efficient portal (i.e, a set of static functions) to access java code
+// from c++.
+
+#ifndef JAVA_ROCKSJNI_PORTAL_H_
+#define JAVA_ROCKSJNI_PORTAL_H_
+
+#include <algorithm>
+#include <cstring>
+#include <functional>
+#include <iostream>
+#include <iterator>
+#include <jni.h>
+#include <limits>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "rocksdb/db.h"
+#include "rocksdb/filter_policy.h"
+#include "rocksdb/rate_limiter.h"
+#include "rocksdb/status.h"
+#include "rocksdb/table.h"
+#include "rocksdb/utilities/backupable_db.h"
+#include "rocksdb/utilities/memory_util.h"
+#include "rocksdb/utilities/transaction_db.h"
+#include "rocksdb/utilities/write_batch_with_index.h"
+#include "rocksjni/compaction_filter_factory_jnicallback.h"
+#include "rocksjni/comparatorjnicallback.h"
+#include "rocksjni/loggerjnicallback.h"
+#include "rocksjni/table_filter_jnicallback.h"
+#include "rocksjni/trace_writer_jnicallback.h"
+#include "rocksjni/transaction_notifier_jnicallback.h"
+#include "rocksjni/wal_filter_jnicallback.h"
+#include "rocksjni/writebatchhandlerjnicallback.h"
+
+// Remove macro on windows
+#ifdef DELETE
+#undef DELETE
+#endif
+
+namespace rocksdb {
+
+class JavaClass {
+ public:
+ /**
+ * Gets and initializes a Java Class
+ *
+ * @param env A pointer to the Java environment
+ * @param jclazz_name The fully qualified JNI name of the Java Class
+ * e.g. "java/lang/String"
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env, const char* jclazz_name) {
+ jclass jclazz = env->FindClass(jclazz_name);
+ assert(jclazz != nullptr);
+ return jclazz;
+ }
+};
+
+// Native class template
+template<class PTR, class DERIVED> class RocksDBNativeClass : public JavaClass {
+};
+
+// Native class template for sub-classes of RocksMutableObject
+template<class PTR, class DERIVED> class NativeRocksMutableObject
+ : public RocksDBNativeClass<PTR, DERIVED> {
+ public:
+
+ /**
+ * Gets the Java Method ID for the
+ * RocksMutableObject#setNativeHandle(long, boolean) method
+ *
+ * @param env A pointer to the Java environment
+ * @return The Java Method ID or nullptr the RocksMutableObject class cannot
+ * be accessed, or if one of the NoSuchMethodError,
+ * ExceptionInInitializerError or OutOfMemoryError exceptions is thrown
+ */
+ static jmethodID getSetNativeHandleMethod(JNIEnv* env) {
+ static jclass jclazz = DERIVED::getJClass(env);
+ if(jclazz == nullptr) {
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "setNativeHandle", "(JZ)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Sets the C++ object pointer handle in the Java object
+ *
+ * @param env A pointer to the Java environment
+ * @param jobj The Java object on which to set the pointer handle
+ * @param ptr The C++ object pointer
+ * @param java_owns_handle JNI_TRUE if ownership of the C++ object is
+ * managed by the Java object
+ *
+ * @return true if a Java exception is pending, false otherwise
+ */
+ static bool setHandle(JNIEnv* env, jobject jobj, PTR ptr,
+ jboolean java_owns_handle) {
+ assert(jobj != nullptr);
+ static jmethodID mid = getSetNativeHandleMethod(env);
+ if(mid == nullptr) {
+ return true; // signal exception
+ }
+
+ env->CallVoidMethod(jobj, mid, reinterpret_cast<jlong>(ptr), java_owns_handle);
+ if(env->ExceptionCheck()) {
+ return true; // signal exception
+ }
+
+ return false;
+ }
+};
+
+// Java Exception template
+template<class DERIVED> class JavaException : public JavaClass {
+ public:
+ /**
+ * Create and throw a java exception with the provided message
+ *
+ * @param env A pointer to the Java environment
+ * @param msg The message for the exception
+ *
+ * @return true if an exception was thrown, false otherwise
+ */
+ static bool ThrowNew(JNIEnv* env, const std::string& msg) {
+ jclass jclazz = DERIVED::getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ std::cerr << "JavaException::ThrowNew - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ const jint rs = env->ThrowNew(jclazz, msg.c_str());
+ if(rs != JNI_OK) {
+ // exception could not be thrown
+ std::cerr << "JavaException::ThrowNew - Fatal: could not throw exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ return true;
+ }
+};
+
+// The portal class for java.lang.IllegalArgumentException
+class IllegalArgumentExceptionJni :
+ public JavaException<IllegalArgumentExceptionJni> {
+ public:
+ /**
+ * Get the Java Class java.lang.IllegalArgumentException
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaException::getJClass(env, "java/lang/IllegalArgumentException");
+ }
+
+ /**
+ * Create and throw a Java IllegalArgumentException with the provided status
+ *
+ * If s.ok() == true, then this function will not throw any exception.
+ *
+ * @param env A pointer to the Java environment
+ * @param s The status for the exception
+ *
+ * @return true if an exception was thrown, false otherwise
+ */
+ static bool ThrowNew(JNIEnv* env, const Status& s) {
+ assert(!s.ok());
+ if (s.ok()) {
+ return false;
+ }
+
+ // get the IllegalArgumentException class
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ std::cerr << "IllegalArgumentExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ return JavaException::ThrowNew(env, s.ToString());
+ }
+};
+
+// The portal class for org.rocksdb.Status.Code
+class CodeJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Status.Code
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/Status$Code");
+ }
+
+ /**
+ * Get the Java Method: Status.Code#getValue
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getValueMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "getValue", "()b");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.Status.SubCode
+class SubCodeJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Status.SubCode
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/Status$SubCode");
+ }
+
+ /**
+ * Get the Java Method: Status.SubCode#getValue
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getValueMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "getValue", "()b");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ static rocksdb::Status::SubCode toCppSubCode(const jbyte jsub_code) {
+ switch (jsub_code) {
+ case 0x0:
+ return rocksdb::Status::SubCode::kNone;
+ case 0x1:
+ return rocksdb::Status::SubCode::kMutexTimeout;
+ case 0x2:
+ return rocksdb::Status::SubCode::kLockTimeout;
+ case 0x3:
+ return rocksdb::Status::SubCode::kLockLimit;
+ case 0x4:
+ return rocksdb::Status::SubCode::kNoSpace;
+ case 0x5:
+ return rocksdb::Status::SubCode::kDeadlock;
+ case 0x6:
+ return rocksdb::Status::SubCode::kStaleFile;
+ case 0x7:
+ return rocksdb::Status::SubCode::kMemoryLimit;
+
+ case 0x7F:
+ default:
+ return rocksdb::Status::SubCode::kNone;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.Status
+class StatusJni : public RocksDBNativeClass<rocksdb::Status*, StatusJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Status
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/Status");
+ }
+
+ /**
+ * Get the Java Method: Status#getCode
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getCodeMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "getCode", "()Lorg/rocksdb/Status$Code;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Status#getSubCode
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getSubCodeMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "getSubCode", "()Lorg/rocksdb/Status$SubCode;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Status#getState
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getStateMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "getState", "()Ljava/lang/String;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Create a new Java org.rocksdb.Status object with the same properties as
+ * the provided C++ rocksdb::Status object
+ *
+ * @param env A pointer to the Java environment
+ * @param status The rocksdb::Status object
+ *
+ * @return A reference to a Java org.rocksdb.Status object, or nullptr
+ * if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env, const Status& status) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid =
+ env->GetMethodID(jclazz, "<init>", "(BBLjava/lang/String;)V");
+ if(mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ // convert the Status state for Java
+ jstring jstate = nullptr;
+ if (status.getState() != nullptr) {
+ const char* const state = status.getState();
+ jstate = env->NewStringUTF(state);
+ if(env->ExceptionCheck()) {
+ if(jstate != nullptr) {
+ env->DeleteLocalRef(jstate);
+ }
+ return nullptr;
+ }
+ }
+
+ jobject jstatus =
+ env->NewObject(jclazz, mid, toJavaStatusCode(status.code()),
+ toJavaStatusSubCode(status.subcode()), jstate);
+ if(env->ExceptionCheck()) {
+ // exception occurred
+ if(jstate != nullptr) {
+ env->DeleteLocalRef(jstate);
+ }
+ return nullptr;
+ }
+
+ if(jstate != nullptr) {
+ env->DeleteLocalRef(jstate);
+ }
+
+ return jstatus;
+ }
+
+ // Returns the equivalent org.rocksdb.Status.Code for the provided
+ // C++ rocksdb::Status::Code enum
+ static jbyte toJavaStatusCode(const rocksdb::Status::Code& code) {
+ switch (code) {
+ case rocksdb::Status::Code::kOk:
+ return 0x0;
+ case rocksdb::Status::Code::kNotFound:
+ return 0x1;
+ case rocksdb::Status::Code::kCorruption:
+ return 0x2;
+ case rocksdb::Status::Code::kNotSupported:
+ return 0x3;
+ case rocksdb::Status::Code::kInvalidArgument:
+ return 0x4;
+ case rocksdb::Status::Code::kIOError:
+ return 0x5;
+ case rocksdb::Status::Code::kMergeInProgress:
+ return 0x6;
+ case rocksdb::Status::Code::kIncomplete:
+ return 0x7;
+ case rocksdb::Status::Code::kShutdownInProgress:
+ return 0x8;
+ case rocksdb::Status::Code::kTimedOut:
+ return 0x9;
+ case rocksdb::Status::Code::kAborted:
+ return 0xA;
+ case rocksdb::Status::Code::kBusy:
+ return 0xB;
+ case rocksdb::Status::Code::kExpired:
+ return 0xC;
+ case rocksdb::Status::Code::kTryAgain:
+ return 0xD;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent org.rocksdb.Status.SubCode for the provided
+ // C++ rocksdb::Status::SubCode enum
+ static jbyte toJavaStatusSubCode(const rocksdb::Status::SubCode& subCode) {
+ switch (subCode) {
+ case rocksdb::Status::SubCode::kNone:
+ return 0x0;
+ case rocksdb::Status::SubCode::kMutexTimeout:
+ return 0x1;
+ case rocksdb::Status::SubCode::kLockTimeout:
+ return 0x2;
+ case rocksdb::Status::SubCode::kLockLimit:
+ return 0x3;
+ case rocksdb::Status::SubCode::kNoSpace:
+ return 0x4;
+ case rocksdb::Status::SubCode::kDeadlock:
+ return 0x5;
+ case rocksdb::Status::SubCode::kStaleFile:
+ return 0x6;
+ case rocksdb::Status::SubCode::kMemoryLimit:
+ return 0x7;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ static std::unique_ptr<rocksdb::Status> toCppStatus(
+ const jbyte jcode_value, const jbyte jsub_code_value) {
+ std::unique_ptr<rocksdb::Status> status;
+ switch (jcode_value) {
+ case 0x0:
+ //Ok
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::OK()));
+ break;
+ case 0x1:
+ //NotFound
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::NotFound(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x2:
+ //Corruption
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::Corruption(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x3:
+ //NotSupported
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::NotSupported(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x4:
+ //InvalidArgument
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::InvalidArgument(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x5:
+ //IOError
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::IOError(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x6:
+ //MergeInProgress
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::MergeInProgress(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x7:
+ //Incomplete
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::Incomplete(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x8:
+ //ShutdownInProgress
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::ShutdownInProgress(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x9:
+ //TimedOut
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::TimedOut(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0xA:
+ //Aborted
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::Aborted(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0xB:
+ //Busy
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::Busy(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0xC:
+ //Expired
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::Expired(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0xD:
+ //TryAgain
+ status = std::unique_ptr<rocksdb::Status>(
+ new rocksdb::Status(rocksdb::Status::TryAgain(
+ rocksdb::SubCodeJni::toCppSubCode(jsub_code_value))));
+ break;
+ case 0x7F:
+ default:
+ return nullptr;
+ }
+ return status;
+ }
+
+ // Returns the equivalent rocksdb::Status for the Java org.rocksdb.Status
+ static std::unique_ptr<rocksdb::Status> toCppStatus(JNIEnv* env, const jobject jstatus) {
+ jmethodID mid_code = getCodeMethod(env);
+ if (mid_code == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ jobject jcode = env->CallObjectMethod(jstatus, mid_code);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ return nullptr;
+ }
+
+ jmethodID mid_code_value = rocksdb::CodeJni::getValueMethod(env);
+ if (mid_code_value == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ jbyte jcode_value = env->CallByteMethod(jcode, mid_code_value);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ if (jcode != nullptr) {
+ env->DeleteLocalRef(jcode);
+ }
+ return nullptr;
+ }
+
+ jmethodID mid_subCode = getSubCodeMethod(env);
+ if (mid_subCode == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ jobject jsubCode = env->CallObjectMethod(jstatus, mid_subCode);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ if (jcode != nullptr) {
+ env->DeleteLocalRef(jcode);
+ }
+ return nullptr;
+ }
+
+ jbyte jsub_code_value = 0x0; // None
+ if (jsubCode != nullptr) {
+ jmethodID mid_subCode_value = rocksdb::SubCodeJni::getValueMethod(env);
+ if (mid_subCode_value == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ jsub_code_value = env->CallByteMethod(jsubCode, mid_subCode_value);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ if (jcode != nullptr) {
+ env->DeleteLocalRef(jcode);
+ }
+ return nullptr;
+ }
+ }
+
+ jmethodID mid_state = getStateMethod(env);
+ if (mid_state == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ jobject jstate = env->CallObjectMethod(jstatus, mid_state);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ if (jsubCode != nullptr) {
+ env->DeleteLocalRef(jsubCode);
+ }
+ if (jcode != nullptr) {
+ env->DeleteLocalRef(jcode);
+ }
+ return nullptr;
+ }
+
+ std::unique_ptr<rocksdb::Status> status =
+ toCppStatus(jcode_value, jsub_code_value);
+
+ // delete all local refs
+ if (jstate != nullptr) {
+ env->DeleteLocalRef(jstate);
+ }
+ if (jsubCode != nullptr) {
+ env->DeleteLocalRef(jsubCode);
+ }
+ if (jcode != nullptr) {
+ env->DeleteLocalRef(jcode);
+ }
+
+ return status;
+ }
+};
+
+// The portal class for org.rocksdb.RocksDBException
+class RocksDBExceptionJni :
+ public JavaException<RocksDBExceptionJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.RocksDBException
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaException::getJClass(env, "org/rocksdb/RocksDBException");
+ }
+
+ /**
+ * Create and throw a Java RocksDBException with the provided message
+ *
+ * @param env A pointer to the Java environment
+ * @param msg The message for the exception
+ *
+ * @return true if an exception was thrown, false otherwise
+ */
+ static bool ThrowNew(JNIEnv* env, const std::string& msg) {
+ return JavaException::ThrowNew(env, msg);
+ }
+
+ /**
+ * Create and throw a Java RocksDBException with the provided status
+ *
+ * If s->ok() == true, then this function will not throw any exception.
+ *
+ * @param env A pointer to the Java environment
+ * @param s The status for the exception
+ *
+ * @return true if an exception was thrown, false otherwise
+ */
+ static bool ThrowNew(JNIEnv* env, std::unique_ptr<Status>& s) {
+ return rocksdb::RocksDBExceptionJni::ThrowNew(env, *(s.get()));
+ }
+
+ /**
+ * Create and throw a Java RocksDBException with the provided status
+ *
+ * If s.ok() == true, then this function will not throw any exception.
+ *
+ * @param env A pointer to the Java environment
+ * @param s The status for the exception
+ *
+ * @return true if an exception was thrown, false otherwise
+ */
+ static bool ThrowNew(JNIEnv* env, const Status& s) {
+ if (s.ok()) {
+ return false;
+ }
+
+ // get the RocksDBException class
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ // get the constructor of org.rocksdb.RocksDBException
+ jmethodID mid =
+ env->GetMethodID(jclazz, "<init>", "(Lorg/rocksdb/Status;)V");
+ if(mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ // get the Java status object
+ jobject jstatus = StatusJni::construct(env, s);
+ if(jstatus == nullptr) {
+ // exception occcurred
+ std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ // construct the RocksDBException
+ jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jstatus));
+ if(env->ExceptionCheck()) {
+ if(jstatus != nullptr) {
+ env->DeleteLocalRef(jstatus);
+ }
+ if(rocksdb_exception != nullptr) {
+ env->DeleteLocalRef(rocksdb_exception);
+ }
+ std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
+ return true;
+ }
+
+ // throw the RocksDBException
+ const jint rs = env->Throw(rocksdb_exception);
+ if(rs != JNI_OK) {
+ // exception could not be thrown
+ std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
+ if(jstatus != nullptr) {
+ env->DeleteLocalRef(jstatus);
+ }
+ if(rocksdb_exception != nullptr) {
+ env->DeleteLocalRef(rocksdb_exception);
+ }
+ return env->ExceptionCheck();
+ }
+
+ if(jstatus != nullptr) {
+ env->DeleteLocalRef(jstatus);
+ }
+ if(rocksdb_exception != nullptr) {
+ env->DeleteLocalRef(rocksdb_exception);
+ }
+
+ return true;
+ }
+
+ /**
+ * Create and throw a Java RocksDBException with the provided message
+ * and status
+ *
+ * If s.ok() == true, then this function will not throw any exception.
+ *
+ * @param env A pointer to the Java environment
+ * @param msg The message for the exception
+ * @param s The status for the exception
+ *
+ * @return true if an exception was thrown, false otherwise
+ */
+ static bool ThrowNew(JNIEnv* env, const std::string& msg, const Status& s) {
+ assert(!s.ok());
+ if (s.ok()) {
+ return false;
+ }
+
+ // get the RocksDBException class
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ // get the constructor of org.rocksdb.RocksDBException
+ jmethodID mid =
+ env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;Lorg/rocksdb/Status;)V");
+ if(mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ jstring jmsg = env->NewStringUTF(msg.c_str());
+ if(jmsg == nullptr) {
+ // exception thrown: OutOfMemoryError
+ std::cerr << "RocksDBExceptionJni::ThrowNew/msg - Error: unexpected exception!" << std::endl;
+ return env->ExceptionCheck();
+ }
+
+ // get the Java status object
+ jobject jstatus = StatusJni::construct(env, s);
+ if(jstatus == nullptr) {
+ // exception occcurred
+ std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
+ if(jmsg != nullptr) {
+ env->DeleteLocalRef(jmsg);
+ }
+ return env->ExceptionCheck();
+ }
+
+ // construct the RocksDBException
+ jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jmsg, jstatus));
+ if(env->ExceptionCheck()) {
+ if(jstatus != nullptr) {
+ env->DeleteLocalRef(jstatus);
+ }
+ if(jmsg != nullptr) {
+ env->DeleteLocalRef(jmsg);
+ }
+ if(rocksdb_exception != nullptr) {
+ env->DeleteLocalRef(rocksdb_exception);
+ }
+ std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
+ return true;
+ }
+
+ // throw the RocksDBException
+ const jint rs = env->Throw(rocksdb_exception);
+ if(rs != JNI_OK) {
+ // exception could not be thrown
+ std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
+ if(jstatus != nullptr) {
+ env->DeleteLocalRef(jstatus);
+ }
+ if(jmsg != nullptr) {
+ env->DeleteLocalRef(jmsg);
+ }
+ if(rocksdb_exception != nullptr) {
+ env->DeleteLocalRef(rocksdb_exception);
+ }
+ return env->ExceptionCheck();
+ }
+
+ if(jstatus != nullptr) {
+ env->DeleteLocalRef(jstatus);
+ }
+ if(jmsg != nullptr) {
+ env->DeleteLocalRef(jmsg);
+ }
+ if(rocksdb_exception != nullptr) {
+ env->DeleteLocalRef(rocksdb_exception);
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the Java Method: RocksDBException#getStatus
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getStatusMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "getStatus", "()Lorg/rocksdb/Status;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ static std::unique_ptr<rocksdb::Status> toCppStatus(
+ JNIEnv* env, jthrowable jrocksdb_exception) {
+ if(!env->IsInstanceOf(jrocksdb_exception, getJClass(env))) {
+ // not an instance of RocksDBException
+ return nullptr;
+ }
+
+ // get the java status object
+ jmethodID mid = getStatusMethod(env);
+ if(mid == nullptr) {
+ // exception occurred accessing class or method
+ return nullptr;
+ }
+
+ jobject jstatus = env->CallObjectMethod(jrocksdb_exception, mid);
+ if(env->ExceptionCheck()) {
+ // exception occurred
+ return nullptr;
+ }
+
+ if(jstatus == nullptr) {
+ return nullptr; // no status available
+ }
+
+ return rocksdb::StatusJni::toCppStatus(env, jstatus);
+ }
+};
+
+// The portal class for java.util.List
+class ListJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.util.List
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getListClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/util/List");
+ }
+
+ /**
+ * Get the Java Class java.util.ArrayList
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getArrayListClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/util/ArrayList");
+ }
+
+ /**
+ * Get the Java Class java.util.Iterator
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getIteratorClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/util/Iterator");
+ }
+
+ /**
+ * Get the Java Method: List#iterator
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getIteratorMethod(JNIEnv* env) {
+ jclass jlist_clazz = getListClass(env);
+ if(jlist_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jlist_clazz, "iterator", "()Ljava/util/Iterator;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Iterator#hasNext
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getHasNextMethod(JNIEnv* env) {
+ jclass jiterator_clazz = getIteratorClass(env);
+ if(jiterator_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jiterator_clazz, "hasNext", "()Z");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Iterator#next
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getNextMethod(JNIEnv* env) {
+ jclass jiterator_clazz = getIteratorClass(env);
+ if(jiterator_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jiterator_clazz, "next", "()Ljava/lang/Object;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: ArrayList constructor
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getArrayListConstructorMethodId(JNIEnv* env) {
+ jclass jarray_list_clazz = getArrayListClass(env);
+ if(jarray_list_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+ static jmethodID mid =
+ env->GetMethodID(jarray_list_clazz, "<init>", "(I)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: List#add
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getListAddMethodId(JNIEnv* env) {
+ jclass jlist_clazz = getListClass(env);
+ if(jlist_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jlist_clazz, "add", "(Ljava/lang/Object;)Z");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for java.lang.Byte
+class ByteJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.lang.Byte
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/lang/Byte");
+ }
+
+ /**
+ * Get the Java Class byte[]
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getArrayJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "[B");
+ }
+
+ /**
+ * Creates a new 2-dimensional Java Byte Array byte[][]
+ *
+ * @param env A pointer to the Java environment
+ * @param len The size of the first dimension
+ *
+ * @return A reference to the Java byte[][] or nullptr if an exception occurs
+ */
+ static jobjectArray new2dByteArray(JNIEnv* env, const jsize len) {
+ jclass clazz = getArrayJClass(env);
+ if(clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ return env->NewObjectArray(len, clazz, nullptr);
+ }
+
+ /**
+ * Get the Java Method: Byte#byteValue
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retrieved
+ */
+ static jmethodID getByteValueMethod(JNIEnv* env) {
+ jclass clazz = getJClass(env);
+ if(clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(clazz, "byteValue", "()B");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Calls the Java Method: Byte#valueOf, returning a constructed Byte jobject
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A constructing Byte object or nullptr if the class or method id could not
+ * be retrieved, or an exception occurred
+ */
+ static jobject valueOf(JNIEnv* env, jbyte jprimitive_byte) {
+ jclass clazz = getJClass(env);
+ if (clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetStaticMethodID(clazz, "valueOf", "(B)Ljava/lang/Byte;");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ const jobject jbyte_obj =
+ env->CallStaticObjectMethod(clazz, mid, jprimitive_byte);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jbyte_obj;
+ }
+
+};
+
+// The portal class for java.lang.Integer
+class IntegerJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.lang.Integer
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/lang/Integer");
+ }
+
+ static jobject valueOf(JNIEnv* env, jint jprimitive_int) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid =
+ env->GetStaticMethodID(jclazz, "valueOf", "(I)Ljava/lang/Integer;");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ const jobject jinteger_obj =
+ env->CallStaticObjectMethod(jclazz, mid, jprimitive_int);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jinteger_obj;
+ }
+};
+
+// The portal class for java.lang.Long
+class LongJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.lang.Long
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/lang/Long");
+ }
+
+ static jobject valueOf(JNIEnv* env, jlong jprimitive_long) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid =
+ env->GetStaticMethodID(jclazz, "valueOf", "(J)Ljava/lang/Long;");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ const jobject jlong_obj =
+ env->CallStaticObjectMethod(jclazz, mid, jprimitive_long);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jlong_obj;
+ }
+};
+
+// The portal class for java.lang.StringBuilder
+class StringBuilderJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.lang.StringBuilder
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/lang/StringBuilder");
+ }
+
+ /**
+ * Get the Java Method: StringBuilder#append
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getListAddMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Appends a C-style string to a StringBuilder
+ *
+ * @param env A pointer to the Java environment
+ * @param jstring_builder Reference to a java.lang.StringBuilder
+ * @param c_str A C-style string to append to the StringBuilder
+ *
+ * @return A reference to the updated StringBuilder, or a nullptr if
+ * an exception occurs
+ */
+ static jobject append(JNIEnv* env, jobject jstring_builder,
+ const char* c_str) {
+ jmethodID mid = getListAddMethodId(env);
+ if(mid == nullptr) {
+ // exception occurred accessing class or method
+ return nullptr;
+ }
+
+ jstring new_value_str = env->NewStringUTF(c_str);
+ if(new_value_str == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jobject jresult_string_builder =
+ env->CallObjectMethod(jstring_builder, mid, new_value_str);
+ if(env->ExceptionCheck()) {
+ // exception occurred
+ env->DeleteLocalRef(new_value_str);
+ return nullptr;
+ }
+
+ return jresult_string_builder;
+ }
+};
+
+// various utility functions for working with RocksDB and JNI
+class JniUtil {
+ public:
+ /**
+ * Detect if jlong overflows size_t
+ *
+ * @param jvalue the jlong value
+ *
+ * @return
+ */
+ inline static Status check_if_jlong_fits_size_t(const jlong& jvalue) {
+ Status s = Status::OK();
+ if (static_cast<uint64_t>(jvalue) > std::numeric_limits<size_t>::max()) {
+ s = Status::InvalidArgument(Slice("jlong overflows 32 bit value."));
+ }
+ return s;
+ }
+
+ /**
+ * Obtains a reference to the JNIEnv from
+ * the JVM
+ *
+ * If the current thread is not attached to the JavaVM
+ * then it will be attached so as to retrieve the JNIEnv
+ *
+ * If a thread is attached, it must later be manually
+ * released by calling JavaVM::DetachCurrentThread.
+ * This can be handled by always matching calls to this
+ * function with calls to {@link JniUtil::releaseJniEnv(JavaVM*, jboolean)}
+ *
+ * @param jvm (IN) A pointer to the JavaVM instance
+ * @param attached (OUT) A pointer to a boolean which
+ * will be set to JNI_TRUE if we had to attach the thread
+ *
+ * @return A pointer to the JNIEnv or nullptr if a fatal error
+ * occurs and the JNIEnv cannot be retrieved
+ */
+ static JNIEnv* getJniEnv(JavaVM* jvm, jboolean* attached) {
+ assert(jvm != nullptr);
+
+ JNIEnv *env;
+ const jint env_rs = jvm->GetEnv(reinterpret_cast<void**>(&env),
+ JNI_VERSION_1_2);
+
+ if(env_rs == JNI_OK) {
+ // current thread is already attached, return the JNIEnv
+ *attached = JNI_FALSE;
+ return env;
+ } else if(env_rs == JNI_EDETACHED) {
+ // current thread is not attached, attempt to attach
+ const jint rs_attach = jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);
+ if(rs_attach == JNI_OK) {
+ *attached = JNI_TRUE;
+ return env;
+ } else {
+ // error, could not attach the thread
+ std::cerr << "JniUtil::getJniEnv - Fatal: could not attach current thread to JVM!" << std::endl;
+ return nullptr;
+ }
+ } else if(env_rs == JNI_EVERSION) {
+ // error, JDK does not support JNI_VERSION_1_2+
+ std::cerr << "JniUtil::getJniEnv - Fatal: JDK does not support JNI_VERSION_1_2" << std::endl;
+ return nullptr;
+ } else {
+ std::cerr << "JniUtil::getJniEnv - Fatal: Unknown error: env_rs=" << env_rs << std::endl;
+ return nullptr;
+ }
+ }
+
+ /**
+ * Counterpart to {@link JniUtil::getJniEnv(JavaVM*, jboolean*)}
+ *
+ * Detachess the current thread from the JVM if it was previously
+ * attached
+ *
+ * @param jvm (IN) A pointer to the JavaVM instance
+ * @param attached (IN) JNI_TRUE if we previously had to attach the thread
+ * to the JavaVM to get the JNIEnv
+ */
+ static void releaseJniEnv(JavaVM* jvm, jboolean& attached) {
+ assert(jvm != nullptr);
+ if(attached == JNI_TRUE) {
+ const jint rs_detach = jvm->DetachCurrentThread();
+ assert(rs_detach == JNI_OK);
+ if(rs_detach != JNI_OK) {
+ std::cerr << "JniUtil::getJniEnv - Warn: Unable to detach current thread from JVM!" << std::endl;
+ }
+ }
+ }
+
+ /**
+ * Copies a Java String[] to a C++ std::vector<std::string>
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param jss (IN) The Java String array to copy
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an OutOfMemoryError or ArrayIndexOutOfBoundsException
+ * exception occurs
+ *
+ * @return A std::vector<std:string> containing copies of the Java strings
+ */
+ static std::vector<std::string> copyStrings(JNIEnv* env,
+ jobjectArray jss, jboolean* has_exception) {
+ return rocksdb::JniUtil::copyStrings(env, jss,
+ env->GetArrayLength(jss), has_exception);
+ }
+
+ /**
+ * Copies a Java String[] to a C++ std::vector<std::string>
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param jss (IN) The Java String array to copy
+ * @param jss_len (IN) The length of the Java String array to copy
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an OutOfMemoryError or ArrayIndexOutOfBoundsException
+ * exception occurs
+ *
+ * @return A std::vector<std:string> containing copies of the Java strings
+ */
+ static std::vector<std::string> copyStrings(JNIEnv* env,
+ jobjectArray jss, const jsize jss_len, jboolean* has_exception) {
+ std::vector<std::string> strs;
+ strs.reserve(jss_len);
+ for (jsize i = 0; i < jss_len; i++) {
+ jobject js = env->GetObjectArrayElement(jss, i);
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ *has_exception = JNI_TRUE;
+ return strs;
+ }
+
+ jstring jstr = static_cast<jstring>(js);
+ const char* str = env->GetStringUTFChars(jstr, nullptr);
+ if(str == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(js);
+ *has_exception = JNI_TRUE;
+ return strs;
+ }
+
+ strs.push_back(std::string(str));
+
+ env->ReleaseStringUTFChars(jstr, str);
+ env->DeleteLocalRef(js);
+ }
+
+ *has_exception = JNI_FALSE;
+ return strs;
+ }
+
+ /**
+ * Copies a jstring to a C-style null-terminated byte string
+ * and releases the original jstring
+ *
+ * The jstring is copied as UTF-8
+ *
+ * If an exception occurs, then JNIEnv::ExceptionCheck()
+ * will have been called
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param js (IN) The java string to copy
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an OutOfMemoryError exception occurs
+ *
+ * @return A pointer to the copied string, or a
+ * nullptr if has_exception == JNI_TRUE
+ */
+ static std::unique_ptr<char[]> copyString(JNIEnv* env, jstring js,
+ jboolean* has_exception) {
+ const char *utf = env->GetStringUTFChars(js, nullptr);
+ if(utf == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ExceptionCheck();
+ *has_exception = JNI_TRUE;
+ return nullptr;
+ } else if(env->ExceptionCheck()) {
+ // exception thrown
+ env->ReleaseStringUTFChars(js, utf);
+ *has_exception = JNI_TRUE;
+ return nullptr;
+ }
+
+ const jsize utf_len = env->GetStringUTFLength(js);
+ std::unique_ptr<char[]> str(new char[utf_len + 1]); // Note: + 1 is needed for the c_str null terminator
+ std::strcpy(str.get(), utf);
+ env->ReleaseStringUTFChars(js, utf);
+ *has_exception = JNI_FALSE;
+ return str;
+ }
+
+ /**
+ * Copies a jstring to a std::string
+ * and releases the original jstring
+ *
+ * If an exception occurs, then JNIEnv::ExceptionCheck()
+ * will have been called
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param js (IN) The java string to copy
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an OutOfMemoryError exception occurs
+ *
+ * @return A std:string copy of the jstring, or an
+ * empty std::string if has_exception == JNI_TRUE
+ */
+ static std::string copyStdString(JNIEnv* env, jstring js,
+ jboolean* has_exception) {
+ const char *utf = env->GetStringUTFChars(js, nullptr);
+ if(utf == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ExceptionCheck();
+ *has_exception = JNI_TRUE;
+ return std::string();
+ } else if(env->ExceptionCheck()) {
+ // exception thrown
+ env->ReleaseStringUTFChars(js, utf);
+ *has_exception = JNI_TRUE;
+ return std::string();
+ }
+
+ std::string name(utf);
+ env->ReleaseStringUTFChars(js, utf);
+ *has_exception = JNI_FALSE;
+ return name;
+ }
+
+ /**
+ * Copies bytes from a std::string to a jByteArray
+ *
+ * @param env A pointer to the java environment
+ * @param bytes The bytes to copy
+ *
+ * @return the Java byte[], or nullptr if an exception occurs
+ *
+ * @throws RocksDBException thrown
+ * if memory size to copy exceeds general java specific array size limitation.
+ */
+ static jbyteArray copyBytes(JNIEnv* env, std::string bytes) {
+ return createJavaByteArrayWithSizeCheck(env, bytes.c_str(), bytes.size());
+ }
+
+ /**
+ * Given a Java byte[][] which is an array of java.lang.Strings
+ * where each String is a byte[], the passed function `string_fn`
+ * will be called on each String, the result is the collected by
+ * calling the passed function `collector_fn`
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param jbyte_strings (IN) A Java array of Strings expressed as bytes
+ * @param string_fn (IN) A transform function to call for each String
+ * @param collector_fn (IN) A collector which is called for the result
+ * of each `string_fn`
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an ArrayIndexOutOfBoundsException or OutOfMemoryError
+ * exception occurs
+ */
+ template <typename T> static void byteStrings(JNIEnv* env,
+ jobjectArray jbyte_strings,
+ std::function<T(const char*, const size_t)> string_fn,
+ std::function<void(size_t, T)> collector_fn,
+ jboolean *has_exception) {
+ const jsize jlen = env->GetArrayLength(jbyte_strings);
+
+ for(jsize i = 0; i < jlen; i++) {
+ jobject jbyte_string_obj = env->GetObjectArrayElement(jbyte_strings, i);
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ *has_exception = JNI_TRUE; // signal error
+ return;
+ }
+
+ jbyteArray jbyte_string_ary =
+ reinterpret_cast<jbyteArray>(jbyte_string_obj);
+ T result = byteString(env, jbyte_string_ary, string_fn, has_exception);
+
+ env->DeleteLocalRef(jbyte_string_obj);
+
+ if(*has_exception == JNI_TRUE) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ collector_fn(i, result);
+ }
+
+ *has_exception = JNI_FALSE;
+ }
+
+ /**
+ * Given a Java String which is expressed as a Java Byte Array byte[],
+ * the passed function `string_fn` will be called on the String
+ * and the result returned
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param jbyte_string_ary (IN) A Java String expressed in bytes
+ * @param string_fn (IN) A transform function to call on the String
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an OutOfMemoryError exception occurs
+ */
+ template <typename T> static T byteString(JNIEnv* env,
+ jbyteArray jbyte_string_ary,
+ std::function<T(const char*, const size_t)> string_fn,
+ jboolean* has_exception) {
+ const jsize jbyte_string_len = env->GetArrayLength(jbyte_string_ary);
+ return byteString<T>(env, jbyte_string_ary, jbyte_string_len, string_fn,
+ has_exception);
+ }
+
+ /**
+ * Given a Java String which is expressed as a Java Byte Array byte[],
+ * the passed function `string_fn` will be called on the String
+ * and the result returned
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param jbyte_string_ary (IN) A Java String expressed in bytes
+ * @param jbyte_string_len (IN) The length of the Java String
+ * expressed in bytes
+ * @param string_fn (IN) A transform function to call on the String
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an OutOfMemoryError exception occurs
+ */
+ template <typename T> static T byteString(JNIEnv* env,
+ jbyteArray jbyte_string_ary, const jsize jbyte_string_len,
+ std::function<T(const char*, const size_t)> string_fn,
+ jboolean* has_exception) {
+ jbyte* jbyte_string =
+ env->GetByteArrayElements(jbyte_string_ary, nullptr);
+ if(jbyte_string == nullptr) {
+ // exception thrown: OutOfMemoryError
+ *has_exception = JNI_TRUE;
+ return nullptr; // signal error
+ }
+
+ T result =
+ string_fn(reinterpret_cast<char *>(jbyte_string), jbyte_string_len);
+
+ env->ReleaseByteArrayElements(jbyte_string_ary, jbyte_string, JNI_ABORT);
+
+ *has_exception = JNI_FALSE;
+ return result;
+ }
+
+ /**
+ * Converts a std::vector<string> to a Java byte[][] where each Java String
+ * is expressed as a Java Byte Array byte[].
+ *
+ * @param env A pointer to the java environment
+ * @param strings A vector of Strings
+ *
+ * @return A Java array of Strings expressed as bytes,
+ * or nullptr if an exception is thrown
+ */
+ static jobjectArray stringsBytes(JNIEnv* env, std::vector<std::string> strings) {
+ jclass jcls_ba = ByteJni::getArrayJClass(env);
+ if(jcls_ba == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const jsize len = static_cast<jsize>(strings.size());
+
+ jobjectArray jbyte_strings = env->NewObjectArray(len, jcls_ba, nullptr);
+ if(jbyte_strings == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ for (jsize i = 0; i < len; i++) {
+ std::string *str = &strings[i];
+ const jsize str_len = static_cast<jsize>(str->size());
+
+ jbyteArray jbyte_string_ary = env->NewByteArray(str_len);
+ if(jbyte_string_ary == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jbyte_strings);
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(
+ jbyte_string_ary, 0, str_len,
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(str->c_str())));
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jbyte_string_ary);
+ env->DeleteLocalRef(jbyte_strings);
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(jbyte_strings, i, jbyte_string_ary);
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ // or ArrayStoreException
+ env->DeleteLocalRef(jbyte_string_ary);
+ env->DeleteLocalRef(jbyte_strings);
+ return nullptr;
+ }
+
+ env->DeleteLocalRef(jbyte_string_ary);
+ }
+
+ return jbyte_strings;
+ }
+
+ /**
+ * Converts a std::vector<std::string> to a Java String[].
+ *
+ * @param env A pointer to the java environment
+ * @param strings A vector of Strings
+ *
+ * @return A Java array of Strings,
+ * or nullptr if an exception is thrown
+ */
+ static jobjectArray toJavaStrings(JNIEnv* env,
+ const std::vector<std::string>* strings) {
+ jclass jcls_str = env->FindClass("java/lang/String");
+ if(jcls_str == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const jsize len = static_cast<jsize>(strings->size());
+
+ jobjectArray jstrings = env->NewObjectArray(len, jcls_str, nullptr);
+ if(jstrings == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ for (jsize i = 0; i < len; i++) {
+ const std::string *str = &((*strings)[i]);
+ jstring js = rocksdb::JniUtil::toJavaString(env, str);
+ if (js == nullptr) {
+ env->DeleteLocalRef(jstrings);
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(jstrings, i, js);
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ // or ArrayStoreException
+ env->DeleteLocalRef(js);
+ env->DeleteLocalRef(jstrings);
+ return nullptr;
+ }
+ }
+
+ return jstrings;
+ }
+
+ /**
+ * Creates a Java UTF String from a C++ std::string
+ *
+ * @param env A pointer to the java environment
+ * @param string the C++ std::string
+ * @param treat_empty_as_null true if empty strings should be treated as null
+ *
+ * @return the Java UTF string, or nullptr if the provided string
+ * is null (or empty and treat_empty_as_null is set), or if an
+ * exception occurs allocating the Java String.
+ */
+ static jstring toJavaString(JNIEnv* env, const std::string* string,
+ const bool treat_empty_as_null = false) {
+ if (string == nullptr) {
+ return nullptr;
+ }
+
+ if (treat_empty_as_null && string->empty()) {
+ return nullptr;
+ }
+
+ return env->NewStringUTF(string->c_str());
+ }
+
+ /**
+ * Copies bytes to a new jByteArray with the check of java array size limitation.
+ *
+ * @param bytes pointer to memory to copy to a new jByteArray
+ * @param size number of bytes to copy
+ *
+ * @return the Java byte[], or nullptr if an exception occurs
+ *
+ * @throws RocksDBException thrown
+ * if memory size to copy exceeds general java array size limitation to avoid overflow.
+ */
+ static jbyteArray createJavaByteArrayWithSizeCheck(JNIEnv* env, const char* bytes, const size_t size) {
+ // Limitation for java array size is vm specific
+ // In general it cannot exceed Integer.MAX_VALUE (2^31 - 1)
+ // Current HotSpot VM limitation for array size is Integer.MAX_VALUE - 5 (2^31 - 1 - 5)
+ // It means that the next call to env->NewByteArray can still end with
+ // OutOfMemoryError("Requested array size exceeds VM limit") coming from VM
+ static const size_t MAX_JARRAY_SIZE = (static_cast<size_t>(1)) << 31;
+ if(size > MAX_JARRAY_SIZE) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, "Requested array size exceeds VM limit");
+ return nullptr;
+ }
+
+ const jsize jlen = static_cast<jsize>(size);
+ jbyteArray jbytes = env->NewByteArray(jlen);
+ if(jbytes == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(jbytes, 0, jlen,
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(bytes)));
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jbytes);
+ return nullptr;
+ }
+
+ return jbytes;
+ }
+
+ /**
+ * Copies bytes from a rocksdb::Slice to a jByteArray
+ *
+ * @param env A pointer to the java environment
+ * @param bytes The bytes to copy
+ *
+ * @return the Java byte[] or nullptr if an exception occurs
+ *
+ * @throws RocksDBException thrown
+ * if memory size to copy exceeds general java specific array size limitation.
+ */
+ static jbyteArray copyBytes(JNIEnv* env, const Slice& bytes) {
+ return createJavaByteArrayWithSizeCheck(env, bytes.data(), bytes.size());
+ }
+
+ /*
+ * Helper for operations on a key and value
+ * for example WriteBatch->Put
+ *
+ * TODO(AR) could be used for RocksDB->Put etc.
+ */
+ static std::unique_ptr<rocksdb::Status> kv_op(
+ std::function<rocksdb::Status(rocksdb::Slice, rocksdb::Slice)> op,
+ JNIEnv* env, jobject /*jobj*/,
+ jbyteArray jkey, jint jkey_len,
+ jbyteArray jvalue, jint jvalue_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if(env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jbyte* value = env->GetByteArrayElements(jvalue, nullptr);
+ if(env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ if(key != nullptr) {
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ }
+ return nullptr;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+ rocksdb::Slice value_slice(reinterpret_cast<char*>(value),
+ jvalue_len);
+
+ auto status = op(key_slice, value_slice);
+
+ if(value != nullptr) {
+ env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
+ }
+ if(key != nullptr) {
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ }
+
+ return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(status));
+ }
+
+ /*
+ * Helper for operations on a key
+ * for example WriteBatch->Delete
+ *
+ * TODO(AR) could be used for RocksDB->Delete etc.
+ */
+ static std::unique_ptr<rocksdb::Status> k_op(
+ std::function<rocksdb::Status(rocksdb::Slice)> op,
+ JNIEnv* env, jobject /*jobj*/,
+ jbyteArray jkey, jint jkey_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if(env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ auto status = op(key_slice);
+
+ if(key != nullptr) {
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ }
+
+ return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(status));
+ }
+
+ /*
+ * Helper for operations on a value
+ * for example WriteBatchWithIndex->GetFromBatch
+ */
+ static jbyteArray v_op(
+ std::function<rocksdb::Status(rocksdb::Slice, std::string*)> op,
+ JNIEnv* env, jbyteArray jkey, jint jkey_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if(env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ std::string value;
+ rocksdb::Status s = op(key_slice, &value);
+
+ if(key != nullptr) {
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ }
+
+ if (s.IsNotFound()) {
+ return nullptr;
+ }
+
+ if (s.ok()) {
+ jbyteArray jret_value =
+ env->NewByteArray(static_cast<jsize>(value.size()));
+ if(jret_value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(jret_value, 0, static_cast<jsize>(value.size()),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.c_str())));
+ if(env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ if(jret_value != nullptr) {
+ env->DeleteLocalRef(jret_value);
+ }
+ return nullptr;
+ }
+
+ return jret_value;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ /**
+ * Creates a vector<T*> of C++ pointers from
+ * a Java array of C++ pointer addresses.
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param pointers (IN) A Java array of C++ pointer addresses
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an ArrayIndexOutOfBoundsException or OutOfMemoryError
+ * exception occurs.
+ *
+ * @return A vector of C++ pointers.
+ */
+ template<typename T> static std::vector<T*> fromJPointers(
+ JNIEnv* env, jlongArray jptrs, jboolean *has_exception) {
+ const jsize jptrs_len = env->GetArrayLength(jptrs);
+ std::vector<T*> ptrs;
+ jlong* jptr = env->GetLongArrayElements(jptrs, nullptr);
+ if (jptr == nullptr) {
+ // exception thrown: OutOfMemoryError
+ *has_exception = JNI_TRUE;
+ return ptrs;
+ }
+ ptrs.reserve(jptrs_len);
+ for (jsize i = 0; i < jptrs_len; i++) {
+ ptrs.push_back(reinterpret_cast<T*>(jptr[i]));
+ }
+ env->ReleaseLongArrayElements(jptrs, jptr, JNI_ABORT);
+ return ptrs;
+ }
+
+ /**
+ * Creates a Java array of C++ pointer addresses
+ * from a vector of C++ pointers.
+ *
+ * @param env (IN) A pointer to the java environment
+ * @param pointers (IN) A vector of C++ pointers
+ * @param has_exception (OUT) will be set to JNI_TRUE
+ * if an ArrayIndexOutOfBoundsException or OutOfMemoryError
+ * exception occurs
+ *
+ * @return Java array of C++ pointer addresses.
+ */
+ template<typename T> static jlongArray toJPointers(JNIEnv* env,
+ const std::vector<T*> &pointers,
+ jboolean *has_exception) {
+ const jsize len = static_cast<jsize>(pointers.size());
+ std::unique_ptr<jlong[]> results(new jlong[len]);
+ std::transform(pointers.begin(), pointers.end(), results.get(), [](T* pointer) -> jlong {
+ return reinterpret_cast<jlong>(pointer);
+ });
+
+ jlongArray jpointers = env->NewLongArray(len);
+ if (jpointers == nullptr) {
+ // exception thrown: OutOfMemoryError
+ *has_exception = JNI_TRUE;
+ return nullptr;
+ }
+
+ env->SetLongArrayRegion(jpointers, 0, len, results.get());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ *has_exception = JNI_TRUE;
+ env->DeleteLocalRef(jpointers);
+ return nullptr;
+ }
+
+ *has_exception = JNI_FALSE;
+
+ return jpointers;
+ }
+};
+
+class MapJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.util.Map
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/util/Map");
+ }
+
+ /**
+ * Get the Java Method: Map#put
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMapPutMethodId(JNIEnv* env) {
+ jclass jlist_clazz = getJClass(env);
+ if(jlist_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jlist_clazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+class HashMapJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class java.util.HashMap
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "java/util/HashMap");
+ }
+
+ /**
+ * Create a new Java java.util.HashMap object.
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to a Java java.util.HashMap object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env, const uint32_t initial_capacity = 16) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(I)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jobject jhash_map = env->NewObject(jclazz, mid, static_cast<jint>(initial_capacity));
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jhash_map;
+ }
+
+ /**
+ * A function which maps a std::pair<K,V> to a std::pair<JK, JV>
+ *
+ * @return Either a pointer to a std::pair<jobject, jobject>, or nullptr
+ * if an error occurs during the mapping
+ */
+ template <typename K, typename V, typename JK, typename JV>
+ using FnMapKV = std::function<std::unique_ptr<std::pair<JK, JV>> (const std::pair<K, V>&)>;
+
+ // template <class I, typename K, typename V, typename K1, typename V1, typename std::enable_if<std::is_same<typename std::iterator_traits<I>::value_type, std::pair<const K,V>>::value, int32_t>::type = 0>
+ // static void putAll(JNIEnv* env, const jobject jhash_map, I iterator, const FnMapKV<const K,V,K1,V1> &fn_map_kv) {
+ /**
+ * Returns true if it succeeds, false if an error occurs
+ */
+ template<class iterator_type, typename K, typename V>
+ static bool putAll(JNIEnv* env, const jobject jhash_map, iterator_type iterator, iterator_type end, const FnMapKV<K, V, jobject, jobject> &fn_map_kv) {
+ const jmethodID jmid_put = rocksdb::MapJni::getMapPutMethodId(env);
+ if (jmid_put == nullptr) {
+ return false;
+ }
+
+ for (auto it = iterator; it != end; ++it) {
+ const std::unique_ptr<std::pair<jobject, jobject>> result = fn_map_kv(*it);
+ if (result == nullptr) {
+ // an error occurred during fn_map_kv
+ return false;
+ }
+ env->CallObjectMethod(jhash_map, jmid_put, result->first, result->second);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ env->DeleteLocalRef(result->second);
+ env->DeleteLocalRef(result->first);
+ return false;
+ }
+
+ // release local references
+ env->DeleteLocalRef(result->second);
+ env->DeleteLocalRef(result->first);
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates a java.util.Map<String, String> from a std::map<std::string, std::string>
+ *
+ * @param env A pointer to the Java environment
+ * @param map the Cpp map
+ *
+ * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
+ */
+ static jobject fromCppMap(JNIEnv* env, const std::map<std::string, std::string>* map) {
+ if (map == nullptr) {
+ return nullptr;
+ }
+
+ jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
+ if (jhash_map == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const std::string, const std::string, jobject, jobject> fn_map_kv =
+ [env](const std::pair<const std::string, const std::string>& kv) {
+ jstring jkey = rocksdb::JniUtil::toJavaString(env, &(kv.first), false);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ jstring jvalue = rocksdb::JniUtil::toJavaString(env, &(kv.second), true);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ env->DeleteLocalRef(jkey);
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ return std::unique_ptr<std::pair<jobject, jobject>>(new std::pair<jobject, jobject>(static_cast<jobject>(jkey), static_cast<jobject>(jvalue)));
+ };
+
+ if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jhash_map;
+ }
+
+ /**
+ * Creates a java.util.Map<String, Long> from a std::map<std::string, uint32_t>
+ *
+ * @param env A pointer to the Java environment
+ * @param map the Cpp map
+ *
+ * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
+ */
+ static jobject fromCppMap(JNIEnv* env, const std::map<std::string, uint32_t>* map) {
+ if (map == nullptr) {
+ return nullptr;
+ }
+
+ if (map == nullptr) {
+ return nullptr;
+ }
+
+ jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
+ if (jhash_map == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const std::string, const uint32_t, jobject, jobject> fn_map_kv =
+ [env](const std::pair<const std::string, const uint32_t>& kv) {
+ jstring jkey = rocksdb::JniUtil::toJavaString(env, &(kv.first), false);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ jobject jvalue = rocksdb::IntegerJni::valueOf(env, static_cast<jint>(kv.second));
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ env->DeleteLocalRef(jkey);
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ return std::unique_ptr<std::pair<jobject, jobject>>(new std::pair<jobject, jobject>(static_cast<jobject>(jkey), jvalue));
+ };
+
+ if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jhash_map;
+ }
+
+ /**
+ * Creates a java.util.Map<String, Long> from a std::map<std::string, uint64_t>
+ *
+ * @param env A pointer to the Java environment
+ * @param map the Cpp map
+ *
+ * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
+ */
+ static jobject fromCppMap(JNIEnv* env, const std::map<std::string, uint64_t>* map) {
+ if (map == nullptr) {
+ return nullptr;
+ }
+
+ jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
+ if (jhash_map == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const std::string, const uint64_t, jobject, jobject> fn_map_kv =
+ [env](const std::pair<const std::string, const uint64_t>& kv) {
+ jstring jkey = rocksdb::JniUtil::toJavaString(env, &(kv.first), false);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ jobject jvalue = rocksdb::LongJni::valueOf(env, static_cast<jlong>(kv.second));
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ env->DeleteLocalRef(jkey);
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ return std::unique_ptr<std::pair<jobject, jobject>>(new std::pair<jobject, jobject>(static_cast<jobject>(jkey), jvalue));
+ };
+
+ if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jhash_map;
+ }
+
+ /**
+ * Creates a java.util.Map<String, Long> from a std::map<uint32_t, uint64_t>
+ *
+ * @param env A pointer to the Java environment
+ * @param map the Cpp map
+ *
+ * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
+ */
+ static jobject fromCppMap(JNIEnv* env, const std::map<uint32_t, uint64_t>* map) {
+ if (map == nullptr) {
+ return nullptr;
+ }
+
+ jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
+ if (jhash_map == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const uint32_t, const uint64_t, jobject, jobject> fn_map_kv =
+ [env](const std::pair<const uint32_t, const uint64_t>& kv) {
+ jobject jkey = rocksdb::IntegerJni::valueOf(env, static_cast<jint>(kv.first));
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ jobject jvalue = rocksdb::LongJni::valueOf(env, static_cast<jlong>(kv.second));
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ env->DeleteLocalRef(jkey);
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ return std::unique_ptr<std::pair<jobject, jobject>>(new std::pair<jobject, jobject>(static_cast<jobject>(jkey), jvalue));
+ };
+
+ if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jhash_map;
+ }
+};
+
+// The portal class for org.rocksdb.RocksDB
+class RocksDBJni : public RocksDBNativeClass<rocksdb::DB*, RocksDBJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.RocksDB
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksDB");
+ }
+};
+
+// The portal class for org.rocksdb.Options
+class OptionsJni : public RocksDBNativeClass<
+ rocksdb::Options*, OptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Options
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/Options");
+ }
+};
+
+// The portal class for org.rocksdb.DBOptions
+class DBOptionsJni : public RocksDBNativeClass<
+ rocksdb::DBOptions*, DBOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.DBOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/DBOptions");
+ }
+};
+
+// The portal class for org.rocksdb.ColumnFamilyOptions
+class ColumnFamilyOptionsJni
+ : public RocksDBNativeClass<rocksdb::ColumnFamilyOptions*,
+ ColumnFamilyOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.ColumnFamilyOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/ColumnFamilyOptions");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.ColumnFamilyOptions object with the same
+ * properties as the provided C++ rocksdb::ColumnFamilyOptions object
+ *
+ * @param env A pointer to the Java environment
+ * @param cfoptions A pointer to rocksdb::ColumnFamilyOptions object
+ *
+ * @return A reference to a Java org.rocksdb.ColumnFamilyOptions object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env, const ColumnFamilyOptions* cfoptions) {
+ auto* cfo = new rocksdb::ColumnFamilyOptions(*cfoptions);
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(J)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jobject jcfd = env->NewObject(jclazz, mid, reinterpret_cast<jlong>(cfo));
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jcfd;
+ }
+};
+
+// The portal class for org.rocksdb.WriteOptions
+class WriteOptionsJni : public RocksDBNativeClass<
+ rocksdb::WriteOptions*, WriteOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WriteOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteOptions");
+ }
+};
+
+// The portal class for org.rocksdb.ReadOptions
+class ReadOptionsJni : public RocksDBNativeClass<
+ rocksdb::ReadOptions*, ReadOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.ReadOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/ReadOptions");
+ }
+};
+
+// The portal class for org.rocksdb.WriteBatch
+class WriteBatchJni : public RocksDBNativeClass<
+ rocksdb::WriteBatch*, WriteBatchJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WriteBatch
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteBatch");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.WriteBatch object
+ *
+ * @param env A pointer to the Java environment
+ * @param wb A pointer to rocksdb::WriteBatch object
+ *
+ * @return A reference to a Java org.rocksdb.WriteBatch object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env, const WriteBatch* wb) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(J)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jobject jwb = env->NewObject(jclazz, mid, reinterpret_cast<jlong>(wb));
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jwb;
+ }
+};
+
+// The portal class for org.rocksdb.WriteBatch.Handler
+class WriteBatchHandlerJni : public RocksDBNativeClass<
+ const rocksdb::WriteBatchHandlerJniCallback*,
+ WriteBatchHandlerJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WriteBatch.Handler
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/WriteBatch$Handler");
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#put
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getPutCfMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "put", "(I[B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#put
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getPutMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "put", "([B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#merge
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMergeCfMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "merge", "(I[B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#merge
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMergeMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "merge", "([B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#delete
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getDeleteCfMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "delete", "(I[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#delete
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getDeleteMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "delete", "([B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#singleDelete
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getSingleDeleteCfMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "singleDelete", "(I[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#singleDelete
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getSingleDeleteMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "singleDelete", "([B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#deleteRange
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getDeleteRangeCfMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "(I[B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#deleteRange
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getDeleteRangeMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "([B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#logData
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getLogDataMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "logData", "([B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#putBlobIndex
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getPutBlobIndexCfMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "putBlobIndex", "(I[B[B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#markBeginPrepare
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMarkBeginPrepareMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "markBeginPrepare", "()V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#markEndPrepare
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMarkEndPrepareMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "markEndPrepare", "([B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#markNoop
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMarkNoopMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "markNoop", "(Z)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#markRollback
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMarkRollbackMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "markRollback", "([B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#markCommit
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getMarkCommitMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "markCommit", "([B)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: WriteBatch.Handler#shouldContinue
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getContinueMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "shouldContinue", "()Z");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+class WriteBatchSavePointJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WriteBatch.SavePoint
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/WriteBatch$SavePoint");
+ }
+
+ /**
+ * Get the Java Method: HistogramData constructor
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getConstructorMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JJJ)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Create a new Java org.rocksdb.WriteBatch.SavePoint object
+ *
+ * @param env A pointer to the Java environment
+ * @param savePoint A pointer to rocksdb::WriteBatch::SavePoint object
+ *
+ * @return A reference to a Java org.rocksdb.WriteBatch.SavePoint object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env, const SavePoint &save_point) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = getConstructorMethodId(env);
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jobject jsave_point = env->NewObject(jclazz, mid,
+ static_cast<jlong>(save_point.size),
+ static_cast<jlong>(save_point.count),
+ static_cast<jlong>(save_point.content_flags));
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jsave_point;
+ }
+};
+
+// The portal class for org.rocksdb.WriteBatchWithIndex
+class WriteBatchWithIndexJni : public RocksDBNativeClass<
+ rocksdb::WriteBatchWithIndex*, WriteBatchWithIndexJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WriteBatchWithIndex
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/WriteBatchWithIndex");
+ }
+};
+
+// The portal class for org.rocksdb.HistogramData
+class HistogramDataJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.HistogramData
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/HistogramData");
+ }
+
+ /**
+ * Get the Java Method: HistogramData constructor
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getConstructorMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(DDDDDDJJD)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.BackupableDBOptions
+class BackupableDBOptionsJni : public RocksDBNativeClass<
+ rocksdb::BackupableDBOptions*, BackupableDBOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.BackupableDBOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/BackupableDBOptions");
+ }
+};
+
+// The portal class for org.rocksdb.BackupEngine
+class BackupEngineJni : public RocksDBNativeClass<
+ rocksdb::BackupEngine*, BackupEngineJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.BackupableEngine
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/BackupEngine");
+ }
+};
+
+// The portal class for org.rocksdb.RocksIterator
+class IteratorJni : public RocksDBNativeClass<
+ rocksdb::Iterator*, IteratorJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.RocksIterator
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksIterator");
+ }
+};
+
+// The portal class for org.rocksdb.Filter
+class FilterJni : public RocksDBNativeClass<
+ std::shared_ptr<rocksdb::FilterPolicy>*, FilterJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Filter
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/Filter");
+ }
+};
+
+// The portal class for org.rocksdb.ColumnFamilyHandle
+class ColumnFamilyHandleJni : public RocksDBNativeClass<
+ rocksdb::ColumnFamilyHandle*, ColumnFamilyHandleJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.ColumnFamilyHandle
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/ColumnFamilyHandle");
+ }
+};
+
+// The portal class for org.rocksdb.FlushOptions
+class FlushOptionsJni : public RocksDBNativeClass<
+ rocksdb::FlushOptions*, FlushOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.FlushOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/FlushOptions");
+ }
+};
+
+// The portal class for org.rocksdb.ComparatorOptions
+class ComparatorOptionsJni : public RocksDBNativeClass<
+ rocksdb::ComparatorJniCallbackOptions*, ComparatorOptionsJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.ComparatorOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/ComparatorOptions");
+ }
+};
+
+// The portal class for org.rocksdb.AbstractCompactionFilterFactory
+class AbstractCompactionFilterFactoryJni : public RocksDBNativeClass<
+ const rocksdb::CompactionFilterFactoryJniCallback*,
+ AbstractCompactionFilterFactoryJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.AbstractCompactionFilterFactory
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/AbstractCompactionFilterFactory");
+ }
+
+ /**
+ * Get the Java Method: AbstractCompactionFilterFactory#name
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getNameMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "name", "()Ljava/lang/String;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: AbstractCompactionFilterFactory#createCompactionFilter
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getCreateCompactionFilterMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz,
+ "createCompactionFilter",
+ "(ZZ)J");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.AbstractTransactionNotifier
+class AbstractTransactionNotifierJni : public RocksDBNativeClass<
+ const rocksdb::TransactionNotifierJniCallback*,
+ AbstractTransactionNotifierJni> {
+ public:
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/AbstractTransactionNotifier");
+ }
+
+ // Get the java method `snapshotCreated`
+ // of org.rocksdb.AbstractTransactionNotifier.
+ static jmethodID getSnapshotCreatedMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "snapshotCreated", "(J)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.AbstractComparator
+class AbstractComparatorJni : public RocksDBNativeClass<
+ const rocksdb::BaseComparatorJniCallback*,
+ AbstractComparatorJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.AbstractComparator
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/AbstractComparator");
+ }
+
+ /**
+ * Get the Java Method: Comparator#name
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getNameMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "name", "()Ljava/lang/String;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Comparator#compare
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getCompareMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "compare",
+ "(Lorg/rocksdb/AbstractSlice;Lorg/rocksdb/AbstractSlice;)I");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Comparator#findShortestSeparator
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getFindShortestSeparatorMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "findShortestSeparator",
+ "(Ljava/lang/String;Lorg/rocksdb/AbstractSlice;)Ljava/lang/String;");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: Comparator#findShortSuccessor
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getFindShortSuccessorMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "findShortSuccessor",
+ "(Ljava/lang/String;)Ljava/lang/String;");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.AbstractSlice
+class AbstractSliceJni : public NativeRocksMutableObject<
+ const rocksdb::Slice*, AbstractSliceJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.AbstractSlice
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/AbstractSlice");
+ }
+};
+
+// The portal class for org.rocksdb.Slice
+class SliceJni : public NativeRocksMutableObject<
+ const rocksdb::Slice*, AbstractSliceJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Slice
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/Slice");
+ }
+
+ /**
+ * Constructs a Slice object
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to a Java Slice object, or a nullptr if an
+ * exception occurs
+ */
+ static jobject construct0(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
+ if(mid == nullptr) {
+ // exception occurred accessing method
+ return nullptr;
+ }
+
+ jobject jslice = env->NewObject(jclazz, mid);
+ if(env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jslice;
+ }
+};
+
+// The portal class for org.rocksdb.DirectSlice
+class DirectSliceJni : public NativeRocksMutableObject<
+ const rocksdb::Slice*, AbstractSliceJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.DirectSlice
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/DirectSlice");
+ }
+
+ /**
+ * Constructs a DirectSlice object
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to a Java DirectSlice object, or a nullptr if an
+ * exception occurs
+ */
+ static jobject construct0(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
+ if(mid == nullptr) {
+ // exception occurred accessing method
+ return nullptr;
+ }
+
+ jobject jdirect_slice = env->NewObject(jclazz, mid);
+ if(env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jdirect_slice;
+ }
+};
+
+// The portal class for org.rocksdb.BackupInfo
+class BackupInfoJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.BackupInfo
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/BackupInfo");
+ }
+
+ /**
+ * Constructs a BackupInfo object
+ *
+ * @param env A pointer to the Java environment
+ * @param backup_id id of the backup
+ * @param timestamp timestamp of the backup
+ * @param size size of the backup
+ * @param number_files number of files related to the backup
+ * @param app_metadata application specific metadata
+ *
+ * @return A reference to a Java BackupInfo object, or a nullptr if an
+ * exception occurs
+ */
+ static jobject construct0(JNIEnv* env, uint32_t backup_id, int64_t timestamp,
+ uint64_t size, uint32_t number_files,
+ const std::string& app_metadata) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "<init>", "(IJJILjava/lang/String;)V");
+ if(mid == nullptr) {
+ // exception occurred accessing method
+ return nullptr;
+ }
+
+ jstring japp_metadata = nullptr;
+ if (app_metadata != nullptr) {
+ japp_metadata = env->NewStringUTF(app_metadata.c_str());
+ if (japp_metadata == nullptr) {
+ // exception occurred creating java string
+ return nullptr;
+ }
+ }
+
+ jobject jbackup_info = env->NewObject(jclazz, mid, backup_id, timestamp,
+ size, number_files, japp_metadata);
+ if(env->ExceptionCheck()) {
+ env->DeleteLocalRef(japp_metadata);
+ return nullptr;
+ }
+
+ return jbackup_info;
+ }
+};
+
+class BackupInfoListJni {
+ public:
+ /**
+ * Converts a C++ std::vector<BackupInfo> object to
+ * a Java ArrayList<org.rocksdb.BackupInfo> object
+ *
+ * @param env A pointer to the Java environment
+ * @param backup_infos A vector of BackupInfo
+ *
+ * @return Either a reference to a Java ArrayList object, or a nullptr
+ * if an exception occurs
+ */
+ static jobject getBackupInfo(JNIEnv* env,
+ std::vector<BackupInfo> backup_infos) {
+ jclass jarray_list_clazz = rocksdb::ListJni::getArrayListClass(env);
+ if(jarray_list_clazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID cstr_mid = rocksdb::ListJni::getArrayListConstructorMethodId(env);
+ if(cstr_mid == nullptr) {
+ // exception occurred accessing method
+ return nullptr;
+ }
+
+ jmethodID add_mid = rocksdb::ListJni::getListAddMethodId(env);
+ if(add_mid == nullptr) {
+ // exception occurred accessing method
+ return nullptr;
+ }
+
+ // create java list
+ jobject jbackup_info_handle_list =
+ env->NewObject(jarray_list_clazz, cstr_mid, backup_infos.size());
+ if(env->ExceptionCheck()) {
+ // exception occurred constructing object
+ return nullptr;
+ }
+
+ // insert in java list
+ auto end = backup_infos.end();
+ for (auto it = backup_infos.begin(); it != end; ++it) {
+ auto backup_info = *it;
+
+ jobject obj = rocksdb::BackupInfoJni::construct0(
+ env, backup_info.backup_id, backup_info.timestamp, backup_info.size,
+ backup_info.number_files, backup_info.app_metadata);
+ if(env->ExceptionCheck()) {
+ // exception occurred constructing object
+ if(obj != nullptr) {
+ env->DeleteLocalRef(obj);
+ }
+ if(jbackup_info_handle_list != nullptr) {
+ env->DeleteLocalRef(jbackup_info_handle_list);
+ }
+ return nullptr;
+ }
+
+ jboolean rs =
+ env->CallBooleanMethod(jbackup_info_handle_list, add_mid, obj);
+ if(env->ExceptionCheck() || rs == JNI_FALSE) {
+ // exception occurred calling method, or could not add
+ if(obj != nullptr) {
+ env->DeleteLocalRef(obj);
+ }
+ if(jbackup_info_handle_list != nullptr) {
+ env->DeleteLocalRef(jbackup_info_handle_list);
+ }
+ return nullptr;
+ }
+ }
+
+ return jbackup_info_handle_list;
+ }
+};
+
+// The portal class for org.rocksdb.WBWIRocksIterator
+class WBWIRocksIteratorJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WBWIRocksIterator
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator");
+ }
+
+ /**
+ * Get the Java Field: WBWIRocksIterator#entry
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Field ID or nullptr if the class or field id could not
+ * be retieved
+ */
+ static jfieldID getWriteEntryField(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jfieldID fid =
+ env->GetFieldID(jclazz, "entry",
+ "Lorg/rocksdb/WBWIRocksIterator$WriteEntry;");
+ assert(fid != nullptr);
+ return fid;
+ }
+
+ /**
+ * Gets the value of the WBWIRocksIterator#entry
+ *
+ * @param env A pointer to the Java environment
+ * @param jwbwi_rocks_iterator A reference to a WBWIIterator
+ *
+ * @return A reference to a Java WBWIRocksIterator.WriteEntry object, or
+ * a nullptr if an exception occurs
+ */
+ static jobject getWriteEntry(JNIEnv* env, jobject jwbwi_rocks_iterator) {
+ assert(jwbwi_rocks_iterator != nullptr);
+
+ jfieldID jwrite_entry_field = getWriteEntryField(env);
+ if(jwrite_entry_field == nullptr) {
+ // exception occurred accessing the field
+ return nullptr;
+ }
+
+ jobject jwe = env->GetObjectField(jwbwi_rocks_iterator, jwrite_entry_field);
+ assert(jwe != nullptr);
+ return jwe;
+ }
+};
+
+// The portal class for org.rocksdb.WBWIRocksIterator.WriteType
+class WriteTypeJni : public JavaClass {
+ public:
+ /**
+ * Get the PUT enum field value of WBWIRocksIterator.WriteType
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject PUT(JNIEnv* env) {
+ return getEnum(env, "PUT");
+ }
+
+ /**
+ * Get the MERGE enum field value of WBWIRocksIterator.WriteType
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject MERGE(JNIEnv* env) {
+ return getEnum(env, "MERGE");
+ }
+
+ /**
+ * Get the DELETE enum field value of WBWIRocksIterator.WriteType
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject DELETE(JNIEnv* env) {
+ return getEnum(env, "DELETE");
+ }
+
+ /**
+ * Get the LOG enum field value of WBWIRocksIterator.WriteType
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject LOG(JNIEnv* env) {
+ return getEnum(env, "LOG");
+ }
+
+ // Returns the equivalent org.rocksdb.WBWIRocksIterator.WriteType for the
+ // provided C++ rocksdb::WriteType enum
+ static jbyte toJavaWriteType(const rocksdb::WriteType& writeType) {
+ switch (writeType) {
+ case rocksdb::WriteType::kPutRecord:
+ return 0x0;
+ case rocksdb::WriteType::kMergeRecord:
+ return 0x1;
+ case rocksdb::WriteType::kDeleteRecord:
+ return 0x2;
+ case rocksdb::WriteType::kSingleDeleteRecord:
+ return 0x3;
+ case rocksdb::WriteType::kDeleteRangeRecord:
+ return 0x4;
+ case rocksdb::WriteType::kLogDataRecord:
+ return 0x5;
+ case rocksdb::WriteType::kXIDRecord:
+ return 0x6;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ private:
+ /**
+ * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteType
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteType");
+ }
+
+ /**
+ * Get an enum field of org.rocksdb.WBWIRocksIterator.WriteType
+ *
+ * @param env A pointer to the Java environment
+ * @param name The name of the enum field
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject getEnum(JNIEnv* env, const char name[]) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jfieldID jfid =
+ env->GetStaticFieldID(jclazz, name,
+ "Lorg/rocksdb/WBWIRocksIterator$WriteType;");
+ if(env->ExceptionCheck()) {
+ // exception occurred while getting field
+ return nullptr;
+ } else if(jfid == nullptr) {
+ return nullptr;
+ }
+
+ jobject jwrite_type = env->GetStaticObjectField(jclazz, jfid);
+ assert(jwrite_type != nullptr);
+ return jwrite_type;
+ }
+};
+
+// The portal class for org.rocksdb.WBWIRocksIterator.WriteEntry
+class WriteEntryJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteEntry
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteEntry");
+ }
+};
+
+// The portal class for org.rocksdb.InfoLogLevel
+class InfoLogLevelJni : public JavaClass {
+ public:
+ /**
+ * Get the DEBUG_LEVEL enum field value of InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject DEBUG_LEVEL(JNIEnv* env) {
+ return getEnum(env, "DEBUG_LEVEL");
+ }
+
+ /**
+ * Get the INFO_LEVEL enum field value of InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject INFO_LEVEL(JNIEnv* env) {
+ return getEnum(env, "INFO_LEVEL");
+ }
+
+ /**
+ * Get the WARN_LEVEL enum field value of InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject WARN_LEVEL(JNIEnv* env) {
+ return getEnum(env, "WARN_LEVEL");
+ }
+
+ /**
+ * Get the ERROR_LEVEL enum field value of InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject ERROR_LEVEL(JNIEnv* env) {
+ return getEnum(env, "ERROR_LEVEL");
+ }
+
+ /**
+ * Get the FATAL_LEVEL enum field value of InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject FATAL_LEVEL(JNIEnv* env) {
+ return getEnum(env, "FATAL_LEVEL");
+ }
+
+ /**
+ * Get the HEADER_LEVEL enum field value of InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject HEADER_LEVEL(JNIEnv* env) {
+ return getEnum(env, "HEADER_LEVEL");
+ }
+
+ private:
+ /**
+ * Get the Java Class org.rocksdb.InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/InfoLogLevel");
+ }
+
+ /**
+ * Get an enum field of org.rocksdb.InfoLogLevel
+ *
+ * @param env A pointer to the Java environment
+ * @param name The name of the enum field
+ *
+ * @return A reference to the enum field value or a nullptr if
+ * the enum field value could not be retrieved
+ */
+ static jobject getEnum(JNIEnv* env, const char name[]) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jfieldID jfid =
+ env->GetStaticFieldID(jclazz, name, "Lorg/rocksdb/InfoLogLevel;");
+ if(env->ExceptionCheck()) {
+ // exception occurred while getting field
+ return nullptr;
+ } else if(jfid == nullptr) {
+ return nullptr;
+ }
+
+ jobject jinfo_log_level = env->GetStaticObjectField(jclazz, jfid);
+ assert(jinfo_log_level != nullptr);
+ return jinfo_log_level;
+ }
+};
+
+// The portal class for org.rocksdb.Logger
+class LoggerJni : public RocksDBNativeClass<
+ std::shared_ptr<rocksdb::LoggerJniCallback>*, LoggerJni> {
+ public:
+ /**
+ * Get the Java Class org/rocksdb/Logger
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env, "org/rocksdb/Logger");
+ }
+
+ /**
+ * Get the Java Method: Logger#log
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getLogMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "log",
+ "(Lorg/rocksdb/InfoLogLevel;Ljava/lang/String;)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.TransactionLogIterator.BatchResult
+class BatchResultJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.TransactionLogIterator.BatchResult
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,
+ "org/rocksdb/TransactionLogIterator$BatchResult");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.TransactionLogIterator.BatchResult object
+ * with the same properties as the provided C++ rocksdb::BatchResult object
+ *
+ * @param env A pointer to the Java environment
+ * @param batch_result The rocksdb::BatchResult object
+ *
+ * @return A reference to a Java
+ * org.rocksdb.TransactionLogIterator.BatchResult object,
+ * or nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env,
+ rocksdb::BatchResult& batch_result) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(
+ jclazz, "<init>", "(JJ)V");
+ if(mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jobject jbatch_result = env->NewObject(jclazz, mid,
+ batch_result.sequence, batch_result.writeBatchPtr.get());
+ if(jbatch_result == nullptr) {
+ // exception thrown: InstantiationException or OutOfMemoryError
+ return nullptr;
+ }
+
+ batch_result.writeBatchPtr.release();
+ return jbatch_result;
+ }
+};
+
+// The portal class for org.rocksdb.BottommostLevelCompaction
+class BottommostLevelCompactionJni {
+ public:
+ // Returns the equivalent org.rocksdb.BottommostLevelCompaction for the provided
+ // C++ rocksdb::BottommostLevelCompaction enum
+ static jint toJavaBottommostLevelCompaction(
+ const rocksdb::BottommostLevelCompaction& bottommost_level_compaction) {
+ switch(bottommost_level_compaction) {
+ case rocksdb::BottommostLevelCompaction::kSkip:
+ return 0x0;
+ case rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter:
+ return 0x1;
+ case rocksdb::BottommostLevelCompaction::kForce:
+ return 0x2;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::BottommostLevelCompaction enum for the
+ // provided Java org.rocksdb.BottommostLevelCompaction
+ static rocksdb::BottommostLevelCompaction toCppBottommostLevelCompaction(
+ jint bottommost_level_compaction) {
+ switch(bottommost_level_compaction) {
+ case 0x0:
+ return rocksdb::BottommostLevelCompaction::kSkip;
+ case 0x1:
+ return rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter;
+ case 0x2:
+ return rocksdb::BottommostLevelCompaction::kForce;
+ default:
+ // undefined/default
+ return rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.CompactionStopStyle
+class CompactionStopStyleJni {
+ public:
+ // Returns the equivalent org.rocksdb.CompactionStopStyle for the provided
+ // C++ rocksdb::CompactionStopStyle enum
+ static jbyte toJavaCompactionStopStyle(
+ const rocksdb::CompactionStopStyle& compaction_stop_style) {
+ switch(compaction_stop_style) {
+ case rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize:
+ return 0x0;
+ case rocksdb::CompactionStopStyle::kCompactionStopStyleTotalSize:
+ return 0x1;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::CompactionStopStyle enum for the
+ // provided Java org.rocksdb.CompactionStopStyle
+ static rocksdb::CompactionStopStyle toCppCompactionStopStyle(
+ jbyte jcompaction_stop_style) {
+ switch(jcompaction_stop_style) {
+ case 0x0:
+ return rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize;
+ case 0x1:
+ return rocksdb::CompactionStopStyle::kCompactionStopStyleTotalSize;
+ default:
+ // undefined/default
+ return rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.CompressionType
+class CompressionTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.CompressionType for the provided
+ // C++ rocksdb::CompressionType enum
+ static jbyte toJavaCompressionType(
+ const rocksdb::CompressionType& compression_type) {
+ switch(compression_type) {
+ case rocksdb::CompressionType::kNoCompression:
+ return 0x0;
+ case rocksdb::CompressionType::kSnappyCompression:
+ return 0x1;
+ case rocksdb::CompressionType::kZlibCompression:
+ return 0x2;
+ case rocksdb::CompressionType::kBZip2Compression:
+ return 0x3;
+ case rocksdb::CompressionType::kLZ4Compression:
+ return 0x4;
+ case rocksdb::CompressionType::kLZ4HCCompression:
+ return 0x5;
+ case rocksdb::CompressionType::kXpressCompression:
+ return 0x6;
+ case rocksdb::CompressionType::kZSTD:
+ return 0x7;
+ case rocksdb::CompressionType::kDisableCompressionOption:
+ default:
+ return 0x7F;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::CompressionType enum for the
+ // provided Java org.rocksdb.CompressionType
+ static rocksdb::CompressionType toCppCompressionType(
+ jbyte jcompression_type) {
+ switch(jcompression_type) {
+ case 0x0:
+ return rocksdb::CompressionType::kNoCompression;
+ case 0x1:
+ return rocksdb::CompressionType::kSnappyCompression;
+ case 0x2:
+ return rocksdb::CompressionType::kZlibCompression;
+ case 0x3:
+ return rocksdb::CompressionType::kBZip2Compression;
+ case 0x4:
+ return rocksdb::CompressionType::kLZ4Compression;
+ case 0x5:
+ return rocksdb::CompressionType::kLZ4HCCompression;
+ case 0x6:
+ return rocksdb::CompressionType::kXpressCompression;
+ case 0x7:
+ return rocksdb::CompressionType::kZSTD;
+ case 0x7F:
+ default:
+ return rocksdb::CompressionType::kDisableCompressionOption;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.CompactionPriority
+class CompactionPriorityJni {
+ public:
+ // Returns the equivalent org.rocksdb.CompactionPriority for the provided
+ // C++ rocksdb::CompactionPri enum
+ static jbyte toJavaCompactionPriority(
+ const rocksdb::CompactionPri& compaction_priority) {
+ switch(compaction_priority) {
+ case rocksdb::CompactionPri::kByCompensatedSize:
+ return 0x0;
+ case rocksdb::CompactionPri::kOldestLargestSeqFirst:
+ return 0x1;
+ case rocksdb::CompactionPri::kOldestSmallestSeqFirst:
+ return 0x2;
+ case rocksdb::CompactionPri::kMinOverlappingRatio:
+ return 0x3;
+ default:
+ return 0x0; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::CompactionPri enum for the
+ // provided Java org.rocksdb.CompactionPriority
+ static rocksdb::CompactionPri toCppCompactionPriority(
+ jbyte jcompaction_priority) {
+ switch(jcompaction_priority) {
+ case 0x0:
+ return rocksdb::CompactionPri::kByCompensatedSize;
+ case 0x1:
+ return rocksdb::CompactionPri::kOldestLargestSeqFirst;
+ case 0x2:
+ return rocksdb::CompactionPri::kOldestSmallestSeqFirst;
+ case 0x3:
+ return rocksdb::CompactionPri::kMinOverlappingRatio;
+ default:
+ // undefined/default
+ return rocksdb::CompactionPri::kByCompensatedSize;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.AccessHint
+class AccessHintJni {
+ public:
+ // Returns the equivalent org.rocksdb.AccessHint for the provided
+ // C++ rocksdb::DBOptions::AccessHint enum
+ static jbyte toJavaAccessHint(
+ const rocksdb::DBOptions::AccessHint& access_hint) {
+ switch(access_hint) {
+ case rocksdb::DBOptions::AccessHint::NONE:
+ return 0x0;
+ case rocksdb::DBOptions::AccessHint::NORMAL:
+ return 0x1;
+ case rocksdb::DBOptions::AccessHint::SEQUENTIAL:
+ return 0x2;
+ case rocksdb::DBOptions::AccessHint::WILLNEED:
+ return 0x3;
+ default:
+ // undefined/default
+ return 0x1;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::DBOptions::AccessHint enum for the
+ // provided Java org.rocksdb.AccessHint
+ static rocksdb::DBOptions::AccessHint toCppAccessHint(jbyte jaccess_hint) {
+ switch(jaccess_hint) {
+ case 0x0:
+ return rocksdb::DBOptions::AccessHint::NONE;
+ case 0x1:
+ return rocksdb::DBOptions::AccessHint::NORMAL;
+ case 0x2:
+ return rocksdb::DBOptions::AccessHint::SEQUENTIAL;
+ case 0x3:
+ return rocksdb::DBOptions::AccessHint::WILLNEED;
+ default:
+ // undefined/default
+ return rocksdb::DBOptions::AccessHint::NORMAL;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.WALRecoveryMode
+class WALRecoveryModeJni {
+ public:
+ // Returns the equivalent org.rocksdb.WALRecoveryMode for the provided
+ // C++ rocksdb::WALRecoveryMode enum
+ static jbyte toJavaWALRecoveryMode(
+ const rocksdb::WALRecoveryMode& wal_recovery_mode) {
+ switch(wal_recovery_mode) {
+ case rocksdb::WALRecoveryMode::kTolerateCorruptedTailRecords:
+ return 0x0;
+ case rocksdb::WALRecoveryMode::kAbsoluteConsistency:
+ return 0x1;
+ case rocksdb::WALRecoveryMode::kPointInTimeRecovery:
+ return 0x2;
+ case rocksdb::WALRecoveryMode::kSkipAnyCorruptedRecords:
+ return 0x3;
+ default:
+ // undefined/default
+ return 0x2;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::WALRecoveryMode enum for the
+ // provided Java org.rocksdb.WALRecoveryMode
+ static rocksdb::WALRecoveryMode toCppWALRecoveryMode(jbyte jwal_recovery_mode) {
+ switch(jwal_recovery_mode) {
+ case 0x0:
+ return rocksdb::WALRecoveryMode::kTolerateCorruptedTailRecords;
+ case 0x1:
+ return rocksdb::WALRecoveryMode::kAbsoluteConsistency;
+ case 0x2:
+ return rocksdb::WALRecoveryMode::kPointInTimeRecovery;
+ case 0x3:
+ return rocksdb::WALRecoveryMode::kSkipAnyCorruptedRecords;
+ default:
+ // undefined/default
+ return rocksdb::WALRecoveryMode::kPointInTimeRecovery;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.TickerType
+class TickerTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.TickerType for the provided
+ // C++ rocksdb::Tickers enum
+ static jbyte toJavaTickerType(
+ const rocksdb::Tickers& tickers) {
+ switch(tickers) {
+ case rocksdb::Tickers::BLOCK_CACHE_MISS:
+ return 0x0;
+ case rocksdb::Tickers::BLOCK_CACHE_HIT:
+ return 0x1;
+ case rocksdb::Tickers::BLOCK_CACHE_ADD:
+ return 0x2;
+ case rocksdb::Tickers::BLOCK_CACHE_ADD_FAILURES:
+ return 0x3;
+ case rocksdb::Tickers::BLOCK_CACHE_INDEX_MISS:
+ return 0x4;
+ case rocksdb::Tickers::BLOCK_CACHE_INDEX_HIT:
+ return 0x5;
+ case rocksdb::Tickers::BLOCK_CACHE_INDEX_ADD:
+ return 0x6;
+ case rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_INSERT:
+ return 0x7;
+ case rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_EVICT:
+ return 0x8;
+ case rocksdb::Tickers::BLOCK_CACHE_FILTER_MISS:
+ return 0x9;
+ case rocksdb::Tickers::BLOCK_CACHE_FILTER_HIT:
+ return 0xA;
+ case rocksdb::Tickers::BLOCK_CACHE_FILTER_ADD:
+ return 0xB;
+ case rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_INSERT:
+ return 0xC;
+ case rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_EVICT:
+ return 0xD;
+ case rocksdb::Tickers::BLOCK_CACHE_DATA_MISS:
+ return 0xE;
+ case rocksdb::Tickers::BLOCK_CACHE_DATA_HIT:
+ return 0xF;
+ case rocksdb::Tickers::BLOCK_CACHE_DATA_ADD:
+ return 0x10;
+ case rocksdb::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT:
+ return 0x11;
+ case rocksdb::Tickers::BLOCK_CACHE_BYTES_READ:
+ return 0x12;
+ case rocksdb::Tickers::BLOCK_CACHE_BYTES_WRITE:
+ return 0x13;
+ case rocksdb::Tickers::BLOOM_FILTER_USEFUL:
+ return 0x14;
+ case rocksdb::Tickers::PERSISTENT_CACHE_HIT:
+ return 0x15;
+ case rocksdb::Tickers::PERSISTENT_CACHE_MISS:
+ return 0x16;
+ case rocksdb::Tickers::SIM_BLOCK_CACHE_HIT:
+ return 0x17;
+ case rocksdb::Tickers::SIM_BLOCK_CACHE_MISS:
+ return 0x18;
+ case rocksdb::Tickers::MEMTABLE_HIT:
+ return 0x19;
+ case rocksdb::Tickers::MEMTABLE_MISS:
+ return 0x1A;
+ case rocksdb::Tickers::GET_HIT_L0:
+ return 0x1B;
+ case rocksdb::Tickers::GET_HIT_L1:
+ return 0x1C;
+ case rocksdb::Tickers::GET_HIT_L2_AND_UP:
+ return 0x1D;
+ case rocksdb::Tickers::COMPACTION_KEY_DROP_NEWER_ENTRY:
+ return 0x1E;
+ case rocksdb::Tickers::COMPACTION_KEY_DROP_OBSOLETE:
+ return 0x1F;
+ case rocksdb::Tickers::COMPACTION_KEY_DROP_RANGE_DEL:
+ return 0x20;
+ case rocksdb::Tickers::COMPACTION_KEY_DROP_USER:
+ return 0x21;
+ case rocksdb::Tickers::COMPACTION_RANGE_DEL_DROP_OBSOLETE:
+ return 0x22;
+ case rocksdb::Tickers::NUMBER_KEYS_WRITTEN:
+ return 0x23;
+ case rocksdb::Tickers::NUMBER_KEYS_READ:
+ return 0x24;
+ case rocksdb::Tickers::NUMBER_KEYS_UPDATED:
+ return 0x25;
+ case rocksdb::Tickers::BYTES_WRITTEN:
+ return 0x26;
+ case rocksdb::Tickers::BYTES_READ:
+ return 0x27;
+ case rocksdb::Tickers::NUMBER_DB_SEEK:
+ return 0x28;
+ case rocksdb::Tickers::NUMBER_DB_NEXT:
+ return 0x29;
+ case rocksdb::Tickers::NUMBER_DB_PREV:
+ return 0x2A;
+ case rocksdb::Tickers::NUMBER_DB_SEEK_FOUND:
+ return 0x2B;
+ case rocksdb::Tickers::NUMBER_DB_NEXT_FOUND:
+ return 0x2C;
+ case rocksdb::Tickers::NUMBER_DB_PREV_FOUND:
+ return 0x2D;
+ case rocksdb::Tickers::ITER_BYTES_READ:
+ return 0x2E;
+ case rocksdb::Tickers::NO_FILE_CLOSES:
+ return 0x2F;
+ case rocksdb::Tickers::NO_FILE_OPENS:
+ return 0x30;
+ case rocksdb::Tickers::NO_FILE_ERRORS:
+ return 0x31;
+ case rocksdb::Tickers::STALL_L0_SLOWDOWN_MICROS:
+ return 0x32;
+ case rocksdb::Tickers::STALL_MEMTABLE_COMPACTION_MICROS:
+ return 0x33;
+ case rocksdb::Tickers::STALL_L0_NUM_FILES_MICROS:
+ return 0x34;
+ case rocksdb::Tickers::STALL_MICROS:
+ return 0x35;
+ case rocksdb::Tickers::DB_MUTEX_WAIT_MICROS:
+ return 0x36;
+ case rocksdb::Tickers::RATE_LIMIT_DELAY_MILLIS:
+ return 0x37;
+ case rocksdb::Tickers::NO_ITERATORS:
+ return 0x38;
+ case rocksdb::Tickers::NUMBER_MULTIGET_CALLS:
+ return 0x39;
+ case rocksdb::Tickers::NUMBER_MULTIGET_KEYS_READ:
+ return 0x3A;
+ case rocksdb::Tickers::NUMBER_MULTIGET_BYTES_READ:
+ return 0x3B;
+ case rocksdb::Tickers::NUMBER_FILTERED_DELETES:
+ return 0x3C;
+ case rocksdb::Tickers::NUMBER_MERGE_FAILURES:
+ return 0x3D;
+ case rocksdb::Tickers::BLOOM_FILTER_PREFIX_CHECKED:
+ return 0x3E;
+ case rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL:
+ return 0x3F;
+ case rocksdb::Tickers::NUMBER_OF_RESEEKS_IN_ITERATION:
+ return 0x40;
+ case rocksdb::Tickers::GET_UPDATES_SINCE_CALLS:
+ return 0x41;
+ case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_MISS:
+ return 0x42;
+ case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_HIT:
+ return 0x43;
+ case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD:
+ return 0x44;
+ case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD_FAILURES:
+ return 0x45;
+ case rocksdb::Tickers::WAL_FILE_SYNCED:
+ return 0x46;
+ case rocksdb::Tickers::WAL_FILE_BYTES:
+ return 0x47;
+ case rocksdb::Tickers::WRITE_DONE_BY_SELF:
+ return 0x48;
+ case rocksdb::Tickers::WRITE_DONE_BY_OTHER:
+ return 0x49;
+ case rocksdb::Tickers::WRITE_TIMEDOUT:
+ return 0x4A;
+ case rocksdb::Tickers::WRITE_WITH_WAL:
+ return 0x4B;
+ case rocksdb::Tickers::COMPACT_READ_BYTES:
+ return 0x4C;
+ case rocksdb::Tickers::COMPACT_WRITE_BYTES:
+ return 0x4D;
+ case rocksdb::Tickers::FLUSH_WRITE_BYTES:
+ return 0x4E;
+ case rocksdb::Tickers::NUMBER_DIRECT_LOAD_TABLE_PROPERTIES:
+ return 0x4F;
+ case rocksdb::Tickers::NUMBER_SUPERVERSION_ACQUIRES:
+ return 0x50;
+ case rocksdb::Tickers::NUMBER_SUPERVERSION_RELEASES:
+ return 0x51;
+ case rocksdb::Tickers::NUMBER_SUPERVERSION_CLEANUPS:
+ return 0x52;
+ case rocksdb::Tickers::NUMBER_BLOCK_COMPRESSED:
+ return 0x53;
+ case rocksdb::Tickers::NUMBER_BLOCK_DECOMPRESSED:
+ return 0x54;
+ case rocksdb::Tickers::NUMBER_BLOCK_NOT_COMPRESSED:
+ return 0x55;
+ case rocksdb::Tickers::MERGE_OPERATION_TOTAL_TIME:
+ return 0x56;
+ case rocksdb::Tickers::FILTER_OPERATION_TOTAL_TIME:
+ return 0x57;
+ case rocksdb::Tickers::ROW_CACHE_HIT:
+ return 0x58;
+ case rocksdb::Tickers::ROW_CACHE_MISS:
+ return 0x59;
+ case rocksdb::Tickers::READ_AMP_ESTIMATE_USEFUL_BYTES:
+ return 0x5A;
+ case rocksdb::Tickers::READ_AMP_TOTAL_READ_BYTES:
+ return 0x5B;
+ case rocksdb::Tickers::NUMBER_RATE_LIMITER_DRAINS:
+ return 0x5C;
+ case rocksdb::Tickers::NUMBER_ITER_SKIP:
+ return 0x5D;
+ case rocksdb::Tickers::NUMBER_MULTIGET_KEYS_FOUND:
+ return 0x5E;
+ case rocksdb::Tickers::NO_ITERATOR_CREATED:
+ // -0x01 to fixate the new value that incorrectly changed TICKER_ENUM_MAX.
+ return -0x01;
+ case rocksdb::Tickers::NO_ITERATOR_DELETED:
+ return 0x60;
+ case rocksdb::Tickers::COMPACTION_OPTIMIZED_DEL_DROP_OBSOLETE:
+ return 0x61;
+ case rocksdb::Tickers::COMPACTION_CANCELLED:
+ return 0x62;
+ case rocksdb::Tickers::BLOOM_FILTER_FULL_POSITIVE:
+ return 0x63;
+ case rocksdb::Tickers::BLOOM_FILTER_FULL_TRUE_POSITIVE:
+ return 0x64;
+ case rocksdb::Tickers::BLOB_DB_NUM_PUT:
+ return 0x65;
+ case rocksdb::Tickers::BLOB_DB_NUM_WRITE:
+ return 0x66;
+ case rocksdb::Tickers::BLOB_DB_NUM_GET:
+ return 0x67;
+ case rocksdb::Tickers::BLOB_DB_NUM_MULTIGET:
+ return 0x68;
+ case rocksdb::Tickers::BLOB_DB_NUM_SEEK:
+ return 0x69;
+ case rocksdb::Tickers::BLOB_DB_NUM_NEXT:
+ return 0x6A;
+ case rocksdb::Tickers::BLOB_DB_NUM_PREV:
+ return 0x6B;
+ case rocksdb::Tickers::BLOB_DB_NUM_KEYS_WRITTEN:
+ return 0x6C;
+ case rocksdb::Tickers::BLOB_DB_NUM_KEYS_READ:
+ return 0x6D;
+ case rocksdb::Tickers::BLOB_DB_BYTES_WRITTEN:
+ return 0x6E;
+ case rocksdb::Tickers::BLOB_DB_BYTES_READ:
+ return 0x6F;
+ case rocksdb::Tickers::BLOB_DB_WRITE_INLINED:
+ return 0x70;
+ case rocksdb::Tickers::BLOB_DB_WRITE_INLINED_TTL:
+ return 0x71;
+ case rocksdb::Tickers::BLOB_DB_WRITE_BLOB:
+ return 0x72;
+ case rocksdb::Tickers::BLOB_DB_WRITE_BLOB_TTL:
+ return 0x73;
+ case rocksdb::Tickers::BLOB_DB_BLOB_FILE_BYTES_WRITTEN:
+ return 0x74;
+ case rocksdb::Tickers::BLOB_DB_BLOB_FILE_BYTES_READ:
+ return 0x75;
+ case rocksdb::Tickers::BLOB_DB_BLOB_FILE_SYNCED:
+ return 0x76;
+ case rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_COUNT:
+ return 0x77;
+ case rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_SIZE:
+ return 0x78;
+ case rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_COUNT:
+ return 0x79;
+ case rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_SIZE:
+ return 0x7A;
+ case rocksdb::Tickers::BLOB_DB_GC_NUM_FILES:
+ return 0x7B;
+ case rocksdb::Tickers::BLOB_DB_GC_NUM_NEW_FILES:
+ return 0x7C;
+ case rocksdb::Tickers::BLOB_DB_GC_FAILURES:
+ return 0x7D;
+ case rocksdb::Tickers::BLOB_DB_GC_NUM_KEYS_OVERWRITTEN:
+ return 0x7E;
+ case rocksdb::Tickers::BLOB_DB_GC_NUM_KEYS_EXPIRED:
+ return 0x7F;
+ case rocksdb::Tickers::BLOB_DB_GC_NUM_KEYS_RELOCATED:
+ return -0x02;
+ case rocksdb::Tickers::BLOB_DB_GC_BYTES_OVERWRITTEN:
+ return -0x03;
+ case rocksdb::Tickers::BLOB_DB_GC_BYTES_EXPIRED:
+ return -0x04;
+ case rocksdb::Tickers::BLOB_DB_GC_BYTES_RELOCATED:
+ return -0x05;
+ case rocksdb::Tickers::BLOB_DB_FIFO_NUM_FILES_EVICTED:
+ return -0x06;
+ case rocksdb::Tickers::BLOB_DB_FIFO_NUM_KEYS_EVICTED:
+ return -0x07;
+ case rocksdb::Tickers::BLOB_DB_FIFO_BYTES_EVICTED:
+ return -0x08;
+ case rocksdb::Tickers::TXN_PREPARE_MUTEX_OVERHEAD:
+ return -0x09;
+ case rocksdb::Tickers::TXN_OLD_COMMIT_MAP_MUTEX_OVERHEAD:
+ return -0x0A;
+ case rocksdb::Tickers::TXN_DUPLICATE_KEY_OVERHEAD:
+ return -0x0B;
+ case rocksdb::Tickers::TXN_SNAPSHOT_MUTEX_OVERHEAD:
+ return -0x0C;
+ case rocksdb::Tickers::TICKER_ENUM_MAX:
+ // 0x5F for backwards compatibility on current minor version.
+ return 0x5F;
+ default:
+ // undefined/default
+ return 0x0;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::Tickers enum for the
+ // provided Java org.rocksdb.TickerType
+ static rocksdb::Tickers toCppTickers(jbyte jticker_type) {
+ switch(jticker_type) {
+ case 0x0:
+ return rocksdb::Tickers::BLOCK_CACHE_MISS;
+ case 0x1:
+ return rocksdb::Tickers::BLOCK_CACHE_HIT;
+ case 0x2:
+ return rocksdb::Tickers::BLOCK_CACHE_ADD;
+ case 0x3:
+ return rocksdb::Tickers::BLOCK_CACHE_ADD_FAILURES;
+ case 0x4:
+ return rocksdb::Tickers::BLOCK_CACHE_INDEX_MISS;
+ case 0x5:
+ return rocksdb::Tickers::BLOCK_CACHE_INDEX_HIT;
+ case 0x6:
+ return rocksdb::Tickers::BLOCK_CACHE_INDEX_ADD;
+ case 0x7:
+ return rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_INSERT;
+ case 0x8:
+ return rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_EVICT;
+ case 0x9:
+ return rocksdb::Tickers::BLOCK_CACHE_FILTER_MISS;
+ case 0xA:
+ return rocksdb::Tickers::BLOCK_CACHE_FILTER_HIT;
+ case 0xB:
+ return rocksdb::Tickers::BLOCK_CACHE_FILTER_ADD;
+ case 0xC:
+ return rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_INSERT;
+ case 0xD:
+ return rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_EVICT;
+ case 0xE:
+ return rocksdb::Tickers::BLOCK_CACHE_DATA_MISS;
+ case 0xF:
+ return rocksdb::Tickers::BLOCK_CACHE_DATA_HIT;
+ case 0x10:
+ return rocksdb::Tickers::BLOCK_CACHE_DATA_ADD;
+ case 0x11:
+ return rocksdb::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT;
+ case 0x12:
+ return rocksdb::Tickers::BLOCK_CACHE_BYTES_READ;
+ case 0x13:
+ return rocksdb::Tickers::BLOCK_CACHE_BYTES_WRITE;
+ case 0x14:
+ return rocksdb::Tickers::BLOOM_FILTER_USEFUL;
+ case 0x15:
+ return rocksdb::Tickers::PERSISTENT_CACHE_HIT;
+ case 0x16:
+ return rocksdb::Tickers::PERSISTENT_CACHE_MISS;
+ case 0x17:
+ return rocksdb::Tickers::SIM_BLOCK_CACHE_HIT;
+ case 0x18:
+ return rocksdb::Tickers::SIM_BLOCK_CACHE_MISS;
+ case 0x19:
+ return rocksdb::Tickers::MEMTABLE_HIT;
+ case 0x1A:
+ return rocksdb::Tickers::MEMTABLE_MISS;
+ case 0x1B:
+ return rocksdb::Tickers::GET_HIT_L0;
+ case 0x1C:
+ return rocksdb::Tickers::GET_HIT_L1;
+ case 0x1D:
+ return rocksdb::Tickers::GET_HIT_L2_AND_UP;
+ case 0x1E:
+ return rocksdb::Tickers::COMPACTION_KEY_DROP_NEWER_ENTRY;
+ case 0x1F:
+ return rocksdb::Tickers::COMPACTION_KEY_DROP_OBSOLETE;
+ case 0x20:
+ return rocksdb::Tickers::COMPACTION_KEY_DROP_RANGE_DEL;
+ case 0x21:
+ return rocksdb::Tickers::COMPACTION_KEY_DROP_USER;
+ case 0x22:
+ return rocksdb::Tickers::COMPACTION_RANGE_DEL_DROP_OBSOLETE;
+ case 0x23:
+ return rocksdb::Tickers::NUMBER_KEYS_WRITTEN;
+ case 0x24:
+ return rocksdb::Tickers::NUMBER_KEYS_READ;
+ case 0x25:
+ return rocksdb::Tickers::NUMBER_KEYS_UPDATED;
+ case 0x26:
+ return rocksdb::Tickers::BYTES_WRITTEN;
+ case 0x27:
+ return rocksdb::Tickers::BYTES_READ;
+ case 0x28:
+ return rocksdb::Tickers::NUMBER_DB_SEEK;
+ case 0x29:
+ return rocksdb::Tickers::NUMBER_DB_NEXT;
+ case 0x2A:
+ return rocksdb::Tickers::NUMBER_DB_PREV;
+ case 0x2B:
+ return rocksdb::Tickers::NUMBER_DB_SEEK_FOUND;
+ case 0x2C:
+ return rocksdb::Tickers::NUMBER_DB_NEXT_FOUND;
+ case 0x2D:
+ return rocksdb::Tickers::NUMBER_DB_PREV_FOUND;
+ case 0x2E:
+ return rocksdb::Tickers::ITER_BYTES_READ;
+ case 0x2F:
+ return rocksdb::Tickers::NO_FILE_CLOSES;
+ case 0x30:
+ return rocksdb::Tickers::NO_FILE_OPENS;
+ case 0x31:
+ return rocksdb::Tickers::NO_FILE_ERRORS;
+ case 0x32:
+ return rocksdb::Tickers::STALL_L0_SLOWDOWN_MICROS;
+ case 0x33:
+ return rocksdb::Tickers::STALL_MEMTABLE_COMPACTION_MICROS;
+ case 0x34:
+ return rocksdb::Tickers::STALL_L0_NUM_FILES_MICROS;
+ case 0x35:
+ return rocksdb::Tickers::STALL_MICROS;
+ case 0x36:
+ return rocksdb::Tickers::DB_MUTEX_WAIT_MICROS;
+ case 0x37:
+ return rocksdb::Tickers::RATE_LIMIT_DELAY_MILLIS;
+ case 0x38:
+ return rocksdb::Tickers::NO_ITERATORS;
+ case 0x39:
+ return rocksdb::Tickers::NUMBER_MULTIGET_CALLS;
+ case 0x3A:
+ return rocksdb::Tickers::NUMBER_MULTIGET_KEYS_READ;
+ case 0x3B:
+ return rocksdb::Tickers::NUMBER_MULTIGET_BYTES_READ;
+ case 0x3C:
+ return rocksdb::Tickers::NUMBER_FILTERED_DELETES;
+ case 0x3D:
+ return rocksdb::Tickers::NUMBER_MERGE_FAILURES;
+ case 0x3E:
+ return rocksdb::Tickers::BLOOM_FILTER_PREFIX_CHECKED;
+ case 0x3F:
+ return rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL;
+ case 0x40:
+ return rocksdb::Tickers::NUMBER_OF_RESEEKS_IN_ITERATION;
+ case 0x41:
+ return rocksdb::Tickers::GET_UPDATES_SINCE_CALLS;
+ case 0x42:
+ return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_MISS;
+ case 0x43:
+ return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_HIT;
+ case 0x44:
+ return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD;
+ case 0x45:
+ return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD_FAILURES;
+ case 0x46:
+ return rocksdb::Tickers::WAL_FILE_SYNCED;
+ case 0x47:
+ return rocksdb::Tickers::WAL_FILE_BYTES;
+ case 0x48:
+ return rocksdb::Tickers::WRITE_DONE_BY_SELF;
+ case 0x49:
+ return rocksdb::Tickers::WRITE_DONE_BY_OTHER;
+ case 0x4A:
+ return rocksdb::Tickers::WRITE_TIMEDOUT;
+ case 0x4B:
+ return rocksdb::Tickers::WRITE_WITH_WAL;
+ case 0x4C:
+ return rocksdb::Tickers::COMPACT_READ_BYTES;
+ case 0x4D:
+ return rocksdb::Tickers::COMPACT_WRITE_BYTES;
+ case 0x4E:
+ return rocksdb::Tickers::FLUSH_WRITE_BYTES;
+ case 0x4F:
+ return rocksdb::Tickers::NUMBER_DIRECT_LOAD_TABLE_PROPERTIES;
+ case 0x50:
+ return rocksdb::Tickers::NUMBER_SUPERVERSION_ACQUIRES;
+ case 0x51:
+ return rocksdb::Tickers::NUMBER_SUPERVERSION_RELEASES;
+ case 0x52:
+ return rocksdb::Tickers::NUMBER_SUPERVERSION_CLEANUPS;
+ case 0x53:
+ return rocksdb::Tickers::NUMBER_BLOCK_COMPRESSED;
+ case 0x54:
+ return rocksdb::Tickers::NUMBER_BLOCK_DECOMPRESSED;
+ case 0x55:
+ return rocksdb::Tickers::NUMBER_BLOCK_NOT_COMPRESSED;
+ case 0x56:
+ return rocksdb::Tickers::MERGE_OPERATION_TOTAL_TIME;
+ case 0x57:
+ return rocksdb::Tickers::FILTER_OPERATION_TOTAL_TIME;
+ case 0x58:
+ return rocksdb::Tickers::ROW_CACHE_HIT;
+ case 0x59:
+ return rocksdb::Tickers::ROW_CACHE_MISS;
+ case 0x5A:
+ return rocksdb::Tickers::READ_AMP_ESTIMATE_USEFUL_BYTES;
+ case 0x5B:
+ return rocksdb::Tickers::READ_AMP_TOTAL_READ_BYTES;
+ case 0x5C:
+ return rocksdb::Tickers::NUMBER_RATE_LIMITER_DRAINS;
+ case 0x5D:
+ return rocksdb::Tickers::NUMBER_ITER_SKIP;
+ case 0x5E:
+ return rocksdb::Tickers::NUMBER_MULTIGET_KEYS_FOUND;
+ case -0x01:
+ // -0x01 to fixate the new value that incorrectly changed TICKER_ENUM_MAX.
+ return rocksdb::Tickers::NO_ITERATOR_CREATED;
+ case 0x60:
+ return rocksdb::Tickers::NO_ITERATOR_DELETED;
+ case 0x61:
+ return rocksdb::Tickers::COMPACTION_OPTIMIZED_DEL_DROP_OBSOLETE;
+ case 0x62:
+ return rocksdb::Tickers::COMPACTION_CANCELLED;
+ case 0x63:
+ return rocksdb::Tickers::BLOOM_FILTER_FULL_POSITIVE;
+ case 0x64:
+ return rocksdb::Tickers::BLOOM_FILTER_FULL_TRUE_POSITIVE;
+ case 0x65:
+ return rocksdb::Tickers::BLOB_DB_NUM_PUT;
+ case 0x66:
+ return rocksdb::Tickers::BLOB_DB_NUM_WRITE;
+ case 0x67:
+ return rocksdb::Tickers::BLOB_DB_NUM_GET;
+ case 0x68:
+ return rocksdb::Tickers::BLOB_DB_NUM_MULTIGET;
+ case 0x69:
+ return rocksdb::Tickers::BLOB_DB_NUM_SEEK;
+ case 0x6A:
+ return rocksdb::Tickers::BLOB_DB_NUM_NEXT;
+ case 0x6B:
+ return rocksdb::Tickers::BLOB_DB_NUM_PREV;
+ case 0x6C:
+ return rocksdb::Tickers::BLOB_DB_NUM_KEYS_WRITTEN;
+ case 0x6D:
+ return rocksdb::Tickers::BLOB_DB_NUM_KEYS_READ;
+ case 0x6E:
+ return rocksdb::Tickers::BLOB_DB_BYTES_WRITTEN;
+ case 0x6F:
+ return rocksdb::Tickers::BLOB_DB_BYTES_READ;
+ case 0x70:
+ return rocksdb::Tickers::BLOB_DB_WRITE_INLINED;
+ case 0x71:
+ return rocksdb::Tickers::BLOB_DB_WRITE_INLINED_TTL;
+ case 0x72:
+ return rocksdb::Tickers::BLOB_DB_WRITE_BLOB;
+ case 0x73:
+ return rocksdb::Tickers::BLOB_DB_WRITE_BLOB_TTL;
+ case 0x74:
+ return rocksdb::Tickers::BLOB_DB_BLOB_FILE_BYTES_WRITTEN;
+ case 0x75:
+ return rocksdb::Tickers::BLOB_DB_BLOB_FILE_BYTES_READ;
+ case 0x76:
+ return rocksdb::Tickers::BLOB_DB_BLOB_FILE_SYNCED;
+ case 0x77:
+ return rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_COUNT;
+ case 0x78:
+ return rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_SIZE;
+ case 0x79:
+ return rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_COUNT;
+ case 0x7A:
+ return rocksdb::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_SIZE;
+ case 0x7B:
+ return rocksdb::Tickers::BLOB_DB_GC_NUM_FILES;
+ case 0x7C:
+ return rocksdb::Tickers::BLOB_DB_GC_NUM_NEW_FILES;
+ case 0x7D:
+ return rocksdb::Tickers::BLOB_DB_GC_FAILURES;
+ case 0x7E:
+ return rocksdb::Tickers::BLOB_DB_GC_NUM_KEYS_OVERWRITTEN;
+ case 0x7F:
+ return rocksdb::Tickers::BLOB_DB_GC_NUM_KEYS_EXPIRED;
+ case -0x02:
+ return rocksdb::Tickers::BLOB_DB_GC_NUM_KEYS_RELOCATED;
+ case -0x03:
+ return rocksdb::Tickers::BLOB_DB_GC_BYTES_OVERWRITTEN;
+ case -0x04:
+ return rocksdb::Tickers::BLOB_DB_GC_BYTES_EXPIRED;
+ case -0x05:
+ return rocksdb::Tickers::BLOB_DB_GC_BYTES_RELOCATED;
+ case -0x06:
+ return rocksdb::Tickers::BLOB_DB_FIFO_NUM_FILES_EVICTED;
+ case -0x07:
+ return rocksdb::Tickers::BLOB_DB_FIFO_NUM_KEYS_EVICTED;
+ case -0x08:
+ return rocksdb::Tickers::BLOB_DB_FIFO_BYTES_EVICTED;
+ case -0x09:
+ return rocksdb::Tickers::TXN_PREPARE_MUTEX_OVERHEAD;
+ case -0x0A:
+ return rocksdb::Tickers::TXN_OLD_COMMIT_MAP_MUTEX_OVERHEAD;
+ case -0x0B:
+ return rocksdb::Tickers::TXN_DUPLICATE_KEY_OVERHEAD;
+ case -0x0C:
+ return rocksdb::Tickers::TXN_SNAPSHOT_MUTEX_OVERHEAD;
+ case 0x5F:
+ // 0x5F for backwards compatibility on current minor version.
+ return rocksdb::Tickers::TICKER_ENUM_MAX;
+
+ default:
+ // undefined/default
+ return rocksdb::Tickers::BLOCK_CACHE_MISS;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.HistogramType
+class HistogramTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.HistogramType for the provided
+ // C++ rocksdb::Histograms enum
+ static jbyte toJavaHistogramsType(
+ const rocksdb::Histograms& histograms) {
+ switch(histograms) {
+ case rocksdb::Histograms::DB_GET:
+ return 0x0;
+ case rocksdb::Histograms::DB_WRITE:
+ return 0x1;
+ case rocksdb::Histograms::COMPACTION_TIME:
+ return 0x2;
+ case rocksdb::Histograms::SUBCOMPACTION_SETUP_TIME:
+ return 0x3;
+ case rocksdb::Histograms::TABLE_SYNC_MICROS:
+ return 0x4;
+ case rocksdb::Histograms::COMPACTION_OUTFILE_SYNC_MICROS:
+ return 0x5;
+ case rocksdb::Histograms::WAL_FILE_SYNC_MICROS:
+ return 0x6;
+ case rocksdb::Histograms::MANIFEST_FILE_SYNC_MICROS:
+ return 0x7;
+ case rocksdb::Histograms::TABLE_OPEN_IO_MICROS:
+ return 0x8;
+ case rocksdb::Histograms::DB_MULTIGET:
+ return 0x9;
+ case rocksdb::Histograms::READ_BLOCK_COMPACTION_MICROS:
+ return 0xA;
+ case rocksdb::Histograms::READ_BLOCK_GET_MICROS:
+ return 0xB;
+ case rocksdb::Histograms::WRITE_RAW_BLOCK_MICROS:
+ return 0xC;
+ case rocksdb::Histograms::STALL_L0_SLOWDOWN_COUNT:
+ return 0xD;
+ case rocksdb::Histograms::STALL_MEMTABLE_COMPACTION_COUNT:
+ return 0xE;
+ case rocksdb::Histograms::STALL_L0_NUM_FILES_COUNT:
+ return 0xF;
+ case rocksdb::Histograms::HARD_RATE_LIMIT_DELAY_COUNT:
+ return 0x10;
+ case rocksdb::Histograms::SOFT_RATE_LIMIT_DELAY_COUNT:
+ return 0x11;
+ case rocksdb::Histograms::NUM_FILES_IN_SINGLE_COMPACTION:
+ return 0x12;
+ case rocksdb::Histograms::DB_SEEK:
+ return 0x13;
+ case rocksdb::Histograms::WRITE_STALL:
+ return 0x14;
+ case rocksdb::Histograms::SST_READ_MICROS:
+ return 0x15;
+ case rocksdb::Histograms::NUM_SUBCOMPACTIONS_SCHEDULED:
+ return 0x16;
+ case rocksdb::Histograms::BYTES_PER_READ:
+ return 0x17;
+ case rocksdb::Histograms::BYTES_PER_WRITE:
+ return 0x18;
+ case rocksdb::Histograms::BYTES_PER_MULTIGET:
+ return 0x19;
+ case rocksdb::Histograms::BYTES_COMPRESSED:
+ return 0x1A;
+ case rocksdb::Histograms::BYTES_DECOMPRESSED:
+ return 0x1B;
+ case rocksdb::Histograms::COMPRESSION_TIMES_NANOS:
+ return 0x1C;
+ case rocksdb::Histograms::DECOMPRESSION_TIMES_NANOS:
+ return 0x1D;
+ case rocksdb::Histograms::READ_NUM_MERGE_OPERANDS:
+ return 0x1E;
+ // 0x20 to skip 0x1F so TICKER_ENUM_MAX remains unchanged for minor version compatibility.
+ case rocksdb::Histograms::FLUSH_TIME:
+ return 0x20;
+ case rocksdb::Histograms::BLOB_DB_KEY_SIZE:
+ return 0x21;
+ case rocksdb::Histograms::BLOB_DB_VALUE_SIZE:
+ return 0x22;
+ case rocksdb::Histograms::BLOB_DB_WRITE_MICROS:
+ return 0x23;
+ case rocksdb::Histograms::BLOB_DB_GET_MICROS:
+ return 0x24;
+ case rocksdb::Histograms::BLOB_DB_MULTIGET_MICROS:
+ return 0x25;
+ case rocksdb::Histograms::BLOB_DB_SEEK_MICROS:
+ return 0x26;
+ case rocksdb::Histograms::BLOB_DB_NEXT_MICROS:
+ return 0x27;
+ case rocksdb::Histograms::BLOB_DB_PREV_MICROS:
+ return 0x28;
+ case rocksdb::Histograms::BLOB_DB_BLOB_FILE_WRITE_MICROS:
+ return 0x29;
+ case rocksdb::Histograms::BLOB_DB_BLOB_FILE_READ_MICROS:
+ return 0x2A;
+ case rocksdb::Histograms::BLOB_DB_BLOB_FILE_SYNC_MICROS:
+ return 0x2B;
+ case rocksdb::Histograms::BLOB_DB_GC_MICROS:
+ return 0x2C;
+ case rocksdb::Histograms::BLOB_DB_COMPRESSION_MICROS:
+ return 0x2D;
+ case rocksdb::Histograms::BLOB_DB_DECOMPRESSION_MICROS:
+ return 0x2E;
+ case rocksdb::Histograms::HISTOGRAM_ENUM_MAX:
+ // 0x1F for backwards compatibility on current minor version.
+ return 0x1F;
+
+ default:
+ // undefined/default
+ return 0x0;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::Histograms enum for the
+ // provided Java org.rocksdb.HistogramsType
+ static rocksdb::Histograms toCppHistograms(jbyte jhistograms_type) {
+ switch(jhistograms_type) {
+ case 0x0:
+ return rocksdb::Histograms::DB_GET;
+ case 0x1:
+ return rocksdb::Histograms::DB_WRITE;
+ case 0x2:
+ return rocksdb::Histograms::COMPACTION_TIME;
+ case 0x3:
+ return rocksdb::Histograms::SUBCOMPACTION_SETUP_TIME;
+ case 0x4:
+ return rocksdb::Histograms::TABLE_SYNC_MICROS;
+ case 0x5:
+ return rocksdb::Histograms::COMPACTION_OUTFILE_SYNC_MICROS;
+ case 0x6:
+ return rocksdb::Histograms::WAL_FILE_SYNC_MICROS;
+ case 0x7:
+ return rocksdb::Histograms::MANIFEST_FILE_SYNC_MICROS;
+ case 0x8:
+ return rocksdb::Histograms::TABLE_OPEN_IO_MICROS;
+ case 0x9:
+ return rocksdb::Histograms::DB_MULTIGET;
+ case 0xA:
+ return rocksdb::Histograms::READ_BLOCK_COMPACTION_MICROS;
+ case 0xB:
+ return rocksdb::Histograms::READ_BLOCK_GET_MICROS;
+ case 0xC:
+ return rocksdb::Histograms::WRITE_RAW_BLOCK_MICROS;
+ case 0xD:
+ return rocksdb::Histograms::STALL_L0_SLOWDOWN_COUNT;
+ case 0xE:
+ return rocksdb::Histograms::STALL_MEMTABLE_COMPACTION_COUNT;
+ case 0xF:
+ return rocksdb::Histograms::STALL_L0_NUM_FILES_COUNT;
+ case 0x10:
+ return rocksdb::Histograms::HARD_RATE_LIMIT_DELAY_COUNT;
+ case 0x11:
+ return rocksdb::Histograms::SOFT_RATE_LIMIT_DELAY_COUNT;
+ case 0x12:
+ return rocksdb::Histograms::NUM_FILES_IN_SINGLE_COMPACTION;
+ case 0x13:
+ return rocksdb::Histograms::DB_SEEK;
+ case 0x14:
+ return rocksdb::Histograms::WRITE_STALL;
+ case 0x15:
+ return rocksdb::Histograms::SST_READ_MICROS;
+ case 0x16:
+ return rocksdb::Histograms::NUM_SUBCOMPACTIONS_SCHEDULED;
+ case 0x17:
+ return rocksdb::Histograms::BYTES_PER_READ;
+ case 0x18:
+ return rocksdb::Histograms::BYTES_PER_WRITE;
+ case 0x19:
+ return rocksdb::Histograms::BYTES_PER_MULTIGET;
+ case 0x1A:
+ return rocksdb::Histograms::BYTES_COMPRESSED;
+ case 0x1B:
+ return rocksdb::Histograms::BYTES_DECOMPRESSED;
+ case 0x1C:
+ return rocksdb::Histograms::COMPRESSION_TIMES_NANOS;
+ case 0x1D:
+ return rocksdb::Histograms::DECOMPRESSION_TIMES_NANOS;
+ case 0x1E:
+ return rocksdb::Histograms::READ_NUM_MERGE_OPERANDS;
+ // 0x20 to skip 0x1F so TICKER_ENUM_MAX remains unchanged for minor version compatibility.
+ case 0x20:
+ return rocksdb::Histograms::FLUSH_TIME;
+ case 0x21:
+ return rocksdb::Histograms::BLOB_DB_KEY_SIZE;
+ case 0x22:
+ return rocksdb::Histograms::BLOB_DB_VALUE_SIZE;
+ case 0x23:
+ return rocksdb::Histograms::BLOB_DB_WRITE_MICROS;
+ case 0x24:
+ return rocksdb::Histograms::BLOB_DB_GET_MICROS;
+ case 0x25:
+ return rocksdb::Histograms::BLOB_DB_MULTIGET_MICROS;
+ case 0x26:
+ return rocksdb::Histograms::BLOB_DB_SEEK_MICROS;
+ case 0x27:
+ return rocksdb::Histograms::BLOB_DB_NEXT_MICROS;
+ case 0x28:
+ return rocksdb::Histograms::BLOB_DB_PREV_MICROS;
+ case 0x29:
+ return rocksdb::Histograms::BLOB_DB_BLOB_FILE_WRITE_MICROS;
+ case 0x2A:
+ return rocksdb::Histograms::BLOB_DB_BLOB_FILE_READ_MICROS;
+ case 0x2B:
+ return rocksdb::Histograms::BLOB_DB_BLOB_FILE_SYNC_MICROS;
+ case 0x2C:
+ return rocksdb::Histograms::BLOB_DB_GC_MICROS;
+ case 0x2D:
+ return rocksdb::Histograms::BLOB_DB_COMPRESSION_MICROS;
+ case 0x2E:
+ return rocksdb::Histograms::BLOB_DB_DECOMPRESSION_MICROS;
+ case 0x1F:
+ // 0x1F for backwards compatibility on current minor version.
+ return rocksdb::Histograms::HISTOGRAM_ENUM_MAX;
+
+ default:
+ // undefined/default
+ return rocksdb::Histograms::DB_GET;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.StatsLevel
+class StatsLevelJni {
+ public:
+ // Returns the equivalent org.rocksdb.StatsLevel for the provided
+ // C++ rocksdb::StatsLevel enum
+ static jbyte toJavaStatsLevel(
+ const rocksdb::StatsLevel& stats_level) {
+ switch(stats_level) {
+ case rocksdb::StatsLevel::kExceptDetailedTimers:
+ return 0x0;
+ case rocksdb::StatsLevel::kExceptTimeForMutex:
+ return 0x1;
+ case rocksdb::StatsLevel::kAll:
+ return 0x2;
+
+ default:
+ // undefined/default
+ return 0x0;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::StatsLevel enum for the
+ // provided Java org.rocksdb.StatsLevel
+ static rocksdb::StatsLevel toCppStatsLevel(jbyte jstats_level) {
+ switch(jstats_level) {
+ case 0x0:
+ return rocksdb::StatsLevel::kExceptDetailedTimers;
+ case 0x1:
+ return rocksdb::StatsLevel::kExceptTimeForMutex;
+ case 0x2:
+ return rocksdb::StatsLevel::kAll;
+
+ default:
+ // undefined/default
+ return rocksdb::StatsLevel::kExceptDetailedTimers;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.RateLimiterMode
+class RateLimiterModeJni {
+ public:
+ // Returns the equivalent org.rocksdb.RateLimiterMode for the provided
+ // C++ rocksdb::RateLimiter::Mode enum
+ static jbyte toJavaRateLimiterMode(
+ const rocksdb::RateLimiter::Mode& rate_limiter_mode) {
+ switch(rate_limiter_mode) {
+ case rocksdb::RateLimiter::Mode::kReadsOnly:
+ return 0x0;
+ case rocksdb::RateLimiter::Mode::kWritesOnly:
+ return 0x1;
+ case rocksdb::RateLimiter::Mode::kAllIo:
+ return 0x2;
+
+ default:
+ // undefined/default
+ return 0x1;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::RateLimiter::Mode enum for the
+ // provided Java org.rocksdb.RateLimiterMode
+ static rocksdb::RateLimiter::Mode toCppRateLimiterMode(jbyte jrate_limiter_mode) {
+ switch(jrate_limiter_mode) {
+ case 0x0:
+ return rocksdb::RateLimiter::Mode::kReadsOnly;
+ case 0x1:
+ return rocksdb::RateLimiter::Mode::kWritesOnly;
+ case 0x2:
+ return rocksdb::RateLimiter::Mode::kAllIo;
+
+ default:
+ // undefined/default
+ return rocksdb::RateLimiter::Mode::kWritesOnly;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.MemoryUsageType
+class MemoryUsageTypeJni {
+public:
+ // Returns the equivalent org.rocksdb.MemoryUsageType for the provided
+ // C++ rocksdb::MemoryUtil::UsageType enum
+ static jbyte toJavaMemoryUsageType(
+ const rocksdb::MemoryUtil::UsageType& usage_type) {
+ switch(usage_type) {
+ case rocksdb::MemoryUtil::UsageType::kMemTableTotal:
+ return 0x0;
+ case rocksdb::MemoryUtil::UsageType::kMemTableUnFlushed:
+ return 0x1;
+ case rocksdb::MemoryUtil::UsageType::kTableReadersTotal:
+ return 0x2;
+ case rocksdb::MemoryUtil::UsageType::kCacheTotal:
+ return 0x3;
+ default:
+ // undefined: use kNumUsageTypes
+ return 0x4;
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::MemoryUtil::UsageType enum for the
+ // provided Java org.rocksdb.MemoryUsageType
+ static rocksdb::MemoryUtil::UsageType toCppMemoryUsageType(
+ jbyte usage_type) {
+ switch(usage_type) {
+ case 0x0:
+ return rocksdb::MemoryUtil::UsageType::kMemTableTotal;
+ case 0x1:
+ return rocksdb::MemoryUtil::UsageType::kMemTableUnFlushed;
+ case 0x2:
+ return rocksdb::MemoryUtil::UsageType::kTableReadersTotal;
+ case 0x3:
+ return rocksdb::MemoryUtil::UsageType::kCacheTotal;
+ default:
+ // undefined/default: use kNumUsageTypes
+ return rocksdb::MemoryUtil::UsageType::kNumUsageTypes;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.Transaction
+class TransactionJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.Transaction
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,
+ "org/rocksdb/Transaction");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.Transaction.WaitingTransactions object
+ *
+ * @param env A pointer to the Java environment
+ * @param jtransaction A Java org.rocksdb.Transaction object
+ * @param column_family_id The id of the column family
+ * @param key The key
+ * @param transaction_ids The transaction ids
+ *
+ * @return A reference to a Java
+ * org.rocksdb.Transaction.WaitingTransactions object,
+ * or nullptr if an an exception occurs
+ */
+ static jobject newWaitingTransactions(JNIEnv* env, jobject jtransaction,
+ const uint32_t column_family_id, const std::string &key,
+ const std::vector<TransactionID> &transaction_ids) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(
+ jclazz, "newWaitingTransactions", "(JLjava/lang/String;[J)Lorg/rocksdb/Transaction$WaitingTransactions;");
+ if(mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jstring jkey = env->NewStringUTF(key.c_str());
+ if(jkey == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ const size_t len = transaction_ids.size();
+ jlongArray jtransaction_ids = env->NewLongArray(static_cast<jsize>(len));
+ if(jtransaction_ids == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jkey);
+ return nullptr;
+ }
+
+ jlong *body = env->GetLongArrayElements(jtransaction_ids, nullptr);
+ if(body == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jkey);
+ env->DeleteLocalRef(jtransaction_ids);
+ return nullptr;
+ }
+ for(size_t i = 0; i < len; ++i) {
+ body[i] = static_cast<jlong>(transaction_ids[i]);
+ }
+ env->ReleaseLongArrayElements(jtransaction_ids, body, 0);
+
+ jobject jwaiting_transactions = env->CallObjectMethod(jtransaction,
+ mid, static_cast<jlong>(column_family_id), jkey, jtransaction_ids);
+ if(env->ExceptionCheck()) {
+ // exception thrown: InstantiationException or OutOfMemoryError
+ env->DeleteLocalRef(jkey);
+ env->DeleteLocalRef(jtransaction_ids);
+ return nullptr;
+ }
+
+ return jwaiting_transactions;
+ }
+};
+
+// The portal class for org.rocksdb.TransactionDB
+class TransactionDBJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.TransactionDB
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,
+ "org/rocksdb/TransactionDB");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.TransactionDB.DeadlockInfo object
+ *
+ * @param env A pointer to the Java environment
+ * @param jtransaction A Java org.rocksdb.Transaction object
+ * @param column_family_id The id of the column family
+ * @param key The key
+ * @param transaction_ids The transaction ids
+ *
+ * @return A reference to a Java
+ * org.rocksdb.Transaction.WaitingTransactions object,
+ * or nullptr if an an exception occurs
+ */
+ static jobject newDeadlockInfo(JNIEnv* env, jobject jtransaction_db,
+ const rocksdb::TransactionID transaction_id,
+ const uint32_t column_family_id, const std::string &waiting_key,
+ const bool exclusive) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(
+ jclazz, "newDeadlockInfo", "(JJLjava/lang/String;Z)Lorg/rocksdb/TransactionDB$DeadlockInfo;");
+ if(mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jstring jwaiting_key = env->NewStringUTF(waiting_key.c_str());
+ if(jwaiting_key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ // resolve the column family id to a ColumnFamilyHandle
+ jobject jdeadlock_info = env->CallObjectMethod(jtransaction_db,
+ mid, transaction_id, static_cast<jlong>(column_family_id),
+ jwaiting_key, exclusive);
+ if(env->ExceptionCheck()) {
+ // exception thrown: InstantiationException or OutOfMemoryError
+ env->DeleteLocalRef(jwaiting_key);
+ return nullptr;
+ }
+
+ return jdeadlock_info;
+ }
+};
+
+// The portal class for org.rocksdb.TxnDBWritePolicy
+class TxnDBWritePolicyJni {
+ public:
+ // Returns the equivalent org.rocksdb.TxnDBWritePolicy for the provided
+ // C++ rocksdb::TxnDBWritePolicy enum
+ static jbyte toJavaTxnDBWritePolicy(
+ const rocksdb::TxnDBWritePolicy& txndb_write_policy) {
+ switch(txndb_write_policy) {
+ case rocksdb::TxnDBWritePolicy::WRITE_COMMITTED:
+ return 0x0;
+ case rocksdb::TxnDBWritePolicy::WRITE_PREPARED:
+ return 0x1;
+ case rocksdb::TxnDBWritePolicy::WRITE_UNPREPARED:
+ return 0x2;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::TxnDBWritePolicy enum for the
+ // provided Java org.rocksdb.TxnDBWritePolicy
+ static rocksdb::TxnDBWritePolicy toCppTxnDBWritePolicy(
+ jbyte jtxndb_write_policy) {
+ switch(jtxndb_write_policy) {
+ case 0x0:
+ return rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
+ case 0x1:
+ return rocksdb::TxnDBWritePolicy::WRITE_PREPARED;
+ case 0x2:
+ return rocksdb::TxnDBWritePolicy::WRITE_UNPREPARED;
+ default:
+ // undefined/default
+ return rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.TransactionDB.KeyLockInfo
+class KeyLockInfoJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.TransactionDB.KeyLockInfo
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,
+ "org/rocksdb/TransactionDB$KeyLockInfo");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.TransactionDB.KeyLockInfo object
+ * with the same properties as the provided C++ rocksdb::KeyLockInfo object
+ *
+ * @param env A pointer to the Java environment
+ * @param key_lock_info The rocksdb::KeyLockInfo object
+ *
+ * @return A reference to a Java
+ * org.rocksdb.TransactionDB.KeyLockInfo object,
+ * or nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env,
+ const rocksdb::KeyLockInfo& key_lock_info) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(
+ jclazz, "<init>", "(Ljava/lang/String;[JZ)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jstring jkey = env->NewStringUTF(key_lock_info.key.c_str());
+ if (jkey == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ const jsize jtransaction_ids_len = static_cast<jsize>(key_lock_info.ids.size());
+ jlongArray jtransactions_ids = env->NewLongArray(jtransaction_ids_len);
+ if (jtransactions_ids == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jkey);
+ return nullptr;
+ }
+
+ const jobject jkey_lock_info = env->NewObject(jclazz, mid,
+ jkey, jtransactions_ids, key_lock_info.exclusive);
+ if(jkey_lock_info == nullptr) {
+ // exception thrown: InstantiationException or OutOfMemoryError
+ env->DeleteLocalRef(jtransactions_ids);
+ env->DeleteLocalRef(jkey);
+ return nullptr;
+ }
+
+ return jkey_lock_info;
+ }
+};
+
+// The portal class for org.rocksdb.TransactionDB.DeadlockInfo
+class DeadlockInfoJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.TransactionDB.DeadlockInfo
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,"org/rocksdb/TransactionDB$DeadlockInfo");
+ }
+};
+
+// The portal class for org.rocksdb.TransactionDB.DeadlockPath
+class DeadlockPathJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.TransactionDB.DeadlockPath
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,
+ "org/rocksdb/TransactionDB$DeadlockPath");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.TransactionDB.DeadlockPath object
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return A reference to a Java
+ * org.rocksdb.TransactionDB.DeadlockPath object,
+ * or nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env,
+ const jobjectArray jdeadlock_infos, const bool limit_exceeded) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(
+ jclazz, "<init>", "([LDeadlockInfo;Z)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ const jobject jdeadlock_path = env->NewObject(jclazz, mid,
+ jdeadlock_infos, limit_exceeded);
+ if(jdeadlock_path == nullptr) {
+ // exception thrown: InstantiationException or OutOfMemoryError
+ return nullptr;
+ }
+
+ return jdeadlock_path;
+ }
+};
+
+class AbstractTableFilterJni : public RocksDBNativeClass<const rocksdb::TableFilterJniCallback*, AbstractTableFilterJni> {
+ public:
+ /**
+ * Get the Java Method: TableFilter#filter(TableProperties)
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getFilterMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid =
+ env->GetMethodID(jclazz, "filter", "(Lorg/rocksdb/TableProperties;)Z");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ private:
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/TableFilter");
+ }
+};
+
+class TablePropertiesJni : public JavaClass {
+ public:
+ /**
+ * Create a new Java org.rocksdb.TableProperties object.
+ *
+ * @param env A pointer to the Java environment
+ * @param table_properties A Cpp table properties object
+ *
+ * @return A reference to a Java org.rocksdb.TableProperties object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject fromCppTableProperties(JNIEnv* env, const rocksdb::TableProperties& table_properties) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JJJJJJJJJJJJJJJJJJJ[BLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jbyteArray jcolumn_family_name = rocksdb::JniUtil::copyBytes(env, table_properties.column_family_name);
+ if (jcolumn_family_name == nullptr) {
+ // exception occurred creating java string
+ return nullptr;
+ }
+
+ jstring jfilter_policy_name = rocksdb::JniUtil::toJavaString(env, &table_properties.filter_policy_name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ return nullptr;
+ }
+
+ jstring jcomparator_name = rocksdb::JniUtil::toJavaString(env, &table_properties.comparator_name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ return nullptr;
+ }
+
+ jstring jmerge_operator_name = rocksdb::JniUtil::toJavaString(env, &table_properties.merge_operator_name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ return nullptr;
+ }
+
+ jstring jprefix_extractor_name = rocksdb::JniUtil::toJavaString(env, &table_properties.prefix_extractor_name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ env->DeleteLocalRef(jmerge_operator_name);
+ return nullptr;
+ }
+
+ jstring jproperty_collectors_names = rocksdb::JniUtil::toJavaString(env, &table_properties.property_collectors_names, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ env->DeleteLocalRef(jmerge_operator_name);
+ env->DeleteLocalRef(jprefix_extractor_name);
+ return nullptr;
+ }
+
+ jstring jcompression_name = rocksdb::JniUtil::toJavaString(env, &table_properties.compression_name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ env->DeleteLocalRef(jmerge_operator_name);
+ env->DeleteLocalRef(jprefix_extractor_name);
+ env->DeleteLocalRef(jproperty_collectors_names);
+ return nullptr;
+ }
+
+ // Map<String, String>
+ jobject juser_collected_properties = rocksdb::HashMapJni::fromCppMap(env, &table_properties.user_collected_properties);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java map
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ env->DeleteLocalRef(jmerge_operator_name);
+ env->DeleteLocalRef(jprefix_extractor_name);
+ env->DeleteLocalRef(jproperty_collectors_names);
+ env->DeleteLocalRef(jcompression_name);
+ return nullptr;
+ }
+
+ // Map<String, String>
+ jobject jreadable_properties = rocksdb::HashMapJni::fromCppMap(env, &table_properties.readable_properties);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java map
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ env->DeleteLocalRef(jmerge_operator_name);
+ env->DeleteLocalRef(jprefix_extractor_name);
+ env->DeleteLocalRef(jproperty_collectors_names);
+ env->DeleteLocalRef(jcompression_name);
+ env->DeleteLocalRef(juser_collected_properties);
+ return nullptr;
+ }
+
+ // Map<String, Long>
+ jobject jproperties_offsets = rocksdb::HashMapJni::fromCppMap(env, &table_properties.properties_offsets);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java map
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfilter_policy_name);
+ env->DeleteLocalRef(jcomparator_name);
+ env->DeleteLocalRef(jmerge_operator_name);
+ env->DeleteLocalRef(jprefix_extractor_name);
+ env->DeleteLocalRef(jproperty_collectors_names);
+ env->DeleteLocalRef(jcompression_name);
+ env->DeleteLocalRef(juser_collected_properties);
+ env->DeleteLocalRef(jreadable_properties);
+ return nullptr;
+ }
+
+ jobject jtable_properties = env->NewObject(jclazz, mid,
+ static_cast<jlong>(table_properties.data_size),
+ static_cast<jlong>(table_properties.index_size),
+ static_cast<jlong>(table_properties.index_partitions),
+ static_cast<jlong>(table_properties.top_level_index_size),
+ static_cast<jlong>(table_properties.index_key_is_user_key),
+ static_cast<jlong>(table_properties.index_value_is_delta_encoded),
+ static_cast<jlong>(table_properties.filter_size),
+ static_cast<jlong>(table_properties.raw_key_size),
+ static_cast<jlong>(table_properties.raw_value_size),
+ static_cast<jlong>(table_properties.num_data_blocks),
+ static_cast<jlong>(table_properties.num_entries),
+ static_cast<jlong>(table_properties.num_deletions),
+ static_cast<jlong>(table_properties.num_merge_operands),
+ static_cast<jlong>(table_properties.num_range_deletions),
+ static_cast<jlong>(table_properties.format_version),
+ static_cast<jlong>(table_properties.fixed_key_len),
+ static_cast<jlong>(table_properties.column_family_id),
+ static_cast<jlong>(table_properties.creation_time),
+ static_cast<jlong>(table_properties.oldest_key_time),
+ jcolumn_family_name,
+ jfilter_policy_name,
+ jcomparator_name,
+ jmerge_operator_name,
+ jprefix_extractor_name,
+ jproperty_collectors_names,
+ jcompression_name,
+ juser_collected_properties,
+ jreadable_properties,
+ jproperties_offsets
+ );
+
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ return jtable_properties;
+ }
+
+ private:
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/TableProperties");
+ }
+};
+
+class ColumnFamilyDescriptorJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.ColumnFamilyDescriptor
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/ColumnFamilyDescriptor");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.ColumnFamilyDescriptor object with the same
+ * properties as the provided C++ rocksdb::ColumnFamilyDescriptor object
+ *
+ * @param env A pointer to the Java environment
+ * @param cfd A pointer to rocksdb::ColumnFamilyDescriptor object
+ *
+ * @return A reference to a Java org.rocksdb.ColumnFamilyDescriptor object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env, ColumnFamilyDescriptor* cfd) {
+ jbyteArray jcf_name = JniUtil::copyBytes(env, cfd->name);
+ jobject cfopts = ColumnFamilyOptionsJni::construct(env, &(cfd->options));
+
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>",
+ "([BLorg/rocksdb/ColumnFamilyOptions;)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ env->DeleteLocalRef(jcf_name);
+ return nullptr;
+ }
+
+ jobject jcfd = env->NewObject(jclazz, mid, jcf_name, cfopts);
+ if (env->ExceptionCheck()) {
+ env->DeleteLocalRef(jcf_name);
+ return nullptr;
+ }
+
+ return jcfd;
+ }
+
+ /**
+ * Get the Java Method: ColumnFamilyDescriptor#columnFamilyName
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getColumnFamilyNameMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(jclazz, "columnFamilyName", "()[B");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: ColumnFamilyDescriptor#columnFamilyOptions
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getColumnFamilyOptionsMethod(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "columnFamilyOptions", "()Lorg/rocksdb/ColumnFamilyOptions;");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.IndexType
+class IndexTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.IndexType for the provided
+ // C++ rocksdb::IndexType enum
+ static jbyte toJavaIndexType(
+ const rocksdb::BlockBasedTableOptions::IndexType& index_type) {
+ switch(index_type) {
+ case rocksdb::BlockBasedTableOptions::IndexType::kBinarySearch:
+ return 0x0;
+ case rocksdb::BlockBasedTableOptions::IndexType::kHashSearch:
+ return 0x1;
+ case rocksdb::BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch:
+ return 0x2;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::IndexType enum for the
+ // provided Java org.rocksdb.IndexType
+ static rocksdb::BlockBasedTableOptions::IndexType toCppIndexType(
+ jbyte jindex_type) {
+ switch(jindex_type) {
+ case 0x0:
+ return rocksdb::BlockBasedTableOptions::IndexType::kBinarySearch;
+ case 0x1:
+ return rocksdb::BlockBasedTableOptions::IndexType::kHashSearch;
+ case 0x2:
+ return rocksdb::BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
+ default:
+ // undefined/default
+ return rocksdb::BlockBasedTableOptions::IndexType::kBinarySearch;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.DataBlockIndexType
+class DataBlockIndexTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.DataBlockIndexType for the provided
+ // C++ rocksdb::DataBlockIndexType enum
+ static jbyte toJavaDataBlockIndexType(
+ const rocksdb::BlockBasedTableOptions::DataBlockIndexType& index_type) {
+ switch(index_type) {
+ case rocksdb::BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch:
+ return 0x0;
+ case rocksdb::BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinaryAndHash:
+ return 0x1;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::DataBlockIndexType enum for the
+ // provided Java org.rocksdb.DataBlockIndexType
+ static rocksdb::BlockBasedTableOptions::DataBlockIndexType toCppDataBlockIndexType(
+ jbyte jindex_type) {
+ switch(jindex_type) {
+ case 0x0:
+ return rocksdb::BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch;
+ case 0x1:
+ return rocksdb::BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinaryAndHash;
+ default:
+ // undefined/default
+ return rocksdb::BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.ChecksumType
+class ChecksumTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.ChecksumType for the provided
+ // C++ rocksdb::ChecksumType enum
+ static jbyte toJavaChecksumType(
+ const rocksdb::ChecksumType& checksum_type) {
+ switch(checksum_type) {
+ case rocksdb::ChecksumType::kNoChecksum:
+ return 0x0;
+ case rocksdb::ChecksumType::kCRC32c:
+ return 0x1;
+ case rocksdb::ChecksumType::kxxHash:
+ return 0x2;
+ case rocksdb::ChecksumType::kxxHash64:
+ return 0x3;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::ChecksumType enum for the
+ // provided Java org.rocksdb.ChecksumType
+ static rocksdb::ChecksumType toCppChecksumType(
+ jbyte jchecksum_type) {
+ switch(jchecksum_type) {
+ case 0x0:
+ return rocksdb::ChecksumType::kNoChecksum;
+ case 0x1:
+ return rocksdb::ChecksumType::kCRC32c;
+ case 0x2:
+ return rocksdb::ChecksumType::kxxHash;
+ case 0x3:
+ return rocksdb::ChecksumType::kxxHash64;
+ default:
+ // undefined/default
+ return rocksdb::ChecksumType::kCRC32c;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.Priority
+class PriorityJni {
+ public:
+ // Returns the equivalent org.rocksdb.Priority for the provided
+ // C++ rocksdb::Env::Priority enum
+ static jbyte toJavaPriority(
+ const rocksdb::Env::Priority& priority) {
+ switch(priority) {
+ case rocksdb::Env::Priority::BOTTOM:
+ return 0x0;
+ case rocksdb::Env::Priority::LOW:
+ return 0x1;
+ case rocksdb::Env::Priority::HIGH:
+ return 0x2;
+ case rocksdb::Env::Priority::TOTAL:
+ return 0x3;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::env::Priority enum for the
+ // provided Java org.rocksdb.Priority
+ static rocksdb::Env::Priority toCppPriority(
+ jbyte jpriority) {
+ switch(jpriority) {
+ case 0x0:
+ return rocksdb::Env::Priority::BOTTOM;
+ case 0x1:
+ return rocksdb::Env::Priority::LOW;
+ case 0x2:
+ return rocksdb::Env::Priority::HIGH;
+ case 0x3:
+ return rocksdb::Env::Priority::TOTAL;
+ default:
+ // undefined/default
+ return rocksdb::Env::Priority::LOW;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.ThreadType
+class ThreadTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.ThreadType for the provided
+ // C++ rocksdb::ThreadStatus::ThreadType enum
+ static jbyte toJavaThreadType(
+ const rocksdb::ThreadStatus::ThreadType& thread_type) {
+ switch(thread_type) {
+ case rocksdb::ThreadStatus::ThreadType::HIGH_PRIORITY:
+ return 0x0;
+ case rocksdb::ThreadStatus::ThreadType::LOW_PRIORITY:
+ return 0x1;
+ case rocksdb::ThreadStatus::ThreadType::USER:
+ return 0x2;
+ case rocksdb::ThreadStatus::ThreadType::BOTTOM_PRIORITY:
+ return 0x3;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::ThreadStatus::ThreadType enum for the
+ // provided Java org.rocksdb.ThreadType
+ static rocksdb::ThreadStatus::ThreadType toCppThreadType(
+ jbyte jthread_type) {
+ switch(jthread_type) {
+ case 0x0:
+ return rocksdb::ThreadStatus::ThreadType::HIGH_PRIORITY;
+ case 0x1:
+ return rocksdb::ThreadStatus::ThreadType::LOW_PRIORITY;
+ case 0x2:
+ return ThreadStatus::ThreadType::USER;
+ case 0x3:
+ return rocksdb::ThreadStatus::ThreadType::BOTTOM_PRIORITY;
+ default:
+ // undefined/default
+ return rocksdb::ThreadStatus::ThreadType::LOW_PRIORITY;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.OperationType
+class OperationTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.OperationType for the provided
+ // C++ rocksdb::ThreadStatus::OperationType enum
+ static jbyte toJavaOperationType(
+ const rocksdb::ThreadStatus::OperationType& operation_type) {
+ switch(operation_type) {
+ case rocksdb::ThreadStatus::OperationType::OP_UNKNOWN:
+ return 0x0;
+ case rocksdb::ThreadStatus::OperationType::OP_COMPACTION:
+ return 0x1;
+ case rocksdb::ThreadStatus::OperationType::OP_FLUSH:
+ return 0x2;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::ThreadStatus::OperationType enum for the
+ // provided Java org.rocksdb.OperationType
+ static rocksdb::ThreadStatus::OperationType toCppOperationType(
+ jbyte joperation_type) {
+ switch(joperation_type) {
+ case 0x0:
+ return rocksdb::ThreadStatus::OperationType::OP_UNKNOWN;
+ case 0x1:
+ return rocksdb::ThreadStatus::OperationType::OP_COMPACTION;
+ case 0x2:
+ return rocksdb::ThreadStatus::OperationType::OP_FLUSH;
+ default:
+ // undefined/default
+ return rocksdb::ThreadStatus::OperationType::OP_UNKNOWN;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.OperationStage
+class OperationStageJni {
+ public:
+ // Returns the equivalent org.rocksdb.OperationStage for the provided
+ // C++ rocksdb::ThreadStatus::OperationStage enum
+ static jbyte toJavaOperationStage(
+ const rocksdb::ThreadStatus::OperationStage& operation_stage) {
+ switch(operation_stage) {
+ case rocksdb::ThreadStatus::OperationStage::STAGE_UNKNOWN:
+ return 0x0;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_FLUSH_RUN:
+ return 0x1;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_FLUSH_WRITE_L0:
+ return 0x2;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_PREPARE:
+ return 0x3;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_RUN:
+ return 0x4;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_PROCESS_KV:
+ return 0x5;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_INSTALL:
+ return 0x6;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_SYNC_FILE:
+ return 0x7;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_PICK_MEMTABLES_TO_FLUSH:
+ return 0x8;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_MEMTABLE_ROLLBACK:
+ return 0x9;
+ case rocksdb::ThreadStatus::OperationStage::STAGE_MEMTABLE_INSTALL_FLUSH_RESULTS:
+ return 0xA;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::ThreadStatus::OperationStage enum for the
+ // provided Java org.rocksdb.OperationStage
+ static rocksdb::ThreadStatus::OperationStage toCppOperationStage(
+ jbyte joperation_stage) {
+ switch(joperation_stage) {
+ case 0x0:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_UNKNOWN;
+ case 0x1:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_FLUSH_RUN;
+ case 0x2:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_FLUSH_WRITE_L0;
+ case 0x3:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_PREPARE;
+ case 0x4:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_RUN;
+ case 0x5:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_PROCESS_KV;
+ case 0x6:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_INSTALL;
+ case 0x7:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_COMPACTION_SYNC_FILE;
+ case 0x8:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_PICK_MEMTABLES_TO_FLUSH;
+ case 0x9:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_MEMTABLE_ROLLBACK;
+ case 0xA:
+ return rocksdb::ThreadStatus::OperationStage::STAGE_MEMTABLE_INSTALL_FLUSH_RESULTS;
+ default:
+ // undefined/default
+ return rocksdb::ThreadStatus::OperationStage::STAGE_UNKNOWN;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.StateType
+class StateTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.StateType for the provided
+ // C++ rocksdb::ThreadStatus::StateType enum
+ static jbyte toJavaStateType(
+ const rocksdb::ThreadStatus::StateType& state_type) {
+ switch(state_type) {
+ case rocksdb::ThreadStatus::StateType::STATE_UNKNOWN:
+ return 0x0;
+ case rocksdb::ThreadStatus::StateType::STATE_MUTEX_WAIT:
+ return 0x1;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::ThreadStatus::StateType enum for the
+ // provided Java org.rocksdb.StateType
+ static rocksdb::ThreadStatus::StateType toCppStateType(
+ jbyte jstate_type) {
+ switch(jstate_type) {
+ case 0x0:
+ return rocksdb::ThreadStatus::StateType::STATE_UNKNOWN;
+ case 0x1:
+ return rocksdb::ThreadStatus::StateType::STATE_MUTEX_WAIT;
+ default:
+ // undefined/default
+ return rocksdb::ThreadStatus::StateType::STATE_UNKNOWN;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.ThreadStatus
+class ThreadStatusJni : public JavaClass {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.ThreadStatus
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env,
+ "org/rocksdb/ThreadStatus");
+ }
+
+ /**
+ * Create a new Java org.rocksdb.ThreadStatus object with the same
+ * properties as the provided C++ rocksdb::ThreadStatus object
+ *
+ * @param env A pointer to the Java environment
+ * @param thread_status A pointer to rocksdb::ThreadStatus object
+ *
+ * @return A reference to a Java org.rocksdb.ColumnFamilyOptions object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject construct(JNIEnv* env,
+ const rocksdb::ThreadStatus* thread_status) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JBLjava/lang/String;Ljava/lang/String;BJB[JB)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jstring jdb_name =
+ JniUtil::toJavaString(env, &(thread_status->db_name), true);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return nullptr;
+ }
+
+ jstring jcf_name =
+ JniUtil::toJavaString(env, &(thread_status->cf_name), true);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ env->DeleteLocalRef(jdb_name);
+ return nullptr;
+ }
+
+ // long[]
+ const jsize len = static_cast<jsize>(rocksdb::ThreadStatus::kNumOperationProperties);
+ jlongArray joperation_properties =
+ env->NewLongArray(len);
+ if (joperation_properties == nullptr) {
+ // an exception occurred
+ env->DeleteLocalRef(jdb_name);
+ env->DeleteLocalRef(jcf_name);
+ return nullptr;
+ }
+ jlong *body = env->GetLongArrayElements(joperation_properties, nullptr);
+ if (body == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jdb_name);
+ env->DeleteLocalRef(jcf_name);
+ env->DeleteLocalRef(joperation_properties);
+ return nullptr;
+ }
+ for (size_t i = 0; i < len; ++i) {
+ body[i] = static_cast<jlong>(thread_status->op_properties[i]);
+ }
+ env->ReleaseLongArrayElements(joperation_properties, body, 0);
+
+ jobject jcfd = env->NewObject(jclazz, mid,
+ static_cast<jlong>(thread_status->thread_id),
+ ThreadTypeJni::toJavaThreadType(thread_status->thread_type),
+ jdb_name,
+ jcf_name,
+ OperationTypeJni::toJavaOperationType(thread_status->operation_type),
+ static_cast<jlong>(thread_status->op_elapsed_micros),
+ OperationStageJni::toJavaOperationStage(thread_status->operation_stage),
+ joperation_properties,
+ StateTypeJni::toJavaStateType(thread_status->state_type));
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ env->DeleteLocalRef(jdb_name);
+ env->DeleteLocalRef(jcf_name);
+ env->DeleteLocalRef(joperation_properties);
+ return nullptr;
+ }
+
+ // cleanup
+ env->DeleteLocalRef(jdb_name);
+ env->DeleteLocalRef(jcf_name);
+ env->DeleteLocalRef(joperation_properties);
+
+ return jcfd;
+ }
+};
+
+// The portal class for org.rocksdb.CompactionStyle
+class CompactionStyleJni {
+ public:
+ // Returns the equivalent org.rocksdb.CompactionStyle for the provided
+ // C++ rocksdb::CompactionStyle enum
+ static jbyte toJavaCompactionStyle(
+ const rocksdb::CompactionStyle& compaction_style) {
+ switch(compaction_style) {
+ case rocksdb::CompactionStyle::kCompactionStyleLevel:
+ return 0x0;
+ case rocksdb::CompactionStyle::kCompactionStyleUniversal:
+ return 0x1;
+ case rocksdb::CompactionStyle::kCompactionStyleFIFO:
+ return 0x2;
+ case rocksdb::CompactionStyle::kCompactionStyleNone:
+ return 0x3;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::CompactionStyle enum for the
+ // provided Java org.rocksdb.CompactionStyle
+ static rocksdb::CompactionStyle toCppCompactionStyle(
+ jbyte jcompaction_style) {
+ switch(jcompaction_style) {
+ case 0x0:
+ return rocksdb::CompactionStyle::kCompactionStyleLevel;
+ case 0x1:
+ return rocksdb::CompactionStyle::kCompactionStyleUniversal;
+ case 0x2:
+ return rocksdb::CompactionStyle::kCompactionStyleFIFO;
+ case 0x3:
+ return rocksdb::CompactionStyle::kCompactionStyleNone;
+ default:
+ // undefined/default
+ return rocksdb::CompactionStyle::kCompactionStyleLevel;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.CompactionReason
+class CompactionReasonJni {
+ public:
+ // Returns the equivalent org.rocksdb.CompactionReason for the provided
+ // C++ rocksdb::CompactionReason enum
+ static jbyte toJavaCompactionReason(
+ const rocksdb::CompactionReason& compaction_reason) {
+ switch(compaction_reason) {
+ case rocksdb::CompactionReason::kUnknown:
+ return 0x0;
+ case rocksdb::CompactionReason::kLevelL0FilesNum:
+ return 0x1;
+ case rocksdb::CompactionReason::kLevelMaxLevelSize:
+ return 0x2;
+ case rocksdb::CompactionReason::kUniversalSizeAmplification:
+ return 0x3;
+ case rocksdb::CompactionReason::kUniversalSizeRatio:
+ return 0x4;
+ case rocksdb::CompactionReason::kUniversalSortedRunNum:
+ return 0x5;
+ case rocksdb::CompactionReason::kFIFOMaxSize:
+ return 0x6;
+ case rocksdb::CompactionReason::kFIFOReduceNumFiles:
+ return 0x7;
+ case rocksdb::CompactionReason::kFIFOTtl:
+ return 0x8;
+ case rocksdb::CompactionReason::kManualCompaction:
+ return 0x9;
+ case rocksdb::CompactionReason::kFilesMarkedForCompaction:
+ return 0x10;
+ case rocksdb::CompactionReason::kBottommostFiles:
+ return 0x0A;
+ case rocksdb::CompactionReason::kTtl:
+ return 0x0B;
+ case rocksdb::CompactionReason::kFlush:
+ return 0x0C;
+ case rocksdb::CompactionReason::kExternalSstIngestion:
+ return 0x0D;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::CompactionReason enum for the
+ // provided Java org.rocksdb.CompactionReason
+ static rocksdb::CompactionReason toCppCompactionReason(
+ jbyte jcompaction_reason) {
+ switch(jcompaction_reason) {
+ case 0x0:
+ return rocksdb::CompactionReason::kUnknown;
+ case 0x1:
+ return rocksdb::CompactionReason::kLevelL0FilesNum;
+ case 0x2:
+ return rocksdb::CompactionReason::kLevelMaxLevelSize;
+ case 0x3:
+ return rocksdb::CompactionReason::kUniversalSizeAmplification;
+ case 0x4:
+ return rocksdb::CompactionReason::kUniversalSizeRatio;
+ case 0x5:
+ return rocksdb::CompactionReason::kUniversalSortedRunNum;
+ case 0x6:
+ return rocksdb::CompactionReason::kFIFOMaxSize;
+ case 0x7:
+ return rocksdb::CompactionReason::kFIFOReduceNumFiles;
+ case 0x8:
+ return rocksdb::CompactionReason::kFIFOTtl;
+ case 0x9:
+ return rocksdb::CompactionReason::kManualCompaction;
+ case 0x10:
+ return rocksdb::CompactionReason::kFilesMarkedForCompaction;
+ case 0x0A:
+ return rocksdb::CompactionReason::kBottommostFiles;
+ case 0x0B:
+ return rocksdb::CompactionReason::kTtl;
+ case 0x0C:
+ return rocksdb::CompactionReason::kFlush;
+ case 0x0D:
+ return rocksdb::CompactionReason::kExternalSstIngestion;
+ default:
+ // undefined/default
+ return rocksdb::CompactionReason::kUnknown;
+ }
+ }
+};
+
+// The portal class for org.rocksdb.WalFileType
+class WalFileTypeJni {
+ public:
+ // Returns the equivalent org.rocksdb.WalFileType for the provided
+ // C++ rocksdb::WalFileType enum
+ static jbyte toJavaWalFileType(
+ const rocksdb::WalFileType& wal_file_type) {
+ switch(wal_file_type) {
+ case rocksdb::WalFileType::kArchivedLogFile:
+ return 0x0;
+ case rocksdb::WalFileType::kAliveLogFile:
+ return 0x1;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::WalFileType enum for the
+ // provided Java org.rocksdb.WalFileType
+ static rocksdb::WalFileType toCppWalFileType(
+ jbyte jwal_file_type) {
+ switch(jwal_file_type) {
+ case 0x0:
+ return rocksdb::WalFileType::kArchivedLogFile;
+ case 0x1:
+ return rocksdb::WalFileType::kAliveLogFile;
+ default:
+ // undefined/default
+ return rocksdb::WalFileType::kAliveLogFile;
+ }
+ }
+};
+
+class LogFileJni : public JavaClass {
+ public:
+ /**
+ * Create a new Java org.rocksdb.LogFile object.
+ *
+ * @param env A pointer to the Java environment
+ * @param log_file A Cpp log file object
+ *
+ * @return A reference to a Java org.rocksdb.LogFile object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject fromCppLogFile(JNIEnv* env, rocksdb::LogFile* log_file) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;JBJJ)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ std::string path_name = log_file->PathName();
+ jstring jpath_name = rocksdb::JniUtil::toJavaString(env, &path_name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ return nullptr;
+ }
+
+ jobject jlog_file = env->NewObject(jclazz, mid,
+ jpath_name,
+ static_cast<jlong>(log_file->LogNumber()),
+ rocksdb::WalFileTypeJni::toJavaWalFileType(log_file->Type()),
+ static_cast<jlong>(log_file->StartSequence()),
+ static_cast<jlong>(log_file->SizeFileBytes())
+ );
+
+ if (env->ExceptionCheck()) {
+ env->DeleteLocalRef(jpath_name);
+ return nullptr;
+ }
+
+ // cleanup
+ env->DeleteLocalRef(jpath_name);
+
+ return jlog_file;
+ }
+
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/LogFile");
+ }
+};
+
+class LiveFileMetaDataJni : public JavaClass {
+ public:
+ /**
+ * Create a new Java org.rocksdb.LiveFileMetaData object.
+ *
+ * @param env A pointer to the Java environment
+ * @param live_file_meta_data A Cpp live file meta data object
+ *
+ * @return A reference to a Java org.rocksdb.LiveFileMetaData object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject fromCppLiveFileMetaData(JNIEnv* env,
+ rocksdb::LiveFileMetaData* live_file_meta_data) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "([BILjava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jbyteArray jcolumn_family_name = rocksdb::JniUtil::copyBytes(
+ env, live_file_meta_data->column_family_name);
+ if (jcolumn_family_name == nullptr) {
+ // exception occurred creating java byte array
+ return nullptr;
+ }
+
+ jstring jfile_name = rocksdb::JniUtil::toJavaString(
+ env, &live_file_meta_data->name, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ return nullptr;
+ }
+
+ jstring jpath = rocksdb::JniUtil::toJavaString(
+ env, &live_file_meta_data->db_path, true);
+ if (env->ExceptionCheck()) {
+ // exception occurred creating java string
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfile_name);
+ return nullptr;
+ }
+
+ jbyteArray jsmallest_key = rocksdb::JniUtil::copyBytes(
+ env, live_file_meta_data->smallestkey);
+ if (jsmallest_key == nullptr) {
+ // exception occurred creating java byte array
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ return nullptr;
+ }
+
+ jbyteArray jlargest_key = rocksdb::JniUtil::copyBytes(
+ env, live_file_meta_data->largestkey);
+ if (jlargest_key == nullptr) {
+ // exception occurred creating java byte array
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jsmallest_key);
+ return nullptr;
+ }
+
+ jobject jlive_file_meta_data = env->NewObject(jclazz, mid,
+ jcolumn_family_name,
+ static_cast<jint>(live_file_meta_data->level),
+ jfile_name,
+ jpath,
+ static_cast<jlong>(live_file_meta_data->size),
+ static_cast<jlong>(live_file_meta_data->smallest_seqno),
+ static_cast<jlong>(live_file_meta_data->largest_seqno),
+ jsmallest_key,
+ jlargest_key,
+ static_cast<jlong>(live_file_meta_data->num_reads_sampled),
+ static_cast<jboolean>(live_file_meta_data->being_compacted),
+ static_cast<jlong>(live_file_meta_data->num_entries),
+ static_cast<jlong>(live_file_meta_data->num_deletions)
+ );
+
+ if (env->ExceptionCheck()) {
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jsmallest_key);
+ env->DeleteLocalRef(jlargest_key);
+ return nullptr;
+ }
+
+ // cleanup
+ env->DeleteLocalRef(jcolumn_family_name);
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jsmallest_key);
+ env->DeleteLocalRef(jlargest_key);
+
+ return jlive_file_meta_data;
+ }
+
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/LiveFileMetaData");
+ }
+};
+
+class SstFileMetaDataJni : public JavaClass {
+ public:
+ /**
+ * Create a new Java org.rocksdb.SstFileMetaData object.
+ *
+ * @param env A pointer to the Java environment
+ * @param sst_file_meta_data A Cpp sst file meta data object
+ *
+ * @return A reference to a Java org.rocksdb.SstFileMetaData object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject fromCppSstFileMetaData(JNIEnv* env,
+ const rocksdb::SstFileMetaData* sst_file_meta_data) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jstring jfile_name = rocksdb::JniUtil::toJavaString(
+ env, &sst_file_meta_data->name, true);
+ if (jfile_name == nullptr) {
+ // exception occurred creating java byte array
+ return nullptr;
+ }
+
+ jstring jpath = rocksdb::JniUtil::toJavaString(
+ env, &sst_file_meta_data->db_path, true);
+ if (jpath == nullptr) {
+ // exception occurred creating java byte array
+ env->DeleteLocalRef(jfile_name);
+ return nullptr;
+ }
+
+ jbyteArray jsmallest_key = rocksdb::JniUtil::copyBytes(
+ env, sst_file_meta_data->smallestkey);
+ if (jsmallest_key == nullptr) {
+ // exception occurred creating java byte array
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ return nullptr;
+ }
+
+ jbyteArray jlargest_key = rocksdb::JniUtil::copyBytes(
+ env, sst_file_meta_data->largestkey);
+ if (jlargest_key == nullptr) {
+ // exception occurred creating java byte array
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jsmallest_key);
+ return nullptr;
+ }
+
+ jobject jsst_file_meta_data = env->NewObject(jclazz, mid,
+ jfile_name,
+ jpath,
+ static_cast<jlong>(sst_file_meta_data->size),
+ static_cast<jint>(sst_file_meta_data->smallest_seqno),
+ static_cast<jlong>(sst_file_meta_data->largest_seqno),
+ jsmallest_key,
+ jlargest_key,
+ static_cast<jlong>(sst_file_meta_data->num_reads_sampled),
+ static_cast<jboolean>(sst_file_meta_data->being_compacted),
+ static_cast<jlong>(sst_file_meta_data->num_entries),
+ static_cast<jlong>(sst_file_meta_data->num_deletions)
+ );
+
+ if (env->ExceptionCheck()) {
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jsmallest_key);
+ env->DeleteLocalRef(jlargest_key);
+ return nullptr;
+ }
+
+ // cleanup
+ env->DeleteLocalRef(jfile_name);
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jsmallest_key);
+ env->DeleteLocalRef(jlargest_key);
+
+ return jsst_file_meta_data;
+ }
+
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/SstFileMetaData");
+ }
+};
+
+class LevelMetaDataJni : public JavaClass {
+ public:
+ /**
+ * Create a new Java org.rocksdb.LevelMetaData object.
+ *
+ * @param env A pointer to the Java environment
+ * @param level_meta_data A Cpp level meta data object
+ *
+ * @return A reference to a Java org.rocksdb.LevelMetaData object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject fromCppLevelMetaData(JNIEnv* env,
+ const rocksdb::LevelMetaData* level_meta_data) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(IJ[Lorg/rocksdb/SstFileMetaData;)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ const jsize jlen =
+ static_cast<jsize>(level_meta_data->files.size());
+ jobjectArray jfiles = env->NewObjectArray(jlen, SstFileMetaDataJni::getJClass(env), nullptr);
+ if (jfiles == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jsize i = 0;
+ for (auto it = level_meta_data->files.begin();
+ it != level_meta_data->files.end(); ++it) {
+ jobject jfile = SstFileMetaDataJni::fromCppSstFileMetaData(env, &(*it));
+ if (jfile == nullptr) {
+ // exception occurred
+ env->DeleteLocalRef(jfiles);
+ return nullptr;
+ }
+ env->SetObjectArrayElement(jfiles, i++, jfile);
+ }
+
+ jobject jlevel_meta_data = env->NewObject(jclazz, mid,
+ static_cast<jint>(level_meta_data->level),
+ static_cast<jlong>(level_meta_data->size),
+ jfiles
+ );
+
+ if (env->ExceptionCheck()) {
+ env->DeleteLocalRef(jfiles);
+ return nullptr;
+ }
+
+ // cleanup
+ env->DeleteLocalRef(jfiles);
+
+ return jlevel_meta_data;
+ }
+
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/LevelMetaData");
+ }
+};
+
+class ColumnFamilyMetaDataJni : public JavaClass {
+ public:
+ /**
+ * Create a new Java org.rocksdb.ColumnFamilyMetaData object.
+ *
+ * @param env A pointer to the Java environment
+ * @param column_famly_meta_data A Cpp live file meta data object
+ *
+ * @return A reference to a Java org.rocksdb.ColumnFamilyMetaData object, or
+ * nullptr if an an exception occurs
+ */
+ static jobject fromCppColumnFamilyMetaData(JNIEnv* env,
+ const rocksdb::ColumnFamilyMetaData* column_famly_meta_data) {
+ jclass jclazz = getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JJ[B[Lorg/rocksdb/LevelMetaData;)V");
+ if (mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return nullptr;
+ }
+
+ jbyteArray jname = rocksdb::JniUtil::copyBytes(
+ env, column_famly_meta_data->name);
+ if (jname == nullptr) {
+ // exception occurred creating java byte array
+ return nullptr;
+ }
+
+ const jsize jlen =
+ static_cast<jsize>(column_famly_meta_data->levels.size());
+ jobjectArray jlevels = env->NewObjectArray(jlen, LevelMetaDataJni::getJClass(env), nullptr);
+ if(jlevels == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jname);
+ return nullptr;
+ }
+
+ jsize i = 0;
+ for (auto it = column_famly_meta_data->levels.begin();
+ it != column_famly_meta_data->levels.end(); ++it) {
+ jobject jlevel = LevelMetaDataJni::fromCppLevelMetaData(env, &(*it));
+ if (jlevel == nullptr) {
+ // exception occurred
+ env->DeleteLocalRef(jname);
+ env->DeleteLocalRef(jlevels);
+ return nullptr;
+ }
+ env->SetObjectArrayElement(jlevels, i++, jlevel);
+ }
+
+ jobject jcolumn_family_meta_data = env->NewObject(jclazz, mid,
+ static_cast<jlong>(column_famly_meta_data->size),
+ static_cast<jlong>(column_famly_meta_data->file_count),
+ jname,
+ jlevels
+ );
+
+ if (env->ExceptionCheck()) {
+ env->DeleteLocalRef(jname);
+ env->DeleteLocalRef(jlevels);
+ return nullptr;
+ }
+
+ // cleanup
+ env->DeleteLocalRef(jname);
+ env->DeleteLocalRef(jlevels);
+
+ return jcolumn_family_meta_data;
+ }
+
+ static jclass getJClass(JNIEnv* env) {
+ return JavaClass::getJClass(env, "org/rocksdb/ColumnFamilyMetaData");
+ }
+};
+
+// The portal class for org.rocksdb.AbstractTraceWriter
+class AbstractTraceWriterJni : public RocksDBNativeClass<
+ const rocksdb::TraceWriterJniCallback*,
+ AbstractTraceWriterJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.AbstractTraceWriter
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/AbstractTraceWriter");
+ }
+
+ /**
+ * Get the Java Method: AbstractTraceWriter#write
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getWriteProxyMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "writeProxy", "(J)S");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: AbstractTraceWriter#closeWriter
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getCloseWriterProxyMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "closeWriterProxy", "()S");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: AbstractTraceWriter#getFileSize
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getGetFileSizeMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "getFileSize", "()J");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.AbstractWalFilter
+class AbstractWalFilterJni : public RocksDBNativeClass<
+ const rocksdb::WalFilterJniCallback*,
+ AbstractWalFilterJni> {
+ public:
+ /**
+ * Get the Java Class org.rocksdb.AbstractWalFilter
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Class or nullptr if one of the
+ * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
+ * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
+ */
+ static jclass getJClass(JNIEnv* env) {
+ return RocksDBNativeClass::getJClass(env,
+ "org/rocksdb/AbstractWalFilter");
+ }
+
+ /**
+ * Get the Java Method: AbstractWalFilter#columnFamilyLogNumberMap
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getColumnFamilyLogNumberMapMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "columnFamilyLogNumberMap",
+ "(Ljava/util/Map;Ljava/util/Map;)V");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: AbstractTraceWriter#logRecordFoundProxy
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getLogRecordFoundProxyMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "logRecordFoundProxy", "(JLjava/lang/String;JJ)S");
+ assert(mid != nullptr);
+ return mid;
+ }
+
+ /**
+ * Get the Java Method: AbstractTraceWriter#name
+ *
+ * @param env A pointer to the Java environment
+ *
+ * @return The Java Method ID or nullptr if the class or method id could not
+ * be retieved
+ */
+ static jmethodID getNameMethodId(JNIEnv* env) {
+ jclass jclazz = getJClass(env);
+ if(jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ static jmethodID mid = env->GetMethodID(
+ jclazz, "name", "()Ljava/lang/String;");
+ assert(mid != nullptr);
+ return mid;
+ }
+};
+
+// The portal class for org.rocksdb.WalProcessingOption
+class WalProcessingOptionJni {
+ public:
+ // Returns the equivalent org.rocksdb.WalProcessingOption for the provided
+ // C++ rocksdb::WalFilter::WalProcessingOption enum
+ static jbyte toJavaWalProcessingOption(
+ const rocksdb::WalFilter::WalProcessingOption& wal_processing_option) {
+ switch(wal_processing_option) {
+ case rocksdb::WalFilter::WalProcessingOption::kContinueProcessing:
+ return 0x0;
+ case rocksdb::WalFilter::WalProcessingOption::kIgnoreCurrentRecord:
+ return 0x1;
+ case rocksdb::WalFilter::WalProcessingOption::kStopReplay:
+ return 0x2;
+ case rocksdb::WalFilter::WalProcessingOption::kCorruptedRecord:
+ return 0x3;
+ default:
+ return 0x7F; // undefined
+ }
+ }
+
+ // Returns the equivalent C++ rocksdb::WalFilter::WalProcessingOption enum for
+ // the provided Java org.rocksdb.WalProcessingOption
+ static rocksdb::WalFilter::WalProcessingOption toCppWalProcessingOption(
+ jbyte jwal_processing_option) {
+ switch(jwal_processing_option) {
+ case 0x0:
+ return rocksdb::WalFilter::WalProcessingOption::kContinueProcessing;
+ case 0x1:
+ return rocksdb::WalFilter::WalProcessingOption::kIgnoreCurrentRecord;
+ case 0x2:
+ return rocksdb::WalFilter::WalProcessingOption::kStopReplay;
+ case 0x3:
+ return rocksdb::WalFilter::WalProcessingOption::kCorruptedRecord;
+ default:
+ // undefined/default
+ return rocksdb::WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+ }
+};
+} // namespace rocksdb
+#endif // JAVA_ROCKSJNI_PORTAL_H_
diff --git a/src/rocksdb/java/rocksjni/ratelimiterjni.cc b/src/rocksdb/java/rocksjni/ratelimiterjni.cc
new file mode 100644
index 00000000..0804c2fb
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/ratelimiterjni.cc
@@ -0,0 +1,121 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for RateLimiter.
+
+#include "include/org_rocksdb_RateLimiter.h"
+#include "rocksdb/rate_limiter.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: newRateLimiterHandle
+ * Signature: (JJIBZ)J
+ */
+jlong Java_org_rocksdb_RateLimiter_newRateLimiterHandle(
+ JNIEnv* /*env*/, jclass /*jclazz*/, jlong jrate_bytes_per_second,
+ jlong jrefill_period_micros, jint jfairness, jbyte jrate_limiter_mode,
+ jboolean jauto_tune) {
+ auto rate_limiter_mode =
+ rocksdb::RateLimiterModeJni::toCppRateLimiterMode(jrate_limiter_mode);
+ auto* sptr_rate_limiter =
+ new std::shared_ptr<rocksdb::RateLimiter>(rocksdb::NewGenericRateLimiter(
+ static_cast<int64_t>(jrate_bytes_per_second),
+ static_cast<int64_t>(jrefill_period_micros),
+ static_cast<int32_t>(jfairness), rate_limiter_mode, jauto_tune));
+
+ return reinterpret_cast<jlong>(sptr_rate_limiter);
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RateLimiter_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* handle =
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(jhandle);
+ delete handle; // delete std::shared_ptr
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: setBytesPerSecond
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_RateLimiter_setBytesPerSecond(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle,
+ jlong jbytes_per_second) {
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(handle)
+ ->get()
+ ->SetBytesPerSecond(jbytes_per_second);
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: getBytesPerSecond
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RateLimiter_getBytesPerSecond(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(handle)
+ ->get()
+ ->GetBytesPerSecond();
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: request
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_RateLimiter_request(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jlong jbytes) {
+ reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(handle)
+ ->get()
+ ->Request(jbytes, rocksdb::Env::IO_TOTAL);
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: getSingleBurstBytes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RateLimiter_getSingleBurstBytes(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(handle)
+ ->get()
+ ->GetSingleBurstBytes();
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: getTotalBytesThrough
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RateLimiter_getTotalBytesThrough(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(handle)
+ ->get()
+ ->GetTotalBytesThrough();
+}
+
+/*
+ * Class: org_rocksdb_RateLimiter
+ * Method: getTotalRequests
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RateLimiter_getTotalRequests(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<std::shared_ptr<rocksdb::RateLimiter>*>(handle)
+ ->get()
+ ->GetTotalRequests();
+}
diff --git a/src/rocksdb/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc b/src/rocksdb/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc
new file mode 100644
index 00000000..ede150fa
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/remove_emptyvalue_compactionfilterjni.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+
+#include "include/org_rocksdb_RemoveEmptyValueCompactionFilter.h"
+#include "utilities/compaction_filters/remove_emptyvalue_compactionfilter.h"
+
+/*
+ * Class: org_rocksdb_RemoveEmptyValueCompactionFilter
+ * Method: createNewRemoveEmptyValueCompactionFilter0
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_RemoveEmptyValueCompactionFilter_createNewRemoveEmptyValueCompactionFilter0(
+ JNIEnv* /*env*/, jclass /*jcls*/) {
+ auto* compaction_filter = new rocksdb::RemoveEmptyValueCompactionFilter();
+
+ // set the native handle to our native compaction filter
+ return reinterpret_cast<jlong>(compaction_filter);
+}
diff --git a/src/rocksdb/java/rocksjni/restorejni.cc b/src/rocksdb/java/rocksjni/restorejni.cc
new file mode 100644
index 00000000..beca74fb
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/restorejni.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling C++ rocksdb::RestoreOptions methods
+// from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+#include "include/org_rocksdb_RestoreOptions.h"
+#include "rocksdb/utilities/backupable_db.h"
+#include "rocksjni/portal.h"
+/*
+ * Class: org_rocksdb_RestoreOptions
+ * Method: newRestoreOptions
+ * Signature: (Z)J
+ */
+jlong Java_org_rocksdb_RestoreOptions_newRestoreOptions(
+ JNIEnv* /*env*/, jclass /*jcls*/, jboolean keep_log_files) {
+ auto* ropt = new rocksdb::RestoreOptions(keep_log_files);
+ return reinterpret_cast<jlong>(ropt);
+}
+
+/*
+ * Class: org_rocksdb_RestoreOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RestoreOptions_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* ropt = reinterpret_cast<rocksdb::RestoreOptions*>(jhandle);
+ assert(ropt);
+ delete ropt;
+}
diff --git a/src/rocksdb/java/rocksjni/rocks_callback_object.cc b/src/rocksdb/java/rocksjni/rocks_callback_object.cc
new file mode 100644
index 00000000..874ef337
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/rocks_callback_object.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// JNI Callbacks from C++ to sub-classes or org.rocksdb.RocksCallbackObject
+
+#include <jni.h>
+
+#include "include/org_rocksdb_RocksCallbackObject.h"
+#include "jnicallback.h"
+
+/*
+ * Class: org_rocksdb_RocksCallbackObject
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksCallbackObject_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ // TODO(AR) is deleting from the super class JniCallback OK, or must we delete
+ // the subclass? Example hierarchies:
+ // 1) Comparator -> BaseComparatorJniCallback + JniCallback ->
+ // DirectComparatorJniCallback 2) Comparator -> BaseComparatorJniCallback +
+ // JniCallback -> ComparatorJniCallback
+ // I think this is okay, as Comparator and JniCallback both have virtual
+ // destructors...
+ delete reinterpret_cast<rocksdb::JniCallback*>(handle);
+ // @lint-ignore TXT4 T25377293 Grandfathered in
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/rocksdb_exception_test.cc b/src/rocksdb/java/rocksjni/rocksdb_exception_test.cc
new file mode 100644
index 00000000..6e597812
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/rocksdb_exception_test.cc
@@ -0,0 +1,78 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+
+#include "include/org_rocksdb_RocksDBExceptionTest.h"
+
+#include "rocksdb/slice.h"
+#include "rocksdb/status.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_RocksDBExceptionTest
+ * Method: raiseException
+ * Signature: ()V
+ */
+void Java_org_rocksdb_RocksDBExceptionTest_raiseException(JNIEnv* env,
+ jobject /*jobj*/) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, std::string("test message"));
+}
+
+/*
+ * Class: org_rocksdb_RocksDBExceptionTest
+ * Method: raiseExceptionWithStatusCode
+ * Signature: ()V
+ */
+void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionWithStatusCode(
+ JNIEnv* env, jobject /*jobj*/) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, "test message",
+ rocksdb::Status::NotSupported());
+}
+
+/*
+ * Class: org_rocksdb_RocksDBExceptionTest
+ * Method: raiseExceptionNoMsgWithStatusCode
+ * Signature: ()V
+ */
+void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionNoMsgWithStatusCode(
+ JNIEnv* env, jobject /*jobj*/) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotSupported());
+}
+
+/*
+ * Class: org_rocksdb_RocksDBExceptionTest
+ * Method: raiseExceptionWithStatusCodeSubCode
+ * Signature: ()V
+ */
+void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionWithStatusCodeSubCode(
+ JNIEnv* env, jobject /*jobj*/) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, "test message",
+ rocksdb::Status::TimedOut(rocksdb::Status::SubCode::kLockTimeout));
+}
+
+/*
+ * Class: org_rocksdb_RocksDBExceptionTest
+ * Method: raiseExceptionNoMsgWithStatusCodeSubCode
+ * Signature: ()V
+ */
+void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionNoMsgWithStatusCodeSubCode(
+ JNIEnv* env, jobject /*jobj*/) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::TimedOut(rocksdb::Status::SubCode::kLockTimeout));
+}
+
+/*
+ * Class: org_rocksdb_RocksDBExceptionTest
+ * Method: raiseExceptionWithStatusCodeState
+ * Signature: ()V
+ */
+void Java_org_rocksdb_RocksDBExceptionTest_raiseExceptionWithStatusCodeState(
+ JNIEnv* env, jobject /*jobj*/) {
+ rocksdb::Slice state("test state");
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, "test message",
+ rocksdb::Status::NotSupported(state));
+}
diff --git a/src/rocksdb/java/rocksjni/rocksjni.cc b/src/rocksdb/java/rocksjni/rocksjni.cc
new file mode 100644
index 00000000..53224232
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/rocksjni.cc
@@ -0,0 +1,3046 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::DB methods from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "include/org_rocksdb_RocksDB.h"
+#include "rocksdb/cache.h"
+#include "rocksdb/db.h"
+#include "rocksdb/options.h"
+#include "rocksdb/types.h"
+#include "rocksjni/portal.h"
+
+#ifdef min
+#undef min
+#endif
+
+jlong rocksdb_open_helper(
+ JNIEnv* env, jlong jopt_handle, jstring jdb_path,
+ std::function<rocksdb::Status(const rocksdb::Options&, const std::string&,
+ rocksdb::DB**)>
+ open_fn) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
+ rocksdb::DB* db = nullptr;
+ rocksdb::Status s = open_fn(*opt, db_path, &db);
+
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(db);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: open
+ * Signature: (JLjava/lang/String;)J
+ */
+jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(
+ JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) {
+ return rocksdb_open_helper(
+ env, jopt_handle, jdb_path,
+ (rocksdb::Status(*)(const rocksdb::Options&, const std::string&,
+ rocksdb::DB**)) &
+ rocksdb::DB::Open);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: openROnly
+ * Signature: (JLjava/lang/String;)J
+ */
+jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2(
+ JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) {
+ return rocksdb_open_helper(env, jopt_handle, jdb_path,
+ [](const rocksdb::Options& options,
+ const std::string& db_path, rocksdb::DB** db) {
+ return rocksdb::DB::OpenForReadOnly(options,
+ db_path, db);
+ });
+}
+
+jlongArray rocksdb_open_helper(
+ JNIEnv* env, jlong jopt_handle, jstring jdb_path,
+ jobjectArray jcolumn_names, jlongArray jcolumn_options,
+ std::function<rocksdb::Status(
+ const rocksdb::DBOptions&, const std::string&,
+ const std::vector<rocksdb::ColumnFamilyDescriptor>&,
+ std::vector<rocksdb::ColumnFamilyHandle*>*, rocksdb::DB**)>
+ open_fn) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ const jsize len_cols = env->GetArrayLength(jcolumn_names);
+ jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr);
+ if (jco == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
+ jboolean has_exception = JNI_FALSE;
+ rocksdb::JniUtil::byteStrings<std::string>(
+ env, jcolumn_names,
+ [](const char* str_data, const size_t str_len) {
+ return std::string(str_data, str_len);
+ },
+ [&jco, &column_families](size_t idx, std::string cf_name) {
+ rocksdb::ColumnFamilyOptions* cf_options =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[idx]);
+ column_families.push_back(
+ rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
+ },
+ &has_exception);
+
+ env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
+
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ rocksdb::DB* db = nullptr;
+ rocksdb::Status s = open_fn(*opt, db_path, column_families, &cf_handles, &db);
+
+ // we have now finished with db_path
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ // check if open operation was successful
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ const jsize resultsLen = 1 + len_cols; // db handle + column family handles
+ std::unique_ptr<jlong[]> results =
+ std::unique_ptr<jlong[]>(new jlong[resultsLen]);
+ results[0] = reinterpret_cast<jlong>(db);
+ for (int i = 1; i <= len_cols; i++) {
+ results[i] = reinterpret_cast<jlong>(cf_handles[i - 1]);
+ }
+
+ jlongArray jresults = env->NewLongArray(resultsLen);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jresults);
+ return nullptr;
+ }
+
+ return jresults;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: openROnly
+ * Signature: (JLjava/lang/String;[[B[J)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3J(
+ JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
+ jobjectArray jcolumn_names, jlongArray jcolumn_options) {
+ return rocksdb_open_helper(
+ env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
+ [](const rocksdb::DBOptions& options, const std::string& db_path,
+ const std::vector<rocksdb::ColumnFamilyDescriptor>& column_families,
+ std::vector<rocksdb::ColumnFamilyHandle*>* handles, rocksdb::DB** db) {
+ return rocksdb::DB::OpenForReadOnly(options, db_path, column_families,
+ handles, db);
+ });
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: open
+ * Signature: (JLjava/lang/String;[[B[J)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J(
+ JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
+ jobjectArray jcolumn_names, jlongArray jcolumn_options) {
+ return rocksdb_open_helper(
+ env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
+ (rocksdb::Status(*)(const rocksdb::DBOptions&, const std::string&,
+ const std::vector<rocksdb::ColumnFamilyDescriptor>&,
+ std::vector<rocksdb::ColumnFamilyHandle*>*,
+ rocksdb::DB**)) &
+ rocksdb::DB::Open);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jhandle);
+ assert(db != nullptr);
+ delete db;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: closeDatabase
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_closeDatabase(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jhandle);
+ assert(db != nullptr);
+ rocksdb::Status s = db->Close();
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: listColumnFamilies
+ * Signature: (JLjava/lang/String;)[[B
+ */
+jobjectArray Java_org_rocksdb_RocksDB_listColumnFamilies(
+ JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) {
+ std::vector<std::string> column_family_names;
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
+ rocksdb::Status s =
+ rocksdb::DB::ListColumnFamilies(*opt, db_path, &column_family_names);
+
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ jobjectArray jcolumn_family_names =
+ rocksdb::JniUtil::stringsBytes(env, column_family_names);
+
+ return jcolumn_family_names;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: createColumnFamily
+ * Signature: (J[BIJ)J
+ */
+jlong Java_org_rocksdb_RocksDB_createColumnFamily(
+ JNIEnv* env, jobject, jlong jhandle, jbyteArray jcf_name,
+ jint jcf_name_len, jlong jcf_options_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jhandle);
+ jboolean has_exception = JNI_FALSE;
+ const std::string cf_name =
+ rocksdb::JniUtil::byteString<std::string>(env, jcf_name, jcf_name_len,
+ [](const char* str, const size_t len) {
+ return std::string(str, len);
+ }, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return 0;
+ }
+ auto* cf_options =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcf_options_handle);
+ rocksdb::ColumnFamilyHandle *cf_handle;
+ rocksdb::Status s = db->CreateColumnFamily(*cf_options, cf_name, &cf_handle);
+ if (!s.ok()) {
+ // error occurred
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+ }
+ return reinterpret_cast<jlong>(cf_handle);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: createColumnFamilies
+ * Signature: (JJ[[B)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__JJ_3_3B(
+ JNIEnv* env, jobject, jlong jhandle, jlong jcf_options_handle,
+ jobjectArray jcf_names) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jhandle);
+ auto* cf_options =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcf_options_handle);
+ jboolean has_exception = JNI_FALSE;
+ std::vector<std::string> cf_names;
+ rocksdb::JniUtil::byteStrings<std::string>(env, jcf_names,
+ [](const char* str, const size_t len) {
+ return std::string(str, len);
+ },
+ [&cf_names](const size_t, std::string str) {
+ cf_names.push_back(str);
+ },
+ &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return nullptr;
+ }
+
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ rocksdb::Status s = db->CreateColumnFamilies(*cf_options, cf_names, &cf_handles);
+ if (!s.ok()) {
+ // error occurred
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ jlongArray jcf_handles = rocksdb::JniUtil::toJPointers<rocksdb::ColumnFamilyHandle>(
+ env, cf_handles, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return nullptr;
+ }
+ return jcf_handles;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: createColumnFamilies
+ * Signature: (J[J[[B)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__J_3J_3_3B(
+ JNIEnv* env, jobject, jlong jhandle, jlongArray jcf_options_handles,
+ jobjectArray jcf_names) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jhandle);
+ const jsize jlen = env->GetArrayLength(jcf_options_handles);
+ std::vector<rocksdb::ColumnFamilyDescriptor> cf_descriptors;
+ cf_descriptors.reserve(jlen);
+
+ jboolean jcf_options_handles_is_copy = JNI_FALSE;
+ jlong *jcf_options_handles_elems = env->GetLongArrayElements(jcf_options_handles, &jcf_options_handles_is_copy);
+ if(jcf_options_handles_elems == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ // extract the column family descriptors
+ jboolean has_exception = JNI_FALSE;
+ for (jsize i = 0; i < jlen; i++) {
+ auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>(
+ jcf_options_handles_elems[i]);
+ jbyteArray jcf_name = static_cast<jbyteArray>(
+ env->GetObjectArrayElement(jcf_names, i));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT);
+ return nullptr;
+ }
+ const std::string cf_name =
+ rocksdb::JniUtil::byteString<std::string>(env, jcf_name,
+ [](const char* str, const size_t len) {
+ return std::string(str, len);
+ },
+ &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->DeleteLocalRef(jcf_name);
+ env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT);
+ return nullptr;
+ }
+
+ cf_descriptors.push_back(rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
+
+ env->DeleteLocalRef(jcf_name);
+ }
+
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ rocksdb::Status s = db->CreateColumnFamilies(cf_descriptors, &cf_handles);
+
+ env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT);
+
+ if (!s.ok()) {
+ // error occurred
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ jlongArray jcf_handles = rocksdb::JniUtil::toJPointers<rocksdb::ColumnFamilyHandle>(
+ env, cf_handles, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return nullptr;
+ }
+ return jcf_handles;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: dropColumnFamily
+ * Signature: (JJ)V;
+ */
+void Java_org_rocksdb_RocksDB_dropColumnFamily(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jlong jcf_handle) {
+ auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ rocksdb::Status s = db_handle->DropColumnFamily(cf_handle);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: dropColumnFamilies
+ * Signature: (J[J)V
+ */
+void Java_org_rocksdb_RocksDB_dropColumnFamilies(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jlongArray jcolumn_family_handles) {
+ auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ if (jcolumn_family_handles != nullptr) {
+ const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
+
+ jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
+ if (jcfh == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ for (jsize i = 0; i < len_cols; i++) {
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]);
+ cf_handles.push_back(cf_handle);
+ }
+ env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
+ }
+
+ rocksdb::Status s = db_handle->DropColumnFamilies(cf_handles);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::Put
+
+/**
+ * @return true if the put succeeded, false if a Java Exception was thrown
+ */
+bool rocksdb_put_helper(
+ JNIEnv* env, rocksdb::DB* db,
+ const rocksdb::WriteOptions& write_options,
+ rocksdb::ColumnFamilyHandle* cf_handle, jbyteArray jkey,
+ jint jkey_off, jint jkey_len, jbyteArray jval,
+ jint jval_off, jint jval_len) {
+ jbyte* key = new jbyte[jkey_len];
+ env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] key;
+ return false;
+ }
+
+ jbyte* value = new jbyte[jval_len];
+ env->GetByteArrayRegion(jval, jval_off, jval_len, value);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] value;
+ delete[] key;
+ return false;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+ rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jval_len);
+
+ rocksdb::Status s;
+ if (cf_handle != nullptr) {
+ s = db->Put(write_options, cf_handle, key_slice, value_slice);
+ } else {
+ // backwards compatibility
+ s = db->Put(write_options, key_slice, value_slice);
+ }
+
+ // cleanup
+ delete[] value;
+ delete[] key;
+
+ if (s.ok()) {
+ return true;
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return false;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: put
+ * Signature: (J[BII[BII)V
+ */
+void Java_org_rocksdb_RocksDB_put__J_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ rocksdb_put_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
+ jkey_len, jval, jval_off, jval_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: put
+ * Signature: (J[BII[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_put__J_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len,
+ jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_put_helper(env, db, default_write_options, cf_handle, jkey,
+ jkey_off, jkey_len, jval, jval_off, jval_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: put
+ * Signature: (JJ[BII[BII)V
+ */
+void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jlong jwrite_options_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ rocksdb_put_helper(env, db, *write_options, nullptr, jkey, jkey_off, jkey_len,
+ jval, jval_off, jval_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: put
+ * Signature: (JJ[BII[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len,
+ jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_put_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
+ jkey_len, jval, jval_off, jval_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::Delete()
+
+/**
+ * @return true if the delete succeeded, false if a Java Exception was thrown
+ */
+bool rocksdb_delete_helper(
+ JNIEnv* env, rocksdb::DB* db, const rocksdb::WriteOptions& write_options,
+ rocksdb::ColumnFamilyHandle* cf_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len) {
+ jbyte* key = new jbyte[jkey_len];
+ env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] key;
+ return false;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ rocksdb::Status s;
+ if (cf_handle != nullptr) {
+ s = db->Delete(write_options, cf_handle, key_slice);
+ } else {
+ // backwards compatibility
+ s = db->Delete(write_options, key_slice);
+ }
+
+ // cleanup
+ delete[] key;
+
+ if (s.ok()) {
+ return true;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return false;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: delete
+ * Signature: (J[BII)V
+ */
+void Java_org_rocksdb_RocksDB_delete__J_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ rocksdb_delete_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
+ jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: delete
+ * Signature: (J[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_delete__J_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_delete_helper(env, db, default_write_options, cf_handle, jkey,
+ jkey_off, jkey_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: delete
+ * Signature: (JJ[BII)V
+ */
+void Java_org_rocksdb_RocksDB_delete__JJ_3BII(
+ JNIEnv* env, jobject,
+ jlong jdb_handle,
+ jlong jwrite_options,
+ jbyteArray jkey, jint jkey_off, jint jkey_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
+ rocksdb_delete_helper(env, db, *write_options, nullptr, jkey, jkey_off,
+ jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: delete
+ * Signature: (JJ[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_delete__JJ_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
+ jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_delete_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
+ jkey_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::SingleDelete()
+/**
+ * @return true if the single delete succeeded, false if a Java Exception
+ * was thrown
+ */
+bool rocksdb_single_delete_helper(
+ JNIEnv* env, rocksdb::DB* db,
+ const rocksdb::WriteOptions& write_options,
+ rocksdb::ColumnFamilyHandle* cf_handle,
+ jbyteArray jkey, jint jkey_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return false;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ rocksdb::Status s;
+ if (cf_handle != nullptr) {
+ s = db->SingleDelete(write_options, cf_handle, key_slice);
+ } else {
+ // backwards compatibility
+ s = db->SingleDelete(write_options, key_slice);
+ }
+
+ // trigger java unref on key and value.
+ // by passing JNI_ABORT, it will simply release the reference without
+ // copying the result back to the java byte array.
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+
+ if (s.ok()) {
+ return true;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return false;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: singleDelete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_RocksDB_singleDelete__J_3BI(
+ JNIEnv* env, jobject,
+ jlong jdb_handle,
+ jbyteArray jkey,
+ jint jkey_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ rocksdb_single_delete_helper(env, db, default_write_options, nullptr,
+ jkey, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: singleDelete
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_RocksDB_singleDelete__J_3BIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_single_delete_helper(env, db, default_write_options, cf_handle,
+ jkey, jkey_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: singleDelete
+ * Signature: (JJ[BIJ)V
+ */
+void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BI(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jlong jwrite_options,
+ jbyteArray jkey,
+ jint jkey_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
+ rocksdb_single_delete_helper(env, db, *write_options, nullptr, jkey,
+ jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: singleDelete
+ * Signature: (JJ[BIJ)V
+ */
+void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
+ jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_single_delete_helper(env, db, *write_options, cf_handle, jkey,
+ jkey_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::DeleteRange()
+/**
+ * @return true if the delete range succeeded, false if a Java Exception
+ * was thrown
+ */
+bool rocksdb_delete_range_helper(
+ JNIEnv* env, rocksdb::DB* db,
+ const rocksdb::WriteOptions& write_options,
+ rocksdb::ColumnFamilyHandle* cf_handle,
+ jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
+ jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
+ jbyte* begin_key = new jbyte[jbegin_key_len];
+ env->GetByteArrayRegion(jbegin_key, jbegin_key_off, jbegin_key_len,
+ begin_key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] begin_key;
+ return false;
+ }
+ rocksdb::Slice begin_key_slice(reinterpret_cast<char*>(begin_key),
+ jbegin_key_len);
+
+ jbyte* end_key = new jbyte[jend_key_len];
+ env->GetByteArrayRegion(jend_key, jend_key_off, jend_key_len, end_key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] begin_key;
+ delete[] end_key;
+ return false;
+ }
+ rocksdb::Slice end_key_slice(reinterpret_cast<char*>(end_key), jend_key_len);
+
+ rocksdb::Status s =
+ db->DeleteRange(write_options, cf_handle, begin_key_slice, end_key_slice);
+
+ // cleanup
+ delete[] begin_key;
+ delete[] end_key;
+
+ if (s.ok()) {
+ return true;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return false;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: deleteRange
+ * Signature: (J[BII[BII)V
+ */
+void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
+ jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ rocksdb_delete_range_helper(env, db, default_write_options, nullptr,
+ jbegin_key, jbegin_key_off, jbegin_key_len,
+ jend_key, jend_key_off, jend_key_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: deleteRange
+ * Signature: (J[BII[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
+ jbyteArray jend_key, jint jend_key_off, jint jend_key_len,
+ jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_delete_range_helper(env, db, default_write_options, cf_handle,
+ jbegin_key, jbegin_key_off, jbegin_key_len,
+ jend_key, jend_key_off, jend_key_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: deleteRange
+ * Signature: (JJ[BII[BII)V
+ */
+void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
+ jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
+ jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
+ rocksdb_delete_range_helper(env, db, *write_options, nullptr, jbegin_key,
+ jbegin_key_off, jbegin_key_len, jend_key,
+ jend_key_off, jend_key_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: deleteRange
+ * Signature: (JJ[BII[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
+ jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
+ jbyteArray jend_key, jint jend_key_off, jint jend_key_len,
+ jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_delete_range_helper(env, db, *write_options, cf_handle,
+ jbegin_key, jbegin_key_off, jbegin_key_len,
+ jend_key, jend_key_off, jend_key_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::Merge
+
+/**
+ * @return true if the merge succeeded, false if a Java Exception was thrown
+ */
+bool rocksdb_merge_helper(
+ JNIEnv* env, rocksdb::DB* db, const rocksdb::WriteOptions& write_options,
+ rocksdb::ColumnFamilyHandle* cf_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ jbyte* key = new jbyte[jkey_len];
+ env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] key;
+ return false;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ jbyte* value = new jbyte[jval_len];
+ env->GetByteArrayRegion(jval, jval_off, jval_len, value);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] value;
+ delete[] key;
+ return false;
+ }
+ rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jval_len);
+
+ rocksdb::Status s;
+ if (cf_handle != nullptr) {
+ s = db->Merge(write_options, cf_handle, key_slice, value_slice);
+ } else {
+ s = db->Merge(write_options, key_slice, value_slice);
+ }
+
+ // cleanup
+ delete[] value;
+ delete[] key;
+
+ if (s.ok()) {
+ return true;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return false;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: merge
+ * Signature: (J[BII[BII)V
+ */
+void Java_org_rocksdb_RocksDB_merge__J_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ rocksdb_merge_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
+ jkey_len, jval, jval_off, jval_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: merge
+ * Signature: (J[BII[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_merge__J_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len,
+ jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ static const rocksdb::WriteOptions default_write_options =
+ rocksdb::WriteOptions();
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_merge_helper(env, db, default_write_options, cf_handle, jkey,
+ jkey_off, jkey_len, jval, jval_off, jval_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: merge
+ * Signature: (JJ[BII[BII)V
+ */
+void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ rocksdb_merge_helper(env, db, *write_options, nullptr, jkey, jkey_off,
+ jkey_len, jval, jval_off, jval_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: merge
+ * Signature: (JJ[BII[BIIJ)V
+ */
+void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ rocksdb_merge_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
+ jkey_len, jval, jval_off, jval_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ }
+}
+
+jlong rocksdb_iterator_helper(rocksdb::DB* db,
+ rocksdb::ReadOptions read_options,
+ rocksdb::ColumnFamilyHandle* cf_handle) {
+ rocksdb::Iterator* iterator = nullptr;
+ if (cf_handle != nullptr) {
+ iterator = db->NewIterator(read_options, cf_handle);
+ } else {
+ iterator = db->NewIterator(read_options);
+ }
+ return reinterpret_cast<jlong>(iterator);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::Write
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: write0
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_RocksDB_write0(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jlong jwrite_options_handle, jlong jwb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+
+ rocksdb::Status s = db->Write(*write_options, wb);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: write1
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_RocksDB_write1(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jlong jwrite_options_handle, jlong jwbwi_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* wb = wbwi->GetWriteBatch();
+
+ rocksdb::Status s = db->Write(*write_options, wb);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::Get
+
+jbyteArray rocksdb_get_helper(
+ JNIEnv* env, rocksdb::DB* db,
+ const rocksdb::ReadOptions& read_opt,
+ rocksdb::ColumnFamilyHandle* column_family_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len) {
+ jbyte* key = new jbyte[jkey_len];
+ env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] key;
+ return nullptr;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ std::string value;
+ rocksdb::Status s;
+ if (column_family_handle != nullptr) {
+ s = db->Get(read_opt, column_family_handle, key_slice, &value);
+ } else {
+ // backwards compatibility
+ s = db->Get(read_opt, key_slice, &value);
+ }
+
+ // cleanup
+ delete[] key;
+
+ if (s.IsNotFound()) {
+ return nullptr;
+ }
+
+ if (s.ok()) {
+ jbyteArray jret_value = rocksdb::JniUtil::copyBytes(env, value);
+ if (jret_value == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+ return jret_value;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (J[BII)[B
+ */
+jbyteArray Java_org_rocksdb_RocksDB_get__J_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len) {
+ return rocksdb_get_helper(env, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ rocksdb::ReadOptions(), nullptr, jkey, jkey_off, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (J[BIIJ)[B
+ */
+jbyteArray Java_org_rocksdb_RocksDB_get__J_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
+ auto db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ return rocksdb_get_helper(env, db_handle, rocksdb::ReadOptions(), cf_handle,
+ jkey, jkey_off, jkey_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ return nullptr;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (JJ[BII)[B
+ */
+jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BII(
+ JNIEnv* env, jobject,
+ jlong jdb_handle, jlong jropt_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len) {
+ return rocksdb_get_helper(
+ env, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), nullptr, jkey,
+ jkey_off, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (JJ[BIIJ)[B
+ */
+jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
+ auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto& ro_opt = *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ return rocksdb_get_helper(
+ env, db_handle, ro_opt, cf_handle, jkey, jkey_off, jkey_len);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ return nullptr;
+ }
+}
+
+jint rocksdb_get_helper(
+ JNIEnv* env, rocksdb::DB* db, const rocksdb::ReadOptions& read_options,
+ rocksdb::ColumnFamilyHandle* column_family_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len,
+ bool* has_exception) {
+ static const int kNotFound = -1;
+ static const int kStatusError = -2;
+
+ jbyte* key = new jbyte[jkey_len];
+ env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ delete[] key;
+ *has_exception = true;
+ return kStatusError;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ // TODO(yhchiang): we might save one memory allocation here by adding
+ // a DB::Get() function which takes preallocated jbyte* as input.
+ std::string cvalue;
+ rocksdb::Status s;
+ if (column_family_handle != nullptr) {
+ s = db->Get(read_options, column_family_handle, key_slice, &cvalue);
+ } else {
+ // backwards compatibility
+ s = db->Get(read_options, key_slice, &cvalue);
+ }
+
+ // cleanup
+ delete[] key;
+
+ if (s.IsNotFound()) {
+ *has_exception = false;
+ return kNotFound;
+ } else if (!s.ok()) {
+ *has_exception = true;
+ // Here since we are throwing a Java exception from c++ side.
+ // As a result, c++ does not know calling this function will in fact
+ // throwing an exception. As a result, the execution flow will
+ // not stop here, and codes after this throw will still be
+ // executed.
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+
+ // Return a dummy const value to avoid compilation error, although
+ // java side might not have a chance to get the return value :)
+ return kStatusError;
+ }
+
+ const jint cvalue_len = static_cast<jint>(cvalue.size());
+ const jint length = std::min(jval_len, cvalue_len);
+
+ env->SetByteArrayRegion(
+ jval, jval_off, length,
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(cvalue.c_str())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: OutOfMemoryError
+ *has_exception = true;
+ return kStatusError;
+ }
+
+ *has_exception = false;
+ return cvalue_len;
+}
+
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (J[BII[BII)I
+ */
+jint Java_org_rocksdb_RocksDB_get__J_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ bool has_exception = false;
+ return rocksdb_get_helper(env, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ rocksdb::ReadOptions(), nullptr, jkey, jkey_off,
+ jkey_len, jval, jval_off, jval_len, &has_exception);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (J[BII[BIIJ)I
+ */
+jint Java_org_rocksdb_RocksDB_get__J_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len,
+ jlong jcf_handle) {
+ auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ bool has_exception = false;
+ return rocksdb_get_helper(env, db_handle, rocksdb::ReadOptions(), cf_handle,
+ jkey, jkey_off, jkey_len, jval, jval_off,
+ jval_len, &has_exception);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ // will never be evaluated
+ return 0;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (JJ[BII[BII)I
+ */
+jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BII(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len) {
+ bool has_exception = false;
+ return rocksdb_get_helper(
+ env, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), nullptr, jkey,
+ jkey_off, jkey_len, jval, jval_off, jval_len, &has_exception);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: get
+ * Signature: (JJ[BII[BIIJ)I
+ */
+jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BIIJ(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jbyteArray jval, jint jval_off, jint jval_len,
+ jlong jcf_handle) {
+ auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto& ro_opt = *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ bool has_exception = false;
+ return rocksdb_get_helper(env, db_handle, ro_opt, cf_handle,
+ jkey, jkey_off, jkey_len,
+ jval, jval_off, jval_len,
+ &has_exception);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ // will never be evaluated
+ return 0;
+ }
+}
+
+inline void multi_get_helper_release_keys(
+ JNIEnv* env, std::vector<std::pair<jbyte*, jobject>>& keys_to_free) {
+ auto end = keys_to_free.end();
+ for (auto it = keys_to_free.begin(); it != end; ++it) {
+ delete[] it->first;
+ env->DeleteLocalRef(it->second);
+ }
+ keys_to_free.clear();
+}
+
+/**
+ * cf multi get
+ *
+ * @return byte[][] of values or nullptr if an exception occurs
+ */
+jobjectArray multi_get_helper(
+ JNIEnv* env, jobject, rocksdb::DB* db, const rocksdb::ReadOptions& rOpt,
+ jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens,
+ jlongArray jcolumn_family_handles) {
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ if (jcolumn_family_handles != nullptr) {
+ const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
+
+ jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
+ if (jcfh == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ for (jsize i = 0; i < len_cols; i++) {
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]);
+ cf_handles.push_back(cf_handle);
+ }
+ env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
+ }
+
+ const jsize len_keys = env->GetArrayLength(jkeys);
+ if (env->EnsureLocalCapacity(len_keys) != 0) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jint* jkey_off = env->GetIntArrayElements(jkey_offs, nullptr);
+ if (jkey_off == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jint* jkey_len = env->GetIntArrayElements(jkey_lens, nullptr);
+ if (jkey_len == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
+ return nullptr;
+ }
+
+ std::vector<rocksdb::Slice> keys;
+ std::vector<std::pair<jbyte*, jobject>> keys_to_free;
+ for (jsize i = 0; i < len_keys; i++) {
+ jobject jkey = env->GetObjectArrayElement(jkeys, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
+ env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
+ multi_get_helper_release_keys(env, keys_to_free);
+ return nullptr;
+ }
+
+ jbyteArray jkey_ba = reinterpret_cast<jbyteArray>(jkey);
+
+ const jint len_key = jkey_len[i];
+ jbyte* key = new jbyte[len_key];
+ env->GetByteArrayRegion(jkey_ba, jkey_off[i], len_key, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] key;
+ env->DeleteLocalRef(jkey);
+ env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
+ env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
+ multi_get_helper_release_keys(env, keys_to_free);
+ return nullptr;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), len_key);
+ keys.push_back(key_slice);
+
+ keys_to_free.push_back(std::pair<jbyte*, jobject>(key, jkey));
+ }
+
+ // cleanup jkey_off and jken_len
+ env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
+ env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
+
+ std::vector<std::string> values;
+ std::vector<rocksdb::Status> s;
+ if (cf_handles.size() == 0) {
+ s = db->MultiGet(rOpt, keys, &values);
+ } else {
+ s = db->MultiGet(rOpt, cf_handles, keys, &values);
+ }
+
+ // free up allocated byte arrays
+ multi_get_helper_release_keys(env, keys_to_free);
+
+ // prepare the results
+ jobjectArray jresults =
+ rocksdb::ByteJni::new2dByteArray(env, static_cast<jsize>(s.size()));
+ if (jresults == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ // TODO(AR) it is not clear to me why EnsureLocalCapacity is needed for the
+ // loop as we cleanup references with env->DeleteLocalRef(jentry_value);
+ if (env->EnsureLocalCapacity(static_cast<jint>(s.size())) != 0) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ // add to the jresults
+ for (std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) {
+ if (s[i].ok()) {
+ std::string* value = &values[i];
+ const jsize jvalue_len = static_cast<jsize>(value->size());
+ jbyteArray jentry_value = env->NewByteArray(jvalue_len);
+ if (jentry_value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(
+ jentry_value, 0, static_cast<jsize>(jvalue_len),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value->c_str())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jentry_value);
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jentry_value);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jentry_value);
+ return nullptr;
+ }
+
+ env->DeleteLocalRef(jentry_value);
+ }
+ }
+
+ return jresults;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: multiGet
+ * Signature: (J[[B[I[I)[[B
+ */
+jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I(
+ JNIEnv* env, jobject jdb, jlong jdb_handle,
+ jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) {
+ return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ rocksdb::ReadOptions(), jkeys, jkey_offs, jkey_lens,
+ nullptr);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: multiGet
+ * Signature: (J[[B[I[I[J)[[B
+ */
+jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I_3J(
+ JNIEnv* env, jobject jdb, jlong jdb_handle,
+ jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens,
+ jlongArray jcolumn_family_handles) {
+ return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ rocksdb::ReadOptions(), jkeys, jkey_offs, jkey_lens,
+ jcolumn_family_handles);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: multiGet
+ * Signature: (JJ[[B[I[I)[[B
+ */
+jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I(
+ JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
+ jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) {
+ return multi_get_helper(
+ env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkeys, jkey_offs,
+ jkey_lens, nullptr);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: multiGet
+ * Signature: (JJ[[B[I[I[J)[[B
+ */
+jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I_3J(
+ JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
+ jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens,
+ jlongArray jcolumn_family_handles) {
+ return multi_get_helper(
+ env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
+ *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkeys, jkey_offs,
+ jkey_lens, jcolumn_family_handles);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// rocksdb::DB::KeyMayExist
+jboolean key_may_exist_helper(JNIEnv* env, rocksdb::DB* db,
+ const rocksdb::ReadOptions& read_opt,
+ rocksdb::ColumnFamilyHandle* cf_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jobject jstring_builder, bool* has_exception) {
+ jbyte* key = new jbyte[jkey_len];
+ env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete[] key;
+ *has_exception = true;
+ return false;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
+
+ std::string value;
+ bool value_found = false;
+ bool keyMayExist;
+ if (cf_handle != nullptr) {
+ keyMayExist =
+ db->KeyMayExist(read_opt, cf_handle, key_slice, &value, &value_found);
+ } else {
+ keyMayExist = db->KeyMayExist(read_opt, key_slice, &value, &value_found);
+ }
+
+ // cleanup
+ delete[] key;
+
+ // extract the value
+ if (value_found && !value.empty()) {
+ jobject jresult_string_builder =
+ rocksdb::StringBuilderJni::append(env, jstring_builder, value.c_str());
+ if (jresult_string_builder == nullptr) {
+ *has_exception = true;
+ return false;
+ }
+ }
+
+ *has_exception = false;
+ return static_cast<jboolean>(keyMayExist);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: keyMayExist
+ * Signature: (J[BIILjava/lang/StringBuilder;)Z
+ */
+jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BIILjava_lang_StringBuilder_2(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len, jobject jstring_builder) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ bool has_exception = false;
+ return key_may_exist_helper(env, db, rocksdb::ReadOptions(), nullptr, jkey,
+ jkey_off, jkey_len, jstring_builder, &has_exception);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: keyMayExist
+ * Signature: (J[BIIJLjava/lang/StringBuilder;)Z
+ */
+jboolean
+Java_org_rocksdb_RocksDB_keyMayExist__J_3BIIJLjava_lang_StringBuilder_2(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len,
+ jlong jcf_handle, jobject jstring_builder) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ bool has_exception = false;
+ return key_may_exist_helper(env, db, rocksdb::ReadOptions(), cf_handle,
+ jkey, jkey_off, jkey_len, jstring_builder,
+ &has_exception);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ return true;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: keyMayExist
+ * Signature: (JJ[BIILjava/lang/StringBuilder;)Z
+ */
+jboolean
+Java_org_rocksdb_RocksDB_keyMayExist__JJ_3BIILjava_lang_StringBuilder_2(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jread_options_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len, jobject jstring_builder) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto& read_options =
+ *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ bool has_exception = false;
+ return key_may_exist_helper(env, db, read_options, nullptr, jkey, jkey_off,
+ jkey_len, jstring_builder, &has_exception);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: keyMayExist
+ * Signature: (JJ[BIIJLjava/lang/StringBuilder;)Z
+ */
+jboolean
+Java_org_rocksdb_RocksDB_keyMayExist__JJ_3BIIJLjava_lang_StringBuilder_2(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jread_options_handle,
+ jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle,
+ jobject jstring_builder) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto& read_options =
+ *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ if (cf_handle != nullptr) {
+ bool has_exception = false;
+ return key_may_exist_helper(env, db, read_options, cf_handle, jkey,
+ jkey_off, jkey_len, jstring_builder, &has_exception);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle."));
+ return true;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: iterator
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RocksDB_iterator__J(
+ JNIEnv*, jobject, jlong db_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ return rocksdb_iterator_helper(db, rocksdb::ReadOptions(), nullptr);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: iterator
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_RocksDB_iterator__JJ(
+ JNIEnv*, jobject, jlong db_handle, jlong jread_options_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto& read_options =
+ *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ return rocksdb_iterator_helper(db, read_options, nullptr);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: iteratorCF
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_RocksDB_iteratorCF__JJ(
+ JNIEnv*, jobject, jlong db_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ return rocksdb_iterator_helper(db, rocksdb::ReadOptions(), cf_handle);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: iteratorCF
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_RocksDB_iteratorCF__JJJ(
+ JNIEnv*, jobject,
+ jlong db_handle, jlong jcf_handle, jlong jread_options_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ auto& read_options =
+ *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ return rocksdb_iterator_helper(db, read_options, cf_handle);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: iterators
+ * Signature: (J[JJ)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_iterators(
+ JNIEnv* env, jobject, jlong db_handle,
+ jlongArray jcolumn_family_handles,
+ jlong jread_options_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto& read_options =
+ *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ if (jcolumn_family_handles != nullptr) {
+ const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
+ jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
+ if (jcfh == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ for (jsize i = 0; i < len_cols; i++) {
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]);
+ cf_handles.push_back(cf_handle);
+ }
+
+ env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
+ }
+
+ std::vector<rocksdb::Iterator*> iterators;
+ rocksdb::Status s = db->NewIterators(read_options, cf_handles, &iterators);
+ if (s.ok()) {
+ jlongArray jLongArray =
+ env->NewLongArray(static_cast<jsize>(iterators.size()));
+ if (jLongArray == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ for (std::vector<rocksdb::Iterator*>::size_type i = 0; i < iterators.size();
+ i++) {
+ env->SetLongArrayRegion(
+ jLongArray, static_cast<jsize>(i), 1,
+ const_cast<jlong*>(reinterpret_cast<const jlong*>(&iterators[i])));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jLongArray);
+ return nullptr;
+ }
+ }
+
+ return jLongArray;
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+}
+
+/*
+ * Method: getSnapshot
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RocksDB_getSnapshot(
+ JNIEnv*, jobject, jlong db_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ const rocksdb::Snapshot* snapshot = db->GetSnapshot();
+ return reinterpret_cast<jlong>(snapshot);
+}
+
+/*
+ * Method: releaseSnapshot
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_RocksDB_releaseSnapshot(
+ JNIEnv*, jobject, jlong db_handle,
+ jlong snapshot_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ auto* snapshot = reinterpret_cast<rocksdb::Snapshot*>(snapshot_handle);
+ db->ReleaseSnapshot(snapshot);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getProperty
+ * Signature: (JJLjava/lang/String;I)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_RocksDB_getProperty(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jstring jproperty, jint jproperty_len) {
+ const char* property = env->GetStringUTFChars(jproperty, nullptr);
+ if (property == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ rocksdb::Slice property_name(property, jproperty_len);
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ std::string property_value;
+ bool retCode = db->GetProperty(cf_handle, property_name, &property_value);
+ env->ReleaseStringUTFChars(jproperty, property);
+
+ if (retCode) {
+ return env->NewStringUTF(property_value.c_str());
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound());
+ return nullptr;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getMapProperty
+ * Signature: (JJLjava/lang/String;I)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_RocksDB_getMapProperty(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jstring jproperty, jint jproperty_len) {
+ const char* property = env->GetStringUTFChars(jproperty, nullptr);
+ if (property == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ rocksdb::Slice property_name(property, jproperty_len);
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ std::map<std::string, std::string> property_value;
+ bool retCode = db->GetMapProperty(cf_handle, property_name, &property_value);
+ env->ReleaseStringUTFChars(jproperty, property);
+
+ if (retCode) {
+ return rocksdb::HashMapJni::fromCppMap(env, &property_value);
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound());
+ return nullptr;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getLongProperty
+ * Signature: (JJLjava/lang/String;I)J
+ */
+jlong Java_org_rocksdb_RocksDB_getLongProperty(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jstring jproperty, jint jproperty_len) {
+ const char* property = env->GetStringUTFChars(jproperty, nullptr);
+ if (property == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ rocksdb::Slice property_name(property, jproperty_len);
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ uint64_t property_value;
+ bool retCode = db->GetIntProperty(cf_handle, property_name, &property_value);
+ env->ReleaseStringUTFChars(jproperty, property);
+
+ if (retCode) {
+ return property_value;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound());
+ return 0;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: resetStats
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_resetStats(
+ JNIEnv *, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ db->ResetStats();
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getAggregatedLongProperty
+ * Signature: (JLjava/lang/String;I)J
+ */
+jlong Java_org_rocksdb_RocksDB_getAggregatedLongProperty(
+ JNIEnv* env, jobject, jlong db_handle,
+ jstring jproperty, jint jproperty_len) {
+ const char* property = env->GetStringUTFChars(jproperty, nullptr);
+ if (property == nullptr) {
+ return 0;
+ }
+ rocksdb::Slice property_name(property, jproperty_len);
+ auto* db = reinterpret_cast<rocksdb::DB*>(db_handle);
+ uint64_t property_value = 0;
+ bool retCode = db->GetAggregatedIntProperty(property_name, &property_value);
+ env->ReleaseStringUTFChars(jproperty, property);
+
+ if (retCode) {
+ return property_value;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound());
+ return 0;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getApproximateSizes
+ * Signature: (JJ[JB)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_getApproximateSizes(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jlongArray jrange_slice_handles, jbyte jinclude_flags) {
+ const jsize jlen = env->GetArrayLength(jrange_slice_handles);
+ const size_t range_count = jlen / 2;
+
+ jboolean jranges_is_copy = JNI_FALSE;
+ jlong* jranges = env->GetLongArrayElements(jrange_slice_handles,
+ &jranges_is_copy);
+ if (jranges == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ auto ranges = std::unique_ptr<rocksdb::Range[]>(
+ new rocksdb::Range[range_count]);
+ for (jsize i = 0; i < jlen; ++i) {
+ auto* start = reinterpret_cast<rocksdb::Slice*>(jranges[i]);
+ auto* limit = reinterpret_cast<rocksdb::Slice*>(jranges[++i]);
+ ranges.get()[i] = rocksdb::Range(*start, *limit);
+ }
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ auto sizes = std::unique_ptr<uint64_t[]>(new uint64_t[range_count]);
+ db->GetApproximateSizes(cf_handle, ranges.get(),
+ static_cast<int>(range_count), sizes.get(),
+ static_cast<uint8_t>(jinclude_flags));
+
+ // release LongArrayElements
+ env->ReleaseLongArrayElements(jrange_slice_handles, jranges, JNI_ABORT);
+
+ // prepare results
+ auto results = std::unique_ptr<jlong[]>(new jlong[range_count]);
+ for (size_t i = 0; i < range_count; ++i) {
+ results.get()[i] = static_cast<jlong>(sizes.get()[i]);
+ }
+
+ const jsize jrange_count = jlen / 2;
+ jlongArray jresults = env->NewLongArray(jrange_count);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetLongArrayRegion(jresults, 0, jrange_count, results.get());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jresults);
+ return nullptr;
+ }
+
+ return jresults;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getApproximateMemTableStats
+ * Signature: (JJJJ)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_getApproximateMemTableStats(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jlong jstartHandle, jlong jlimitHandle) {
+ auto* start = reinterpret_cast<rocksdb::Slice*>(jstartHandle);
+ auto* limit = reinterpret_cast<rocksdb::Slice*>( jlimitHandle);
+ const rocksdb::Range range(*start, *limit);
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ uint64_t count = 0;
+ uint64_t sizes = 0;
+ db->GetApproximateMemTableStats(cf_handle, range, &count, &sizes);
+
+ // prepare results
+ jlong results[2] = {
+ static_cast<jlong>(count),
+ static_cast<jlong>(sizes)};
+
+ const jsize jcount = static_cast<jsize>(count);
+ jlongArray jsizes = env->NewLongArray(jcount);
+ if (jsizes == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetLongArrayRegion(jsizes, 0, jcount, results);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jsizes);
+ return nullptr;
+ }
+
+ return jsizes;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: compactRange
+ * Signature: (J[BI[BIJJ)V
+ */
+void Java_org_rocksdb_RocksDB_compactRange(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jbyteArray jbegin, jint jbegin_len,
+ jbyteArray jend, jint jend_len,
+ jlong jcompact_range_opts_handle,
+ jlong jcf_handle) {
+ jboolean has_exception = JNI_FALSE;
+
+ std::string str_begin;
+ if (jbegin_len > 0) {
+ str_begin = rocksdb::JniUtil::byteString<std::string>(env, jbegin, jbegin_len,
+ [](const char* str, const size_t len) {
+ return std::string(str, len);
+ },
+ &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+ }
+
+ std::string str_end;
+ if (jend_len > 0) {
+ str_end = rocksdb::JniUtil::byteString<std::string>(env, jend, jend_len,
+ [](const char* str, const size_t len) {
+ return std::string(str, len);
+ },
+ &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+ }
+
+ rocksdb::CompactRangeOptions *compact_range_opts = nullptr;
+ if (jcompact_range_opts_handle == 0) {
+ // NOTE: we DO own the pointer!
+ compact_range_opts = new rocksdb::CompactRangeOptions();
+ } else {
+ // NOTE: we do NOT own the pointer!
+ compact_range_opts =
+ reinterpret_cast<rocksdb::CompactRangeOptions*>(jcompact_range_opts_handle);
+ }
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ rocksdb::Status s;
+ if (jbegin_len > 0 || jend_len > 0) {
+ const rocksdb::Slice begin(str_begin);
+ const rocksdb::Slice end(str_end);
+ s = db->CompactRange(*compact_range_opts, cf_handle, &begin, &end);
+ } else {
+ s = db->CompactRange(*compact_range_opts, cf_handle, nullptr, nullptr);
+ }
+
+ if (jcompact_range_opts_handle == 0) {
+ delete compact_range_opts;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: setOptions
+ * Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)V
+ */
+void Java_org_rocksdb_RocksDB_setOptions(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jobjectArray jkeys, jobjectArray jvalues) {
+ const jsize len = env->GetArrayLength(jkeys);
+ assert(len == env->GetArrayLength(jvalues));
+
+ std::unordered_map<std::string, std::string> options_map;
+ for (jsize i = 0; i < len; i++) {
+ jobject jobj_key = env->GetObjectArrayElement(jkeys, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ return;
+ }
+
+ jobject jobj_value = env->GetObjectArrayElement(jvalues, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jobj_key);
+ return;
+ }
+
+ jboolean has_exception = JNI_FALSE;
+ std::string s_key =
+ rocksdb::JniUtil::copyStdString(
+ env, reinterpret_cast<jstring>(jobj_key), &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->DeleteLocalRef(jobj_value);
+ env->DeleteLocalRef(jobj_key);
+ return;
+ }
+
+ std::string s_value =
+ rocksdb::JniUtil::copyStdString(
+ env, reinterpret_cast<jstring>(jobj_value), &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->DeleteLocalRef(jobj_value);
+ env->DeleteLocalRef(jobj_key);
+ return;
+ }
+
+ options_map[s_key] = s_value;
+
+ env->DeleteLocalRef(jobj_key);
+ env->DeleteLocalRef(jobj_value);
+ }
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ auto s = db->SetOptions(cf_handle, options_map);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: setDBOptions
+ * Signature: (J[Ljava/lang/String;[Ljava/lang/String;)V
+ */
+void Java_org_rocksdb_RocksDB_setDBOptions(
+ JNIEnv* env, jobject, jlong jdb_handle,
+ jobjectArray jkeys, jobjectArray jvalues) {
+ const jsize len = env->GetArrayLength(jkeys);
+ assert(len == env->GetArrayLength(jvalues));
+
+ std::unordered_map<std::string, std::string> options_map;
+ for (jsize i = 0; i < len; i++) {
+ jobject jobj_key = env->GetObjectArrayElement(jkeys, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ return;
+ }
+
+ jobject jobj_value = env->GetObjectArrayElement(jvalues, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jobj_key);
+ return;
+ }
+
+ jboolean has_exception = JNI_FALSE;
+ std::string s_key =
+ rocksdb::JniUtil::copyStdString(
+ env, reinterpret_cast<jstring>(jobj_key), &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->DeleteLocalRef(jobj_value);
+ env->DeleteLocalRef(jobj_key);
+ return;
+ }
+
+ std::string s_value =
+ rocksdb::JniUtil::copyStdString(
+ env, reinterpret_cast<jstring>(jobj_value), &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->DeleteLocalRef(jobj_value);
+ env->DeleteLocalRef(jobj_key);
+ return;
+ }
+
+ options_map[s_key] = s_value;
+
+ env->DeleteLocalRef(jobj_key);
+ env->DeleteLocalRef(jobj_value);
+ }
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->SetDBOptions(options_map);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: compactFiles
+ * Signature: (JJJ[Ljava/lang/String;IIJ)[Ljava/lang/String;
+ */
+jobjectArray Java_org_rocksdb_RocksDB_compactFiles(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcompaction_opts_handle,
+ jlong jcf_handle, jobjectArray jinput_file_names, jint joutput_level,
+ jint joutput_path_id, jlong jcompaction_job_info_handle) {
+ jboolean has_exception = JNI_FALSE;
+ const std::vector<std::string> input_file_names =
+ rocksdb::JniUtil::copyStrings(env, jinput_file_names, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return nullptr;
+ }
+
+ auto* compaction_opts =
+ reinterpret_cast<rocksdb::CompactionOptions*>(jcompaction_opts_handle);
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+
+ rocksdb::CompactionJobInfo* compaction_job_info = nullptr;
+ if (jcompaction_job_info_handle != 0) {
+ compaction_job_info =
+ reinterpret_cast<rocksdb::CompactionJobInfo*>(jcompaction_job_info_handle);
+ }
+
+ std::vector<std::string> output_file_names;
+ auto s = db->CompactFiles(*compaction_opts, cf_handle, input_file_names,
+ static_cast<int>(joutput_level), static_cast<int>(joutput_path_id),
+ &output_file_names, compaction_job_info);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ return rocksdb::JniUtil::toJavaStrings(env, &output_file_names);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: pauseBackgroundWork
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_pauseBackgroundWork(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->PauseBackgroundWork();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: continueBackgroundWork
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_continueBackgroundWork(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->ContinueBackgroundWork();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: enableAutoCompaction
+ * Signature: (J[J)V
+ */
+void Java_org_rocksdb_RocksDB_enableAutoCompaction(
+ JNIEnv* env, jobject, jlong jdb_handle, jlongArray jcf_handles) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ jboolean has_exception = JNI_FALSE;
+ const std::vector<rocksdb::ColumnFamilyHandle*> cf_handles =
+ rocksdb::JniUtil::fromJPointers<rocksdb::ColumnFamilyHandle>(env, jcf_handles, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+ db->EnableAutoCompaction(cf_handles);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: numberLevels
+ * Signature: (JJ)I
+ */
+jint Java_org_rocksdb_RocksDB_numberLevels(
+ JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ return static_cast<jint>(db->NumberLevels(cf_handle));
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: maxMemCompactionLevel
+ * Signature: (JJ)I
+ */
+jint Java_org_rocksdb_RocksDB_maxMemCompactionLevel(
+ JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ return static_cast<jint>(db->MaxMemCompactionLevel(cf_handle));
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: level0StopWriteTrigger
+ * Signature: (JJ)I
+ */
+jint Java_org_rocksdb_RocksDB_level0StopWriteTrigger(
+ JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ return static_cast<jint>(db->Level0StopWriteTrigger(cf_handle));
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getName
+ * Signature: (J)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_RocksDB_getName(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ std::string name = db->GetName();
+ return rocksdb::JniUtil::toJavaString(env, &name, false);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getEnv
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RocksDB_getEnv(
+ JNIEnv*, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ return reinterpret_cast<jlong>(db->GetEnv());
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: flush
+ * Signature: (JJ[J)V
+ */
+void Java_org_rocksdb_RocksDB_flush(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jflush_opts_handle,
+ jlongArray jcf_handles) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* flush_opts =
+ reinterpret_cast<rocksdb::FlushOptions*>(jflush_opts_handle);
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ if (jcf_handles == nullptr) {
+ cf_handles.push_back(db->DefaultColumnFamily());
+ } else {
+ jboolean has_exception = JNI_FALSE;
+ cf_handles =
+ rocksdb::JniUtil::fromJPointers<rocksdb::ColumnFamilyHandle>(
+ env, jcf_handles, &has_exception);
+ if (has_exception) {
+ // exception occurred
+ return;
+ }
+ }
+ auto s = db->Flush(*flush_opts, cf_handles);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: flushWal
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_RocksDB_flushWal(
+ JNIEnv* env, jobject, jlong jdb_handle, jboolean jsync) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->FlushWAL(jsync == JNI_TRUE);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: syncWal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_syncWal(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->SyncWAL();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getLatestSequenceNumber
+ * Signature: (J)V
+ */
+jlong Java_org_rocksdb_RocksDB_getLatestSequenceNumber(
+ JNIEnv*, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ return db->GetLatestSequenceNumber();
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: setPreserveDeletesSequenceNumber
+ * Signature: (JJ)Z
+ */
+jboolean JNICALL Java_org_rocksdb_RocksDB_setPreserveDeletesSequenceNumber(
+ JNIEnv*, jobject, jlong jdb_handle, jlong jseq_number) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ if (db->SetPreserveDeletesSequenceNumber(
+ static_cast<uint64_t>(jseq_number))) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: disableFileDeletions
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_disableFileDeletions(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::Status s = db->DisableFileDeletions();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: enableFileDeletions
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_RocksDB_enableFileDeletions(
+ JNIEnv* env, jobject, jlong jdb_handle, jboolean jforce) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::Status s = db->EnableFileDeletions(jforce);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getLiveFiles
+ * Signature: (JZ)[Ljava/lang/String;
+ */
+jobjectArray Java_org_rocksdb_RocksDB_getLiveFiles(
+ JNIEnv* env, jobject, jlong jdb_handle, jboolean jflush_memtable) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ std::vector<std::string> live_files;
+ uint64_t manifest_file_size = 0;
+ auto s = db->GetLiveFiles(
+ live_files, &manifest_file_size, jflush_memtable == JNI_TRUE);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ // append the manifest_file_size to the vector
+ // for passing back to java
+ live_files.push_back(std::to_string(manifest_file_size));
+
+ return rocksdb::JniUtil::toJavaStrings(env, &live_files);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getSortedWalFiles
+ * Signature: (J)[Lorg/rocksdb/LogFile;
+ */
+jobjectArray Java_org_rocksdb_RocksDB_getSortedWalFiles(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ std::vector<std::unique_ptr<rocksdb::LogFile>> sorted_wal_files;
+ auto s = db->GetSortedWalFiles(sorted_wal_files);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ // convert to Java type
+ const jsize jlen = static_cast<jsize>(sorted_wal_files.size());
+ jobjectArray jsorted_wal_files = env->NewObjectArray(
+ jlen, rocksdb::LogFileJni::getJClass(env), nullptr);
+ if(jsorted_wal_files == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jsize i = 0;
+ for (auto it = sorted_wal_files.begin(); it != sorted_wal_files.end(); ++it) {
+ jobject jlog_file = rocksdb::LogFileJni::fromCppLogFile(env, it->get());
+ if (jlog_file == nullptr) {
+ // exception occurred
+ env->DeleteLocalRef(jsorted_wal_files);
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(jsorted_wal_files, i++, jlog_file);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ env->DeleteLocalRef(jlog_file);
+ env->DeleteLocalRef(jsorted_wal_files);
+ return nullptr;
+ }
+
+ env->DeleteLocalRef(jlog_file);
+ }
+
+ return jsorted_wal_files;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getUpdatesSince
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_RocksDB_getUpdatesSince(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jsequence_number) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::SequenceNumber sequence_number =
+ static_cast<rocksdb::SequenceNumber>(jsequence_number);
+ std::unique_ptr<rocksdb::TransactionLogIterator> iter;
+ rocksdb::Status s = db->GetUpdatesSince(sequence_number, &iter);
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(iter.release());
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: deleteFile
+ * Signature: (JLjava/lang/String;)V
+ */
+void Java_org_rocksdb_RocksDB_deleteFile(
+ JNIEnv* env, jobject, jlong jdb_handle, jstring jname) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ jboolean has_exception = JNI_FALSE;
+ std::string name =
+ rocksdb::JniUtil::copyStdString(env, jname, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+ db->DeleteFile(name);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getLiveFilesMetaData
+ * Signature: (J)[Lorg/rocksdb/LiveFileMetaData;
+ */
+jobjectArray Java_org_rocksdb_RocksDB_getLiveFilesMetaData(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ std::vector<rocksdb::LiveFileMetaData> live_files_meta_data;
+ db->GetLiveFilesMetaData(&live_files_meta_data);
+
+ // convert to Java type
+ const jsize jlen = static_cast<jsize>(live_files_meta_data.size());
+ jobjectArray jlive_files_meta_data = env->NewObjectArray(
+ jlen, rocksdb::LiveFileMetaDataJni::getJClass(env), nullptr);
+ if(jlive_files_meta_data == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ jsize i = 0;
+ for (auto it = live_files_meta_data.begin(); it != live_files_meta_data.end(); ++it) {
+ jobject jlive_file_meta_data =
+ rocksdb::LiveFileMetaDataJni::fromCppLiveFileMetaData(env, &(*it));
+ if (jlive_file_meta_data == nullptr) {
+ // exception occurred
+ env->DeleteLocalRef(jlive_files_meta_data);
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(jlive_files_meta_data, i++, jlive_file_meta_data);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ env->DeleteLocalRef(jlive_file_meta_data);
+ env->DeleteLocalRef(jlive_files_meta_data);
+ return nullptr;
+ }
+
+ env->DeleteLocalRef(jlive_file_meta_data);
+ }
+
+ return jlive_files_meta_data;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getColumnFamilyMetaData
+ * Signature: (JJ)Lorg/rocksdb/ColumnFamilyMetaData;
+ */
+jobject Java_org_rocksdb_RocksDB_getColumnFamilyMetaData(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ rocksdb::ColumnFamilyMetaData cf_metadata;
+ db->GetColumnFamilyMetaData(cf_handle, &cf_metadata);
+ return rocksdb::ColumnFamilyMetaDataJni::fromCppColumnFamilyMetaData(
+ env, &cf_metadata);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: ingestExternalFile
+ * Signature: (JJ[Ljava/lang/String;IJ)V
+ */
+void Java_org_rocksdb_RocksDB_ingestExternalFile(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jobjectArray jfile_path_list, jint jfile_path_list_len,
+ jlong jingest_external_file_options_handle) {
+ jboolean has_exception = JNI_FALSE;
+ std::vector<std::string> file_path_list = rocksdb::JniUtil::copyStrings(
+ env, jfile_path_list, jfile_path_list_len, &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return;
+ }
+
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* column_family =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ auto* ifo = reinterpret_cast<rocksdb::IngestExternalFileOptions*>(
+ jingest_external_file_options_handle);
+ rocksdb::Status s =
+ db->IngestExternalFile(column_family, file_path_list, *ifo);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: verifyChecksum
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_RocksDB_verifyChecksum(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->VerifyChecksum();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getDefaultColumnFamily
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_RocksDB_getDefaultColumnFamily(
+ JNIEnv*, jobject, jlong jdb_handle) {
+ auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* cf_handle = db_handle->DefaultColumnFamily();
+ return reinterpret_cast<jlong>(cf_handle);
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getPropertiesOfAllTables
+ * Signature: (JJ)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_RocksDB_getPropertiesOfAllTables(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ rocksdb::TablePropertiesCollection table_properties_collection;
+ auto s = db->GetPropertiesOfAllTables(cf_handle,
+ &table_properties_collection);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+
+ // convert to Java type
+ jobject jhash_map = rocksdb::HashMapJni::construct(
+ env, static_cast<uint32_t>(table_properties_collection.size()));
+ if (jhash_map == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const std::string, const std::shared_ptr<const rocksdb::TableProperties>, jobject, jobject> fn_map_kv =
+ [env](const std::pair<const std::string, const std::shared_ptr<const rocksdb::TableProperties>>& kv) {
+ jstring jkey = rocksdb::JniUtil::toJavaString(env, &(kv.first), false);
+ if (env->ExceptionCheck()) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ jobject jtable_properties = rocksdb::TablePropertiesJni::fromCppTableProperties(env, *(kv.second.get()));
+ if (jtable_properties == nullptr) {
+ // an error occurred
+ env->DeleteLocalRef(jkey);
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+
+ return std::unique_ptr<std::pair<jobject, jobject>>(new std::pair<jobject, jobject>(static_cast<jobject>(jkey), static_cast<jobject>(jtable_properties)));
+ };
+
+ if (!rocksdb::HashMapJni::putAll(env, jhash_map, table_properties_collection.begin(), table_properties_collection.end(), fn_map_kv)) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jhash_map;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: getPropertiesOfTablesInRange
+ * Signature: (JJ[J)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_RocksDB_getPropertiesOfTablesInRange(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
+ jlongArray jrange_slice_handles) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ const jsize jlen = env->GetArrayLength(jrange_slice_handles);
+ jboolean jrange_slice_handles_is_copy = JNI_FALSE;
+ jlong *jrange_slice_handle = env->GetLongArrayElements(
+ jrange_slice_handles, &jrange_slice_handles_is_copy);
+ if (jrange_slice_handle == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const size_t ranges_len = static_cast<size_t>(jlen / 2);
+ auto ranges = std::unique_ptr<rocksdb::Range[]>(new rocksdb::Range[ranges_len]);
+ for (jsize i = 0, j = 0; i < jlen; ++i) {
+ auto* start = reinterpret_cast<rocksdb::Slice*>(
+ jrange_slice_handle[i]);
+ auto* limit = reinterpret_cast<rocksdb::Slice*>(
+ jrange_slice_handle[++i]);
+ ranges[j++] = rocksdb::Range(*start, *limit);
+ }
+
+ rocksdb::TablePropertiesCollection table_properties_collection;
+ auto s = db->GetPropertiesOfTablesInRange(
+ cf_handle, ranges.get(), ranges_len, &table_properties_collection);
+ if (!s.ok()) {
+ // error occurred
+ env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle, JNI_ABORT);
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ // cleanup
+ env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle, JNI_ABORT);
+
+ return jrange_slice_handles;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: suggestCompactRange
+ * Signature: (JJ)[J
+ */
+jlongArray Java_org_rocksdb_RocksDB_suggestCompactRange(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ auto* begin = new rocksdb::Slice();
+ auto* end = new rocksdb::Slice();
+ auto s = db->SuggestCompactRange(cf_handle, begin, end);
+ if (!s.ok()) {
+ // error occurred
+ delete begin;
+ delete end;
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+
+ jlongArray jslice_handles = env->NewLongArray(2);
+ if (jslice_handles == nullptr) {
+ // exception thrown: OutOfMemoryError
+ delete begin;
+ delete end;
+ return nullptr;
+ }
+
+ jlong slice_handles[2];
+ slice_handles[0] = reinterpret_cast<jlong>(begin);
+ slice_handles[1] = reinterpret_cast<jlong>(end);
+ env->SetLongArrayRegion(jslice_handles, 0, 2, slice_handles);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ delete begin;
+ delete end;
+ env->DeleteLocalRef(jslice_handles);
+ return nullptr;
+ }
+
+ return jslice_handles;
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: promoteL0
+ * Signature: (JJI)V
+ */
+void Java_org_rocksdb_RocksDB_promoteL0(
+ JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle, jint jtarget_level) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* cf_handle;
+ if (jcf_handle == 0) {
+ cf_handle = db->DefaultColumnFamily();
+ } else {
+ cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ }
+ db->PromoteL0(cf_handle, static_cast<int>(jtarget_level));
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: startTrace
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_RocksDB_startTrace(
+ JNIEnv* env, jobject, jlong jdb_handle, jlong jmax_trace_file_size,
+ jlong jtrace_writer_jnicallback_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ rocksdb::TraceOptions trace_options;
+ trace_options.max_trace_file_size =
+ static_cast<uint64_t>(jmax_trace_file_size);
+ // transfer ownership of trace writer from Java to C++
+ auto trace_writer = std::unique_ptr<rocksdb::TraceWriterJniCallback>(
+ reinterpret_cast<rocksdb::TraceWriterJniCallback*>(
+ jtrace_writer_jnicallback_handle));
+ auto s = db->StartTrace(trace_options, std::move(trace_writer));
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: endTrace
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_rocksdb_RocksDB_endTrace(
+ JNIEnv* env, jobject, jlong jdb_handle) {
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto s = db->EndTrace();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_RocksDB
+ * Method: destroyDB
+ * Signature: (Ljava/lang/String;J)V
+ */
+void Java_org_rocksdb_RocksDB_destroyDB(
+ JNIEnv* env, jclass, jstring jdb_path, jlong joptions_handle) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ auto* options = reinterpret_cast<rocksdb::Options*>(joptions_handle);
+ if (options == nullptr) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Invalid Options."));
+ }
+
+ rocksdb::Status s = rocksdb::DestroyDB(db_path, *options);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
diff --git a/src/rocksdb/java/rocksjni/slice.cc b/src/rocksdb/java/rocksjni/slice.cc
new file mode 100644
index 00000000..e617cde2
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/slice.cc
@@ -0,0 +1,356 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::Slice.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+#include "include/org_rocksdb_AbstractSlice.h"
+#include "include/org_rocksdb_DirectSlice.h"
+#include "include/org_rocksdb_Slice.h"
+#include "rocksdb/slice.h"
+#include "rocksjni/portal.h"
+
+// <editor-fold desc="org.rocksdb.AbstractSlice>
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: createNewSliceFromString
+ * Signature: (Ljava/lang/String;)J
+ */
+jlong Java_org_rocksdb_AbstractSlice_createNewSliceFromString(JNIEnv* env,
+ jclass /*jcls*/,
+ jstring jstr) {
+ const auto* str = env->GetStringUTFChars(jstr, nullptr);
+ if (str == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ const size_t len = strlen(str);
+
+ // NOTE: buf will be deleted in the
+ // Java_org_rocksdb_Slice_disposeInternalBuf or
+ // or Java_org_rocksdb_DirectSlice_disposeInternalBuf methods
+ char* buf = new char[len + 1];
+ memcpy(buf, str, len);
+ buf[len] = 0;
+ env->ReleaseStringUTFChars(jstr, str);
+
+ const auto* slice = new rocksdb::Slice(buf);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: size0
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_AbstractSlice_size0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return static_cast<jint>(slice->size());
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: empty0
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_AbstractSlice_empty0(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return slice->empty();
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: toString0
+ * Signature: (JZ)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_AbstractSlice_toString0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle, jboolean hex) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const std::string s = slice->ToString(hex);
+ return env->NewStringUTF(s.c_str());
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: compare0
+ * Signature: (JJ)I;
+ */
+jint Java_org_rocksdb_AbstractSlice_compare0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jlong otherHandle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const auto* otherSlice = reinterpret_cast<rocksdb::Slice*>(otherHandle);
+ return slice->compare(*otherSlice);
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: startsWith0
+ * Signature: (JJ)Z;
+ */
+jboolean Java_org_rocksdb_AbstractSlice_startsWith0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle,
+ jlong otherHandle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const auto* otherSlice = reinterpret_cast<rocksdb::Slice*>(otherHandle);
+ return slice->starts_with(*otherSlice);
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_AbstractSlice_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ delete reinterpret_cast<rocksdb::Slice*>(handle);
+}
+
+// </editor-fold>
+
+// <editor-fold desc="org.rocksdb.Slice>
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: createNewSlice0
+ * Signature: ([BI)J
+ */
+jlong Java_org_rocksdb_Slice_createNewSlice0(JNIEnv* env, jclass /*jcls*/,
+ jbyteArray data, jint offset) {
+ const jsize dataSize = env->GetArrayLength(data);
+ const int len = dataSize - offset;
+
+ // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf
+ // method
+ jbyte* buf = new jbyte[len];
+ env->GetByteArrayRegion(data, offset, len, buf);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ return 0;
+ }
+
+ const auto* slice = new rocksdb::Slice((const char*)buf, len);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: createNewSlice1
+ * Signature: ([B)J
+ */
+jlong Java_org_rocksdb_Slice_createNewSlice1(JNIEnv* env, jclass /*jcls*/,
+ jbyteArray data) {
+ jbyte* ptrData = env->GetByteArrayElements(data, nullptr);
+ if (ptrData == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ const int len = env->GetArrayLength(data) + 1;
+
+ // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf
+ // method
+ char* buf = new char[len];
+ memcpy(buf, ptrData, len - 1);
+ buf[len - 1] = '\0';
+
+ const auto* slice = new rocksdb::Slice(buf, len - 1);
+
+ env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT);
+
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: data0
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_Slice_data0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const jsize len = static_cast<jsize>(slice->size());
+ const jbyteArray data = env->NewByteArray(len);
+ if (data == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(
+ data, 0, len,
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(slice->data())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(data);
+ return nullptr;
+ }
+
+ return data;
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: clear0
+ * Signature: (JZJ)V
+ */
+void Java_org_rocksdb_Slice_clear0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jboolean shouldRelease,
+ jlong internalBufferOffset) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ if (shouldRelease == JNI_TRUE) {
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+ }
+ slice->clear();
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: removePrefix0
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Slice_removePrefix0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jint length) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ slice->remove_prefix(length);
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: disposeInternalBuf
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Slice_disposeInternalBuf(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong handle,
+ jlong internalBufferOffset) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+}
+
+// </editor-fold>
+
+// <editor-fold desc="org.rocksdb.DirectSlice>
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: createNewDirectSlice0
+ * Signature: (Ljava/nio/ByteBuffer;I)J
+ */
+jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0(JNIEnv* env,
+ jclass /*jcls*/,
+ jobject data,
+ jint length) {
+ assert(data != nullptr);
+ void* data_addr = env->GetDirectBufferAddress(data);
+ if (data_addr == nullptr) {
+ // error: memory region is undefined, given object is not a direct
+ // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Could not access DirectBuffer"));
+ return 0;
+ }
+
+ const auto* ptrData = reinterpret_cast<char*>(data_addr);
+ const auto* slice = new rocksdb::Slice(ptrData, length);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: createNewDirectSlice1
+ * Signature: (Ljava/nio/ByteBuffer;)J
+ */
+jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1(JNIEnv* env,
+ jclass /*jcls*/,
+ jobject data) {
+ void* data_addr = env->GetDirectBufferAddress(data);
+ if (data_addr == nullptr) {
+ // error: memory region is undefined, given object is not a direct
+ // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Could not access DirectBuffer"));
+ return 0;
+ }
+
+ const auto* ptrData = reinterpret_cast<char*>(data_addr);
+ const auto* slice = new rocksdb::Slice(ptrData);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: data0
+ * Signature: (J)Ljava/lang/Object;
+ */
+jobject Java_org_rocksdb_DirectSlice_data0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return env->NewDirectByteBuffer(const_cast<char*>(slice->data()),
+ slice->size());
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: get0
+ * Signature: (JI)B
+ */
+jbyte Java_org_rocksdb_DirectSlice_get0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jint offset) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return (*slice)[offset];
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: clear0
+ * Signature: (JZJ)V
+ */
+void Java_org_rocksdb_DirectSlice_clear0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jboolean shouldRelease,
+ jlong internalBufferOffset) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ if (shouldRelease == JNI_TRUE) {
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+ }
+ slice->clear();
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: removePrefix0
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DirectSlice_removePrefix0(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong handle,
+ jint length) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ slice->remove_prefix(length);
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: disposeInternalBuf
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DirectSlice_disposeInternalBuf(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong handle,
+ jlong internalBufferOffset) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+}
+
+// </editor-fold>
diff --git a/src/rocksdb/java/rocksjni/snapshot.cc b/src/rocksdb/java/rocksjni/snapshot.cc
new file mode 100644
index 00000000..679271db
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/snapshot.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "include/org_rocksdb_Snapshot.h"
+#include "rocksdb/db.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_Snapshot
+ * Method: getSequenceNumber
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Snapshot_getSequenceNumber(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jsnapshot_handle) {
+ auto* snapshot = reinterpret_cast<rocksdb::Snapshot*>(jsnapshot_handle);
+ return snapshot->GetSequenceNumber();
+}
diff --git a/src/rocksdb/java/rocksjni/sst_file_manager.cc b/src/rocksdb/java/rocksjni/sst_file_manager.cc
new file mode 100644
index 00000000..3df3c996
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/sst_file_manager.cc
@@ -0,0 +1,232 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling C++ rocksdb::SstFileManager methods
+// from Java side.
+
+#include <jni.h>
+#include <memory>
+
+#include "include/org_rocksdb_SstFileManager.h"
+#include "rocksdb/sst_file_manager.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: newSstFileManager
+ * Signature: (JJJDJ)J
+ */
+jlong Java_org_rocksdb_SstFileManager_newSstFileManager(
+ JNIEnv* jnienv, jclass /*jcls*/, jlong jenv_handle, jlong jlogger_handle,
+ jlong jrate_bytes, jdouble jmax_trash_db_ratio,
+ jlong jmax_delete_chunk_bytes) {
+ auto* env = reinterpret_cast<rocksdb::Env*>(jenv_handle);
+ rocksdb::Status s;
+ rocksdb::SstFileManager* sst_file_manager = nullptr;
+
+ if (jlogger_handle != 0) {
+ auto* sptr_logger =
+ reinterpret_cast<std::shared_ptr<rocksdb::Logger>*>(jlogger_handle);
+ sst_file_manager = rocksdb::NewSstFileManager(
+ env, *sptr_logger, "", jrate_bytes, true, &s, jmax_trash_db_ratio,
+ jmax_delete_chunk_bytes);
+ } else {
+ sst_file_manager = rocksdb::NewSstFileManager(env, nullptr, "", jrate_bytes,
+ true, &s, jmax_trash_db_ratio,
+ jmax_delete_chunk_bytes);
+ }
+
+ if (!s.ok()) {
+ if (sst_file_manager != nullptr) {
+ delete sst_file_manager;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(jnienv, s);
+ }
+ auto* sptr_sst_file_manager =
+ new std::shared_ptr<rocksdb::SstFileManager>(sst_file_manager);
+
+ return reinterpret_cast<jlong>(sptr_sst_file_manager);
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: setMaxAllowedSpaceUsage
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_SstFileManager_setMaxAllowedSpaceUsage(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jmax_allowed_space) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ sptr_sst_file_manager->get()->SetMaxAllowedSpaceUsage(jmax_allowed_space);
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: setCompactionBufferSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_SstFileManager_setCompactionBufferSize(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jcompaction_buffer_size) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ sptr_sst_file_manager->get()->SetCompactionBufferSize(
+ jcompaction_buffer_size);
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: isMaxAllowedSpaceReached
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_SstFileManager_isMaxAllowedSpaceReached(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ return sptr_sst_file_manager->get()->IsMaxAllowedSpaceReached();
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: isMaxAllowedSpaceReachedIncludingCompactions
+ * Signature: (J)Z
+ */
+jboolean
+Java_org_rocksdb_SstFileManager_isMaxAllowedSpaceReachedIncludingCompactions(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ return sptr_sst_file_manager->get()
+ ->IsMaxAllowedSpaceReachedIncludingCompactions();
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: getTotalSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_SstFileManager_getTotalSize(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ return sptr_sst_file_manager->get()->GetTotalSize();
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: getTrackedFiles
+ * Signature: (J)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_SstFileManager_getTrackedFiles(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ auto tracked_files = sptr_sst_file_manager->get()->GetTrackedFiles();
+
+ //TODO(AR) could refactor to share code with rocksdb::HashMapJni::fromCppMap(env, tracked_files);
+
+ const jobject jtracked_files = rocksdb::HashMapJni::construct(
+ env, static_cast<uint32_t>(tracked_files.size()));
+ if (jtracked_files == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const std::string, const uint64_t, jobject, jobject>
+ fn_map_kv =
+ [env](const std::pair<const std::string, const uint64_t>& pair) {
+ const jstring jtracked_file_path =
+ env->NewStringUTF(pair.first.c_str());
+ if (jtracked_file_path == nullptr) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+ const jobject jtracked_file_size =
+ rocksdb::LongJni::valueOf(env, pair.second);
+ if (jtracked_file_size == nullptr) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+ return std::unique_ptr<std::pair<jobject, jobject>>(
+ new std::pair<jobject, jobject>(jtracked_file_path,
+ jtracked_file_size));
+ };
+
+ if (!rocksdb::HashMapJni::putAll(env, jtracked_files, tracked_files.begin(),
+ tracked_files.end(), fn_map_kv)) {
+ // exception occcurred
+ return nullptr;
+ }
+
+ return jtracked_files;
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: getDeleteRateBytesPerSecond
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_SstFileManager_getDeleteRateBytesPerSecond(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ return sptr_sst_file_manager->get()->GetDeleteRateBytesPerSecond();
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: setDeleteRateBytesPerSecond
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_SstFileManager_setDeleteRateBytesPerSecond(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jlong jdelete_rate) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ sptr_sst_file_manager->get()->SetDeleteRateBytesPerSecond(jdelete_rate);
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: getMaxTrashDBRatio
+ * Signature: (J)D
+ */
+jdouble Java_org_rocksdb_SstFileManager_getMaxTrashDBRatio(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ return sptr_sst_file_manager->get()->GetMaxTrashDBRatio();
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: setMaxTrashDBRatio
+ * Signature: (JD)V
+ */
+void Java_org_rocksdb_SstFileManager_setMaxTrashDBRatio(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jdouble jratio) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ sptr_sst_file_manager->get()->SetMaxTrashDBRatio(jratio);
+}
+
+/*
+ * Class: org_rocksdb_SstFileManager
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_SstFileManager_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* sptr_sst_file_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::SstFileManager>*>(jhandle);
+ delete sptr_sst_file_manager;
+}
diff --git a/src/rocksdb/java/rocksjni/sst_file_writerjni.cc b/src/rocksdb/java/rocksjni/sst_file_writerjni.cc
new file mode 100644
index 00000000..76212ed8
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/sst_file_writerjni.cc
@@ -0,0 +1,268 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling C++ rocksdb::SstFileWriter methods
+// from Java side.
+
+#include <jni.h>
+#include <string>
+
+#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: (JJJB)J
+ */
+jlong Java_org_rocksdb_SstFileWriter_newSstFileWriter__JJJB(
+ JNIEnv * /*env*/, jclass /*jcls*/, jlong jenvoptions, jlong joptions,
+ jlong jcomparator_handle, jbyte jcomparator_type) {
+ rocksdb::Comparator *comparator = nullptr;
+ switch (jcomparator_type) {
+ // JAVA_COMPARATOR
+ case 0x0:
+ comparator = reinterpret_cast<rocksdb::ComparatorJniCallback *>(
+ jcomparator_handle);
+ break;
+
+ // JAVA_DIRECT_COMPARATOR
+ case 0x1:
+ comparator = reinterpret_cast<rocksdb::DirectComparatorJniCallback *>(
+ jcomparator_handle);
+ break;
+
+ // JAVA_NATIVE_COMPARATOR_WRAPPER
+ case 0x2:
+ comparator = reinterpret_cast<rocksdb::Comparator *>(jcomparator_handle);
+ break;
+ }
+ auto *env_options =
+ reinterpret_cast<const rocksdb::EnvOptions *>(jenvoptions);
+ auto *options = reinterpret_cast<const rocksdb::Options *>(joptions);
+ rocksdb::SstFileWriter *sst_file_writer =
+ new rocksdb::SstFileWriter(*env_options, *options, comparator);
+ return reinterpret_cast<jlong>(sst_file_writer);
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: newSstFileWriter
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_SstFileWriter_newSstFileWriter__JJ(JNIEnv * /*env*/,
+ jclass /*jcls*/,
+ jlong jenvoptions,
+ jlong joptions) {
+ auto *env_options =
+ reinterpret_cast<const rocksdb::EnvOptions *>(jenvoptions);
+ auto *options = reinterpret_cast<const rocksdb::Options *>(joptions);
+ rocksdb::SstFileWriter *sst_file_writer =
+ new rocksdb::SstFileWriter(*env_options, *options);
+ return reinterpret_cast<jlong>(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, nullptr);
+ if (file_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ rocksdb::Status s =
+ reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Open(file_path);
+ env->ReleaseStringUTFChars(jfile_path, file_path);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: put
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_SstFileWriter_put__JJJ(JNIEnv *env, jobject /*jobj*/,
+ jlong jhandle, jlong jkey_handle,
+ jlong jvalue_handle) {
+ auto *key_slice = reinterpret_cast<rocksdb::Slice *>(jkey_handle);
+ auto *value_slice = reinterpret_cast<rocksdb::Slice *>(jvalue_handle);
+ rocksdb::Status s = reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Put(
+ *key_slice, *value_slice);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: put
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_SstFileWriter_put__J_3B_3B(JNIEnv *env, jobject /*jobj*/,
+ jlong jhandle, jbyteArray jkey,
+ jbyteArray jval) {
+ jbyte *key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char *>(key),
+ env->GetArrayLength(jkey));
+
+ jbyte *value = env->GetByteArrayElements(jval, nullptr);
+ if (value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ return;
+ }
+ rocksdb::Slice value_slice(reinterpret_cast<char *>(value),
+ env->GetArrayLength(jval));
+
+ rocksdb::Status s = reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Put(
+ key_slice, value_slice);
+
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ env->ReleaseByteArrayElements(jval, value, JNI_ABORT);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: merge
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_SstFileWriter_merge__JJJ(JNIEnv *env, jobject /*jobj*/,
+ jlong jhandle, jlong jkey_handle,
+ jlong jvalue_handle) {
+ auto *key_slice = reinterpret_cast<rocksdb::Slice *>(jkey_handle);
+ auto *value_slice = reinterpret_cast<rocksdb::Slice *>(jvalue_handle);
+ rocksdb::Status s =
+ reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Merge(*key_slice,
+ *value_slice);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: merge
+ * Signature: (J[B[B)V
+ */
+void Java_org_rocksdb_SstFileWriter_merge__J_3B_3B(JNIEnv *env,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jbyteArray jkey,
+ jbyteArray jval) {
+ jbyte *key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char *>(key),
+ env->GetArrayLength(jkey));
+
+ jbyte *value = env->GetByteArrayElements(jval, nullptr);
+ if (value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ return;
+ }
+ rocksdb::Slice value_slice(reinterpret_cast<char *>(value),
+ env->GetArrayLength(jval));
+
+ rocksdb::Status s =
+ reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Merge(key_slice,
+ value_slice);
+
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ env->ReleaseByteArrayElements(jval, value, JNI_ABORT);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: delete
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_SstFileWriter_delete__J_3B(JNIEnv *env, jobject /*jobj*/,
+ jlong jhandle,
+ jbyteArray jkey) {
+ jbyte *key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char *>(key),
+ env->GetArrayLength(jkey));
+
+ rocksdb::Status s =
+ reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Delete(key_slice);
+
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_SstFileWriter
+ * Method: delete
+ * Signature: (JJJ)V
+ */
+void Java_org_rocksdb_SstFileWriter_delete__JJ(JNIEnv *env, jobject /*jobj*/,
+ jlong jhandle,
+ jlong jkey_handle) {
+ auto *key_slice = reinterpret_cast<rocksdb::Slice *>(jkey_handle);
+ rocksdb::Status s =
+ reinterpret_cast<rocksdb::SstFileWriter *>(jhandle)->Delete(*key_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<rocksdb::SstFileWriter *>(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<rocksdb::SstFileWriter *>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/statistics.cc b/src/rocksdb/java/rocksjni/statistics.cc
new file mode 100644
index 00000000..ae7ad535
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/statistics.cc
@@ -0,0 +1,247 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::Statistics methods from Java side.
+
+#include <jni.h>
+#include <memory>
+#include <set>
+
+#include "include/org_rocksdb_Statistics.h"
+#include "rocksdb/statistics.h"
+#include "rocksjni/portal.h"
+#include "rocksjni/statisticsjni.h"
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: newStatistics
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_Statistics_newStatistics__(
+ JNIEnv* env, jclass jcls) {
+ return Java_org_rocksdb_Statistics_newStatistics___3BJ(
+ env, jcls, nullptr, 0);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: newStatistics
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Statistics_newStatistics__J(
+ JNIEnv* env, jclass jcls, jlong jother_statistics_handle) {
+ return Java_org_rocksdb_Statistics_newStatistics___3BJ(
+ env, jcls, nullptr, jother_statistics_handle);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: newStatistics
+ * Signature: ([B)J
+ */
+jlong Java_org_rocksdb_Statistics_newStatistics___3B(
+ JNIEnv* env, jclass jcls, jbyteArray jhistograms) {
+ return Java_org_rocksdb_Statistics_newStatistics___3BJ(
+ env, jcls, jhistograms, 0);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: newStatistics
+ * Signature: ([BJ)J
+ */
+jlong Java_org_rocksdb_Statistics_newStatistics___3BJ(
+ JNIEnv* env, jclass, jbyteArray jhistograms, jlong jother_statistics_handle) {
+ std::shared_ptr<rocksdb::Statistics>* pSptr_other_statistics = nullptr;
+ if (jother_statistics_handle > 0) {
+ pSptr_other_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(
+ jother_statistics_handle);
+ }
+
+ std::set<uint32_t> histograms;
+ if (jhistograms != nullptr) {
+ const jsize len = env->GetArrayLength(jhistograms);
+ if (len > 0) {
+ jbyte* jhistogram = env->GetByteArrayElements(jhistograms, nullptr);
+ if (jhistogram == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ for (jsize i = 0; i < len; i++) {
+ const rocksdb::Histograms histogram =
+ rocksdb::HistogramTypeJni::toCppHistograms(jhistogram[i]);
+ histograms.emplace(histogram);
+ }
+
+ env->ReleaseByteArrayElements(jhistograms, jhistogram, JNI_ABORT);
+ }
+ }
+
+ std::shared_ptr<rocksdb::Statistics> sptr_other_statistics = nullptr;
+ if (pSptr_other_statistics != nullptr) {
+ sptr_other_statistics = *pSptr_other_statistics;
+ }
+
+ auto* pSptr_statistics = new std::shared_ptr<rocksdb::StatisticsJni>(
+ new rocksdb::StatisticsJni(sptr_other_statistics, histograms));
+
+ return reinterpret_cast<jlong>(pSptr_statistics);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Statistics_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ if (jhandle > 0) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ delete pSptr_statistics;
+ }
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: statsLevel
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Statistics_statsLevel(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ return rocksdb::StatsLevelJni::toJavaStatsLevel(
+ pSptr_statistics->get()->get_stats_level());
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: setStatsLevel
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_Statistics_setStatsLevel(
+ JNIEnv*, jobject, jlong jhandle, jbyte jstats_level) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ auto stats_level = rocksdb::StatsLevelJni::toCppStatsLevel(jstats_level);
+ pSptr_statistics->get()->set_stats_level(stats_level);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: getTickerCount
+ * Signature: (JB)J
+ */
+jlong Java_org_rocksdb_Statistics_getTickerCount(
+ JNIEnv*, jobject, jlong jhandle, jbyte jticker_type) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ auto ticker = rocksdb::TickerTypeJni::toCppTickers(jticker_type);
+ uint64_t count = pSptr_statistics->get()->getTickerCount(ticker);
+ return static_cast<jlong>(count);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: getAndResetTickerCount
+ * Signature: (JB)J
+ */
+jlong Java_org_rocksdb_Statistics_getAndResetTickerCount(
+ JNIEnv*, jobject, jlong jhandle, jbyte jticker_type) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ auto ticker = rocksdb::TickerTypeJni::toCppTickers(jticker_type);
+ return pSptr_statistics->get()->getAndResetTickerCount(ticker);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: getHistogramData
+ * Signature: (JB)Lorg/rocksdb/HistogramData;
+ */
+jobject Java_org_rocksdb_Statistics_getHistogramData(
+ JNIEnv* env, jobject, jlong jhandle, jbyte jhistogram_type) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+
+ // TODO(AR) perhaps better to construct a Java Object Wrapper that
+ // uses ptr to C++ `new HistogramData`
+ rocksdb::HistogramData data;
+
+ auto histogram = rocksdb::HistogramTypeJni::toCppHistograms(jhistogram_type);
+ pSptr_statistics->get()->histogramData(
+ static_cast<rocksdb::Histograms>(histogram), &data);
+
+ jclass jclazz = rocksdb::HistogramDataJni::getJClass(env);
+ if (jclazz == nullptr) {
+ // exception occurred accessing class
+ return nullptr;
+ }
+
+ jmethodID mid = rocksdb::HistogramDataJni::getConstructorMethodId(env);
+ if (mid == nullptr) {
+ // exception occurred accessing method
+ return nullptr;
+ }
+
+ return env->NewObject(jclazz, mid, data.median, data.percentile95,
+ data.percentile99, data.average,
+ data.standard_deviation, data.max, data.count,
+ data.sum, data.min);
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: getHistogramString
+ * Signature: (JB)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_Statistics_getHistogramString(
+ JNIEnv* env, jobject, jlong jhandle, jbyte jhistogram_type) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ auto histogram = rocksdb::HistogramTypeJni::toCppHistograms(jhistogram_type);
+ auto str = pSptr_statistics->get()->getHistogramString(histogram);
+ return env->NewStringUTF(str.c_str());
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: reset
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Statistics_reset(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ rocksdb::Status s = pSptr_statistics->get()->Reset();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Statistics
+ * Method: toString
+ * Signature: (J)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_Statistics_toString(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* pSptr_statistics =
+ reinterpret_cast<std::shared_ptr<rocksdb::Statistics>*>(jhandle);
+ assert(pSptr_statistics != nullptr);
+ auto str = pSptr_statistics->get()->ToString();
+ return env->NewStringUTF(str.c_str());
+}
diff --git a/src/rocksdb/java/rocksjni/statisticsjni.cc b/src/rocksdb/java/rocksjni/statisticsjni.cc
new file mode 100644
index 00000000..f59ace4d
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/statisticsjni.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Statistics
+
+#include "rocksjni/statisticsjni.h"
+
+namespace rocksdb {
+
+StatisticsJni::StatisticsJni(std::shared_ptr<Statistics> stats)
+ : StatisticsImpl(stats), m_ignore_histograms() {}
+
+StatisticsJni::StatisticsJni(std::shared_ptr<Statistics> stats,
+ const std::set<uint32_t> ignore_histograms)
+ : StatisticsImpl(stats), m_ignore_histograms(ignore_histograms) {}
+
+bool StatisticsJni::HistEnabledForType(uint32_t type) const {
+ if (type >= HISTOGRAM_ENUM_MAX) {
+ return false;
+ }
+
+ if (m_ignore_histograms.count(type) > 0) {
+ return false;
+ }
+
+ return true;
+}
+// @lint-ignore TXT4 T25377293 Grandfathered in
+}; \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/statisticsjni.h b/src/rocksdb/java/rocksjni/statisticsjni.h
new file mode 100644
index 00000000..56186789
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/statisticsjni.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Statistics
+
+#ifndef JAVA_ROCKSJNI_STATISTICSJNI_H_
+#define JAVA_ROCKSJNI_STATISTICSJNI_H_
+
+#include <memory>
+#include <set>
+#include <string>
+#include "rocksdb/statistics.h"
+#include "monitoring/statistics.h"
+
+namespace rocksdb {
+
+ class StatisticsJni : public StatisticsImpl {
+ public:
+ StatisticsJni(std::shared_ptr<Statistics> stats);
+ StatisticsJni(std::shared_ptr<Statistics> stats,
+ const std::set<uint32_t> ignore_histograms);
+ virtual bool HistEnabledForType(uint32_t type) const override;
+
+ private:
+ const std::set<uint32_t> m_ignore_histograms;
+ };
+
+} // namespace rocksdb
+
+// @lint-ignore TXT4 T25377293 Grandfathered in
+#endif // JAVA_ROCKSJNI_STATISTICSJNI_H_ \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/table.cc b/src/rocksdb/java/rocksjni/table.cc
new file mode 100644
index 00000000..1ccc550a
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/table.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for rocksdb::Options.
+
+#include "rocksdb/table.h"
+#include <jni.h>
+#include "include/org_rocksdb_BlockBasedTableConfig.h"
+#include "include/org_rocksdb_PlainTableConfig.h"
+#include "portal.h"
+#include "rocksdb/cache.h"
+#include "rocksdb/filter_policy.h"
+
+/*
+ * Class: org_rocksdb_PlainTableConfig
+ * Method: newTableFactoryHandle
+ * Signature: (IIDIIBZZ)J
+ */
+jlong Java_org_rocksdb_PlainTableConfig_newTableFactoryHandle(
+ JNIEnv * /*env*/, jobject /*jobj*/, jint jkey_size,
+ jint jbloom_bits_per_key, jdouble jhash_table_ratio, jint jindex_sparseness,
+ jint jhuge_page_tlb_size, jbyte jencoding_type, jboolean jfull_scan_mode,
+ jboolean jstore_index_in_file) {
+ rocksdb::PlainTableOptions options = rocksdb::PlainTableOptions();
+ options.user_key_len = jkey_size;
+ options.bloom_bits_per_key = jbloom_bits_per_key;
+ options.hash_table_ratio = jhash_table_ratio;
+ options.index_sparseness = jindex_sparseness;
+ options.huge_page_tlb_size = jhuge_page_tlb_size;
+ options.encoding_type = static_cast<rocksdb::EncodingType>(jencoding_type);
+ options.full_scan_mode = jfull_scan_mode;
+ options.store_index_in_file = jstore_index_in_file;
+ return reinterpret_cast<jlong>(rocksdb::NewPlainTableFactory(options));
+}
+
+/*
+ * Class: org_rocksdb_BlockBasedTableConfig
+ * Method: newTableFactoryHandle
+ * Signature: (ZZZZBBDBZJJJJIIIJZZJZZIIZZJIJI)J
+ */
+jlong Java_org_rocksdb_BlockBasedTableConfig_newTableFactoryHandle(
+ JNIEnv*, jobject, jboolean jcache_index_and_filter_blocks,
+ jboolean jcache_index_and_filter_blocks_with_high_priority,
+ jboolean jpin_l0_filter_and_index_blocks_in_cache,
+ jboolean jpin_top_level_index_and_filter, jbyte jindex_type_value,
+ jbyte jdata_block_index_type_value,
+ jdouble jdata_block_hash_table_util_ratio, jbyte jchecksum_type_value,
+ jboolean jno_block_cache, jlong jblock_cache_handle,
+ jlong jpersistent_cache_handle,
+ jlong jblock_cache_compressed_handle, jlong jblock_size,
+ jint jblock_size_deviation, jint jblock_restart_interval,
+ jint jindex_block_restart_interval, jlong jmetadata_block_size,
+ jboolean jpartition_filters, jboolean juse_delta_encoding,
+ jlong jfilter_policy_handle, jboolean jwhole_key_filtering,
+ jboolean jverify_compression, jint jread_amp_bytes_per_bit,
+ jint jformat_version, jboolean jenable_index_compression,
+ jboolean jblock_align, jlong jblock_cache_size,
+ jint jblock_cache_num_shard_bits, jlong jblock_cache_compressed_size,
+ jint jblock_cache_compressed_num_shard_bits) {
+ rocksdb::BlockBasedTableOptions options;
+ options.cache_index_and_filter_blocks =
+ static_cast<bool>(jcache_index_and_filter_blocks);
+ options.cache_index_and_filter_blocks_with_high_priority =
+ static_cast<bool>(jcache_index_and_filter_blocks_with_high_priority);
+ options.pin_l0_filter_and_index_blocks_in_cache =
+ static_cast<bool>(jpin_l0_filter_and_index_blocks_in_cache);
+ options.pin_top_level_index_and_filter =
+ static_cast<bool>(jpin_top_level_index_and_filter);
+ options.index_type =
+ rocksdb::IndexTypeJni::toCppIndexType(jindex_type_value);
+ options.data_block_index_type =
+ rocksdb::DataBlockIndexTypeJni::toCppDataBlockIndexType(
+ jdata_block_index_type_value);
+ options.data_block_hash_table_util_ratio =
+ static_cast<double>(jdata_block_hash_table_util_ratio);
+ options.checksum =
+ rocksdb::ChecksumTypeJni::toCppChecksumType(jchecksum_type_value);
+ options.no_block_cache = static_cast<bool>(jno_block_cache);
+ if (options.no_block_cache) {
+ options.block_cache = nullptr;
+ } else {
+ if (jblock_cache_handle > 0) {
+ std::shared_ptr<rocksdb::Cache> *pCache =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache> *>(jblock_cache_handle);
+ options.block_cache = *pCache;
+ } else if (jblock_cache_size > 0) {
+ if (jblock_cache_num_shard_bits > 0) {
+ options.block_cache = rocksdb::NewLRUCache(
+ static_cast<size_t>(jblock_cache_size),
+ static_cast<int>(jblock_cache_num_shard_bits));
+ } else {
+ options.block_cache = rocksdb::NewLRUCache(
+ static_cast<size_t>(jblock_cache_size));
+ }
+ }
+ }
+ if (jpersistent_cache_handle > 0) {
+ std::shared_ptr<rocksdb::PersistentCache> *pCache =
+ reinterpret_cast<std::shared_ptr<rocksdb::PersistentCache> *>(jpersistent_cache_handle);
+ options.persistent_cache = *pCache;
+ }
+ if (jblock_cache_compressed_handle > 0) {
+ std::shared_ptr<rocksdb::Cache> *pCache =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache> *>(jblock_cache_compressed_handle);
+ options.block_cache_compressed = *pCache;
+ } else if (jblock_cache_compressed_size > 0) {
+ if (jblock_cache_compressed_num_shard_bits > 0) {
+ options.block_cache_compressed = rocksdb::NewLRUCache(
+ static_cast<size_t>(jblock_cache_compressed_size),
+ static_cast<int>(jblock_cache_compressed_num_shard_bits));
+ } else {
+ options.block_cache_compressed = rocksdb::NewLRUCache(
+ static_cast<size_t>(jblock_cache_compressed_size));
+ }
+ }
+ options.block_size = static_cast<size_t>(jblock_size);
+ options.block_size_deviation = static_cast<int>(jblock_size_deviation);
+ options.block_restart_interval = static_cast<int>(jblock_restart_interval);
+ options.index_block_restart_interval = static_cast<int>(jindex_block_restart_interval);
+ options.metadata_block_size = static_cast<uint64_t>(jmetadata_block_size);
+ options.partition_filters = static_cast<bool>(jpartition_filters);
+ options.use_delta_encoding = static_cast<bool>(juse_delta_encoding);
+ if (jfilter_policy_handle > 0) {
+ std::shared_ptr<rocksdb::FilterPolicy> *pFilterPolicy =
+ reinterpret_cast<std::shared_ptr<rocksdb::FilterPolicy> *>(
+ jfilter_policy_handle);
+ options.filter_policy = *pFilterPolicy;
+ }
+ options.whole_key_filtering = static_cast<bool>(jwhole_key_filtering);
+ options.verify_compression = static_cast<bool>(jverify_compression);
+ options.read_amp_bytes_per_bit = static_cast<uint32_t>(jread_amp_bytes_per_bit);
+ options.format_version = static_cast<uint32_t>(jformat_version);
+ options.enable_index_compression = static_cast<bool>(jenable_index_compression);
+ options.block_align = static_cast<bool>(jblock_align);
+
+ return reinterpret_cast<jlong>(rocksdb::NewBlockBasedTableFactory(options));
+}
diff --git a/src/rocksdb/java/rocksjni/table_filter.cc b/src/rocksdb/java/rocksjni/table_filter.cc
new file mode 100644
index 00000000..e5b35562
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/table_filter.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// org.rocksdb.AbstractTableFilter.
+
+#include <jni.h>
+#include <memory>
+
+#include "include/org_rocksdb_AbstractTableFilter.h"
+#include "rocksjni/table_filter_jnicallback.h"
+
+/*
+ * Class: org_rocksdb_AbstractTableFilter
+ * Method: createNewTableFilter
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_AbstractTableFilter_createNewTableFilter(
+ JNIEnv* env, jobject jtable_filter) {
+ auto* table_filter_jnicallback =
+ new rocksdb::TableFilterJniCallback(env, jtable_filter);
+ return reinterpret_cast<jlong>(table_filter_jnicallback);
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/table_filter_jnicallback.cc b/src/rocksdb/java/rocksjni/table_filter_jnicallback.cc
new file mode 100644
index 00000000..680c0144
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/table_filter_jnicallback.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::TableFilter.
+
+#include "rocksjni/table_filter_jnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+TableFilterJniCallback::TableFilterJniCallback(
+ JNIEnv* env, jobject jtable_filter)
+ : JniCallback(env, jtable_filter) {
+ m_jfilter_methodid =
+ AbstractTableFilterJni::getFilterMethod(env);
+ if(m_jfilter_methodid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ // create the function reference
+ /*
+ Note the JNI ENV must be obtained/release
+ on each call to the function itself as
+ it may be called from multiple threads
+ */
+ m_table_filter_function = [this](const rocksdb::TableProperties& table_properties) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* thread_env = getJniEnv(&attached_thread);
+ assert(thread_env != nullptr);
+
+ // create a Java TableProperties object
+ jobject jtable_properties = TablePropertiesJni::fromCppTableProperties(thread_env, table_properties);
+ if (jtable_properties == nullptr) {
+ // exception thrown from fromCppTableProperties
+ thread_env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return false;
+ }
+
+ jboolean result = thread_env->CallBooleanMethod(m_jcallback_obj, m_jfilter_methodid, jtable_properties);
+ if (thread_env->ExceptionCheck()) {
+ // exception thrown from CallBooleanMethod
+ thread_env->DeleteLocalRef(jtable_properties);
+ thread_env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return false;
+ }
+
+ // ok... cleanup and then return
+ releaseJniEnv(attached_thread);
+ return static_cast<bool>(result);
+ };
+}
+
+std::function<bool(const rocksdb::TableProperties&)> TableFilterJniCallback::GetTableFilterFunction() {
+ return m_table_filter_function;
+}
+
+} // namespace rocksdb
diff --git a/src/rocksdb/java/rocksjni/table_filter_jnicallback.h b/src/rocksdb/java/rocksjni/table_filter_jnicallback.h
new file mode 100644
index 00000000..39a0c90e
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/table_filter_jnicallback.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::TableFilter.
+
+#ifndef JAVA_ROCKSJNI_TABLE_FILTER_JNICALLBACK_H_
+#define JAVA_ROCKSJNI_TABLE_FILTER_JNICALLBACK_H_
+
+#include <jni.h>
+#include <functional>
+#include <memory>
+
+#include "rocksdb/table_properties.h"
+#include "rocksjni/jnicallback.h"
+
+namespace rocksdb {
+
+class TableFilterJniCallback : public JniCallback {
+ public:
+ TableFilterJniCallback(
+ JNIEnv* env, jobject jtable_filter);
+ std::function<bool(const rocksdb::TableProperties&)> GetTableFilterFunction();
+
+ private:
+ jmethodID m_jfilter_methodid;
+ std::function<bool(const rocksdb::TableProperties&)> m_table_filter_function;
+};
+
+} //namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_TABLE_FILTER_JNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/thread_status.cc b/src/rocksdb/java/rocksjni/thread_status.cc
new file mode 100644
index 00000000..f70d515a
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/thread_status.cc
@@ -0,0 +1,121 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::ThreadStatus methods from Java side.
+
+#include <jni.h>
+
+#include "portal.h"
+#include "include/org_rocksdb_ThreadStatus.h"
+#include "rocksdb/thread_status.h"
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: getThreadTypeName
+ * Signature: (B)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_ThreadStatus_getThreadTypeName(
+ JNIEnv* env, jclass, jbyte jthread_type_value) {
+ auto name = rocksdb::ThreadStatus::GetThreadTypeName(
+ rocksdb::ThreadTypeJni::toCppThreadType(jthread_type_value));
+ return rocksdb::JniUtil::toJavaString(env, &name, true);
+}
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: getOperationName
+ * Signature: (B)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_ThreadStatus_getOperationName(
+ JNIEnv* env, jclass, jbyte joperation_type_value) {
+ auto name = rocksdb::ThreadStatus::GetOperationName(
+ rocksdb::OperationTypeJni::toCppOperationType(joperation_type_value));
+ return rocksdb::JniUtil::toJavaString(env, &name, true);
+}
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: microsToStringNative
+ * Signature: (J)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_ThreadStatus_microsToStringNative(
+ JNIEnv* env, jclass, jlong jmicros) {
+ auto str =
+ rocksdb::ThreadStatus::MicrosToString(static_cast<uint64_t>(jmicros));
+ return rocksdb::JniUtil::toJavaString(env, &str, true);
+}
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: getOperationStageName
+ * Signature: (B)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_ThreadStatus_getOperationStageName(
+ JNIEnv* env, jclass, jbyte joperation_stage_value) {
+ auto name = rocksdb::ThreadStatus::GetOperationStageName(
+ rocksdb::OperationStageJni::toCppOperationStage(joperation_stage_value));
+ return rocksdb::JniUtil::toJavaString(env, &name, true);
+}
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: getOperationPropertyName
+ * Signature: (BI)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_ThreadStatus_getOperationPropertyName(
+ JNIEnv* env, jclass, jbyte joperation_type_value, jint jindex) {
+ auto name = rocksdb::ThreadStatus::GetOperationPropertyName(
+ rocksdb::OperationTypeJni::toCppOperationType(joperation_type_value),
+ static_cast<int>(jindex));
+ return rocksdb::JniUtil::toJavaString(env, &name, true);
+}
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: interpretOperationProperties
+ * Signature: (B[J)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_ThreadStatus_interpretOperationProperties(
+ JNIEnv* env, jclass, jbyte joperation_type_value,
+ jlongArray joperation_properties) {
+
+ //convert joperation_properties
+ const jsize len = env->GetArrayLength(joperation_properties);
+ const std::unique_ptr<uint64_t[]> op_properties(new uint64_t[len]);
+ jlong* jop = env->GetLongArrayElements(joperation_properties, nullptr);
+ if (jop == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ for (jsize i = 0; i < len; i++) {
+ op_properties[i] = static_cast<uint64_t>(jop[i]);
+ }
+ env->ReleaseLongArrayElements(joperation_properties, jop, JNI_ABORT);
+
+ // call the function
+ auto result = rocksdb::ThreadStatus::InterpretOperationProperties(
+ rocksdb::OperationTypeJni::toCppOperationType(joperation_type_value),
+ op_properties.get());
+ jobject jresult = rocksdb::HashMapJni::fromCppMap(env, &result);
+ if (env->ExceptionCheck()) {
+ // exception occurred
+ return nullptr;
+ }
+
+ return jresult;
+}
+
+/*
+ * Class: org_rocksdb_ThreadStatus
+ * Method: getStateName
+ * Signature: (B)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_ThreadStatus_getStateName(
+ JNIEnv* env, jclass, jbyte jstate_type_value) {
+ auto name = rocksdb::ThreadStatus::GetStateName(
+ rocksdb::StateTypeJni::toCppStateType(jstate_type_value));
+ return rocksdb::JniUtil::toJavaString(env, &name, true);
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/trace_writer.cc b/src/rocksdb/java/rocksjni/trace_writer.cc
new file mode 100644
index 00000000..5d47cfcb
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/trace_writer.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::CompactionFilterFactory.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_AbstractTraceWriter.h"
+#include "rocksjni/trace_writer_jnicallback.h"
+
+/*
+ * Class: org_rocksdb_AbstractTraceWriter
+ * Method: createNewTraceWriter
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_AbstractTraceWriter_createNewTraceWriter(
+ JNIEnv* env, jobject jobj) {
+ auto* trace_writer = new rocksdb::TraceWriterJniCallback(env, jobj);
+ return reinterpret_cast<jlong>(trace_writer);
+}
diff --git a/src/rocksdb/java/rocksjni/trace_writer_jnicallback.cc b/src/rocksdb/java/rocksjni/trace_writer_jnicallback.cc
new file mode 100644
index 00000000..d547fb3f
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/trace_writer_jnicallback.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::TraceWriter.
+
+#include "rocksjni/trace_writer_jnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+TraceWriterJniCallback::TraceWriterJniCallback(
+ JNIEnv* env, jobject jtrace_writer)
+ : JniCallback(env, jtrace_writer) {
+ m_jwrite_proxy_methodid =
+ AbstractTraceWriterJni::getWriteProxyMethodId(env);
+ if(m_jwrite_proxy_methodid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ m_jclose_writer_proxy_methodid =
+ AbstractTraceWriterJni::getCloseWriterProxyMethodId(env);
+ if(m_jclose_writer_proxy_methodid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ m_jget_file_size_methodid =
+ AbstractTraceWriterJni::getGetFileSizeMethodId(env);
+ if(m_jget_file_size_methodid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+}
+
+Status TraceWriterJniCallback::Write(const Slice& data) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return Status::IOError("Unable to attach JNI Environment");
+ }
+
+ jshort jstatus = env->CallShortMethod(m_jcallback_obj,
+ m_jwrite_proxy_methodid,
+ &data);
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallShortMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return Status::IOError("Unable to call AbstractTraceWriter#writeProxy(long)");
+ }
+
+ // unpack status code and status sub-code from jstatus
+ jbyte jcode_value = (jstatus >> 8) & 0xFF;
+ jbyte jsub_code_value = jstatus & 0xFF;
+ std::unique_ptr<Status> s = StatusJni::toCppStatus(jcode_value, jsub_code_value);
+
+ releaseJniEnv(attached_thread);
+
+ return Status(*s);
+}
+
+Status TraceWriterJniCallback::Close() {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return Status::IOError("Unable to attach JNI Environment");
+ }
+
+ jshort jstatus = env->CallShortMethod(m_jcallback_obj,
+ m_jclose_writer_proxy_methodid);
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallShortMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return Status::IOError("Unable to call AbstractTraceWriter#closeWriterProxy()");
+ }
+
+ // unpack status code and status sub-code from jstatus
+ jbyte code_value = (jstatus >> 8) & 0xFF;
+ jbyte sub_code_value = jstatus & 0xFF;
+ std::unique_ptr<Status> s = StatusJni::toCppStatus(code_value, sub_code_value);
+
+ releaseJniEnv(attached_thread);
+
+ return Status(*s);
+}
+
+uint64_t TraceWriterJniCallback::GetFileSize() {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return 0;
+ }
+
+ jlong jfile_size = env->CallLongMethod(m_jcallback_obj,
+ m_jget_file_size_methodid);
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallLongMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return 0;
+ }
+
+ releaseJniEnv(attached_thread);
+
+ return static_cast<uint64_t>(jfile_size);
+}
+
+} // namespace rocksdb \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/trace_writer_jnicallback.h b/src/rocksdb/java/rocksjni/trace_writer_jnicallback.h
new file mode 100644
index 00000000..610b6c46
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/trace_writer_jnicallback.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::TraceWriter.
+
+#ifndef JAVA_ROCKSJNI_TRACE_WRITER_JNICALLBACK_H_
+#define JAVA_ROCKSJNI_TRACE_WRITER_JNICALLBACK_H_
+
+#include <jni.h>
+#include <memory>
+
+#include "rocksdb/trace_reader_writer.h"
+#include "rocksjni/jnicallback.h"
+
+namespace rocksdb {
+
+class TraceWriterJniCallback : public JniCallback, public TraceWriter {
+ public:
+ TraceWriterJniCallback(
+ JNIEnv* env, jobject jtrace_writer);
+ virtual Status Write(const Slice& data);
+ virtual Status Close();
+ virtual uint64_t GetFileSize();
+
+ private:
+ jmethodID m_jwrite_proxy_methodid;
+ jmethodID m_jclose_writer_proxy_methodid;
+ jmethodID m_jget_file_size_methodid;
+};
+
+} //namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_TRACE_WRITER_JNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/transaction.cc b/src/rocksdb/java/rocksjni/transaction.cc
new file mode 100644
index 00000000..04eb654d
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction.cc
@@ -0,0 +1,1584 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::Transaction.
+
+#include <jni.h>
+#include <functional>
+
+#include "include/org_rocksdb_Transaction.h"
+
+#include "rocksdb/utilities/transaction.h"
+#include "rocksjni/portal.h"
+
+using namespace std::placeholders;
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4503) // identifier' : decorated name length
+ // exceeded, name was truncated
+#endif
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setSnapshot
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_setSnapshot(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->SetSnapshot();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setSnapshotOnNextOperation
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_setSnapshotOnNextOperation__J(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->SetSnapshotOnNextOperation(nullptr);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setSnapshotOnNextOperation
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Transaction_setSnapshotOnNextOperation__JJ(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jtxn_notifier_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* txn_notifier =
+ reinterpret_cast<std::shared_ptr<rocksdb::TransactionNotifierJniCallback>*>(
+ jtxn_notifier_handle);
+ txn->SetSnapshotOnNextOperation(*txn_notifier);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getSnapshot
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getSnapshot(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ const rocksdb::Snapshot* snapshot = txn->GetSnapshot();
+ return reinterpret_cast<jlong>(snapshot);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: clearSnapshot
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_clearSnapshot(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->ClearSnapshot();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: prepare
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_prepare(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::Status s = txn->Prepare();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: commit
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_commit(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::Status s = txn->Commit();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: rollback
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_rollback(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::Status s = txn->Rollback();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setSavePoint
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_setSavePoint(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->SetSavePoint();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: rollbackToSavePoint
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_rollbackToSavePoint(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::Status s = txn->RollbackToSavePoint();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+typedef std::function<rocksdb::Status(const rocksdb::ReadOptions&,
+ const rocksdb::Slice&, std::string*)>
+ FnGet;
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+jbyteArray txn_get_helper(JNIEnv* env, const FnGet& fn_get,
+ const jlong& jread_options_handle,
+ const jbyteArray& jkey, const jint& jkey_part_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_part_len);
+
+ auto* read_options =
+ reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ std::string value;
+ rocksdb::Status s = fn_get(*read_options, key_slice, &value);
+
+ // trigger java unref on key.
+ // by passing JNI_ABORT, it will simply release the reference without
+ // copying the result back to the java byte array.
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+
+ if (s.IsNotFound()) {
+ return nullptr;
+ }
+
+ if (s.ok()) {
+ jbyteArray jret_value = env->NewByteArray(static_cast<jsize>(value.size()));
+ if (jret_value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetByteArrayRegion(jret_value, 0, static_cast<jsize>(value.size()),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.c_str())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ return nullptr;
+ }
+ return jret_value;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: get
+ * Signature: (JJ[BIJ)[B
+ */
+jbyteArray Java_org_rocksdb_Transaction_get__JJ_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jbyteArray jkey, jint jkey_part_len, jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnGet fn_get = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&, rocksdb::ColumnFamilyHandle*,
+ const rocksdb::Slice&, std::string*)>(&rocksdb::Transaction::Get, txn, _1,
+ column_family_handle, _2, _3);
+ return txn_get_helper(env, fn_get, jread_options_handle, jkey, jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: get
+ * Signature: (JJ[BI)[B
+ */
+jbyteArray Java_org_rocksdb_Transaction_get__JJ_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jbyteArray jkey, jint jkey_part_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnGet fn_get = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&, const rocksdb::Slice&, std::string*)>(
+ &rocksdb::Transaction::Get, txn, _1, _2, _3);
+ return txn_get_helper(env, fn_get, jread_options_handle, jkey, jkey_part_len);
+}
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+// used by txn_multi_get_helper below
+std::vector<rocksdb::ColumnFamilyHandle*> txn_column_families_helper(
+ JNIEnv* env, jlongArray jcolumn_family_handles, bool* has_exception) {
+ std::vector<rocksdb::ColumnFamilyHandle*> cf_handles;
+ if (jcolumn_family_handles != nullptr) {
+ const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
+ if (len_cols > 0) {
+ if (env->EnsureLocalCapacity(len_cols) != 0) {
+ // out of memory
+ *has_exception = JNI_TRUE;
+ return std::vector<rocksdb::ColumnFamilyHandle*>();
+ }
+
+ jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
+ if (jcfh == nullptr) {
+ // exception thrown: OutOfMemoryError
+ *has_exception = JNI_TRUE;
+ return std::vector<rocksdb::ColumnFamilyHandle*>();
+ }
+ for (int i = 0; i < len_cols; i++) {
+ auto* cf_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]);
+ cf_handles.push_back(cf_handle);
+ }
+ env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
+ }
+ }
+ return cf_handles;
+}
+
+typedef std::function<std::vector<rocksdb::Status>(
+ const rocksdb::ReadOptions&, const std::vector<rocksdb::Slice>&,
+ std::vector<std::string>*)>
+ FnMultiGet;
+
+void free_parts(
+ JNIEnv* env,
+ std::vector<std::tuple<jbyteArray, jbyte*, jobject>>& parts_to_free) {
+ for (auto& value : parts_to_free) {
+ jobject jk;
+ jbyteArray jk_ba;
+ jbyte* jk_val;
+ std::tie(jk_ba, jk_val, jk) = value;
+ env->ReleaseByteArrayElements(jk_ba, jk_val, JNI_ABORT);
+ env->DeleteLocalRef(jk);
+ }
+}
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+// cf multi get
+jobjectArray txn_multi_get_helper(JNIEnv* env, const FnMultiGet& fn_multi_get,
+ const jlong& jread_options_handle,
+ const jobjectArray& jkey_parts) {
+ const jsize len_key_parts = env->GetArrayLength(jkey_parts);
+ if (env->EnsureLocalCapacity(len_key_parts) != 0) {
+ // out of memory
+ return nullptr;
+ }
+
+ std::vector<rocksdb::Slice> key_parts;
+ std::vector<std::tuple<jbyteArray, jbyte*, jobject>> key_parts_to_free;
+ for (int i = 0; i < len_key_parts; i++) {
+ const jobject jk = env->GetObjectArrayElement(jkey_parts, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ free_parts(env, key_parts_to_free);
+ return nullptr;
+ }
+ jbyteArray jk_ba = reinterpret_cast<jbyteArray>(jk);
+ const jsize len_key = env->GetArrayLength(jk_ba);
+ if (env->EnsureLocalCapacity(len_key) != 0) {
+ // out of memory
+ env->DeleteLocalRef(jk);
+ free_parts(env, key_parts_to_free);
+ return nullptr;
+ }
+ jbyte* jk_val = env->GetByteArrayElements(jk_ba, nullptr);
+ if (jk_val == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jk);
+ free_parts(env, key_parts_to_free);
+ return nullptr;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(jk_val), len_key);
+ key_parts.push_back(key_slice);
+
+ key_parts_to_free.push_back(std::make_tuple(jk_ba, jk_val, jk));
+ }
+
+ auto* read_options =
+ reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ std::vector<std::string> value_parts;
+ std::vector<rocksdb::Status> s =
+ fn_multi_get(*read_options, key_parts, &value_parts);
+
+ // free up allocated byte arrays
+ free_parts(env, key_parts_to_free);
+
+ // prepare the results
+ const jclass jcls_ba = env->FindClass("[B");
+ jobjectArray jresults =
+ env->NewObjectArray(static_cast<jsize>(s.size()), jcls_ba, nullptr);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ // add to the jresults
+ for (std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) {
+ if (s[i].ok()) {
+ jbyteArray jentry_value =
+ env->NewByteArray(static_cast<jsize>(value_parts[i].size()));
+ if (jentry_value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(
+ jentry_value, 0, static_cast<jsize>(value_parts[i].size()),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value_parts[i].c_str())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jentry_value);
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jentry_value);
+ env->DeleteLocalRef(jentry_value);
+ }
+ }
+
+ return jresults;
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: multiGet
+ * Signature: (JJ[[B[J)[[B
+ */
+jobjectArray Java_org_rocksdb_Transaction_multiGet__JJ_3_3B_3J(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jobjectArray jkey_parts, jlongArray jcolumn_family_handles) {
+ bool has_exception = false;
+ const std::vector<rocksdb::ColumnFamilyHandle*> column_family_handles =
+ txn_column_families_helper(env, jcolumn_family_handles, &has_exception);
+ if (has_exception) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnMultiGet fn_multi_get =
+ std::bind<std::vector<rocksdb::Status> (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&,
+ const std::vector<rocksdb::ColumnFamilyHandle*>&,
+ const std::vector<rocksdb::Slice>&, std::vector<std::string>*)>(
+ &rocksdb::Transaction::MultiGet, txn, _1, column_family_handles, _2,
+ _3);
+ return txn_multi_get_helper(env, fn_multi_get, jread_options_handle,
+ jkey_parts);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: multiGet
+ * Signature: (JJ[[B)[[B
+ */
+jobjectArray Java_org_rocksdb_Transaction_multiGet__JJ_3_3B(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jobjectArray jkey_parts) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnMultiGet fn_multi_get =
+ std::bind<std::vector<rocksdb::Status> (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&, const std::vector<rocksdb::Slice>&,
+ std::vector<std::string>*)>(&rocksdb::Transaction::MultiGet, txn, _1,
+ _2, _3);
+ return txn_multi_get_helper(env, fn_multi_get, jread_options_handle,
+ jkey_parts);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getForUpdate
+ * Signature: (JJ[BIJZZ)[B
+ */
+jbyteArray Java_org_rocksdb_Transaction_getForUpdate__JJ_3BIJZZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jbyteArray jkey, jint jkey_part_len, jlong jcolumn_family_handle,
+ jboolean jexclusive, jboolean jdo_validate) {
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnGet fn_get_for_update = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&, rocksdb::ColumnFamilyHandle*,
+ const rocksdb::Slice&, std::string*, bool, bool)>(
+ &rocksdb::Transaction::GetForUpdate, txn, _1, column_family_handle, _2,
+ _3, jexclusive, jdo_validate);
+ return txn_get_helper(env, fn_get_for_update, jread_options_handle, jkey,
+ jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getForUpdate
+ * Signature: (JJ[BIZZ)[B
+ */
+jbyteArray Java_org_rocksdb_Transaction_getForUpdate__JJ_3BIZZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jbyteArray jkey, jint jkey_part_len, jboolean jexclusive,
+ jboolean jdo_validate) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnGet fn_get_for_update = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&, const rocksdb::Slice&, std::string*, bool,
+ bool)>(&rocksdb::Transaction::GetForUpdate, txn, _1, _2, _3, jexclusive,
+ jdo_validate);
+ return txn_get_helper(env, fn_get_for_update, jread_options_handle, jkey,
+ jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: multiGetForUpdate
+ * Signature: (JJ[[B[J)[[B
+ */
+jobjectArray Java_org_rocksdb_Transaction_multiGetForUpdate__JJ_3_3B_3J(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jobjectArray jkey_parts, jlongArray jcolumn_family_handles) {
+ bool has_exception = false;
+ const std::vector<rocksdb::ColumnFamilyHandle*> column_family_handles =
+ txn_column_families_helper(env, jcolumn_family_handles, &has_exception);
+ if (has_exception) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnMultiGet fn_multi_get_for_update =
+ std::bind<std::vector<rocksdb::Status> (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&,
+ const std::vector<rocksdb::ColumnFamilyHandle*>&,
+ const std::vector<rocksdb::Slice>&, std::vector<std::string>*)>(
+ &rocksdb::Transaction::MultiGetForUpdate, txn, _1,
+ column_family_handles, _2, _3);
+ return txn_multi_get_helper(env, fn_multi_get_for_update,
+ jread_options_handle, jkey_parts);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: multiGetForUpdate
+ * Signature: (JJ[[B)[[B
+ */
+jobjectArray Java_org_rocksdb_Transaction_multiGetForUpdate__JJ_3_3B(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
+ jobjectArray jkey_parts) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnMultiGet fn_multi_get_for_update =
+ std::bind<std::vector<rocksdb::Status> (rocksdb::Transaction::*)(
+ const rocksdb::ReadOptions&, const std::vector<rocksdb::Slice>&,
+ std::vector<std::string>*)>(&rocksdb::Transaction::MultiGetForUpdate,
+ txn, _1, _2, _3);
+ return txn_multi_get_helper(env, fn_multi_get_for_update,
+ jread_options_handle, jkey_parts);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getIterator
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_Transaction_getIterator__JJ(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong jread_options_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* read_options =
+ reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ return reinterpret_cast<jlong>(txn->GetIterator(*read_options));
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getIterator
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_Transaction_getIterator__JJJ(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jread_options_handle, jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* read_options =
+ reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ return reinterpret_cast<jlong>(
+ txn->GetIterator(*read_options, column_family_handle));
+}
+
+typedef std::function<rocksdb::Status(const rocksdb::Slice&,
+ const rocksdb::Slice&)>
+ FnWriteKV;
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+void txn_write_kv_helper(JNIEnv* env, const FnWriteKV& fn_write_kv,
+ const jbyteArray& jkey, const jint& jkey_part_len,
+ const jbyteArray& jval, const jint& jval_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ jbyte* value = env->GetByteArrayElements(jval, nullptr);
+ if (value == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+ return;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_part_len);
+ rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jval_len);
+
+ rocksdb::Status s = fn_write_kv(key_slice, value_slice);
+
+ // trigger java unref on key.
+ // by passing JNI_ABORT, it will simply release the reference without
+ // copying the result back to the java byte array.
+ env->ReleaseByteArrayElements(jval, value, JNI_ABORT);
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+
+ if (s.ok()) {
+ return;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: put
+ * Signature: (J[BI[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_put__J_3BI_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len,
+ jlong jcolumn_family_handle, jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKV fn_put = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::Slice&,
+ const rocksdb::Slice&, bool)>(&rocksdb::Transaction::Put, txn,
+ column_family_handle, _1, _2,
+ jassume_tracked);
+ txn_write_kv_helper(env, fn_put, jkey, jkey_part_len, jval, jval_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: put
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_Transaction_put__J_3BI_3BI(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len,
+ jbyteArray jval,
+ jint jval_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKV fn_put = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::Slice&, const rocksdb::Slice&)>(&rocksdb::Transaction::Put,
+ txn, _1, _2);
+ txn_write_kv_helper(env, fn_put, jkey, jkey_part_len, jval, jval_len);
+}
+
+typedef std::function<rocksdb::Status(const rocksdb::SliceParts&,
+ const rocksdb::SliceParts&)>
+ FnWriteKVParts;
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+void txn_write_kv_parts_helper(JNIEnv* env,
+ const FnWriteKVParts& fn_write_kv_parts,
+ const jobjectArray& jkey_parts,
+ const jint& jkey_parts_len,
+ const jobjectArray& jvalue_parts,
+ const jint& jvalue_parts_len) {
+#ifndef DEBUG
+ (void) jvalue_parts_len;
+#else
+ assert(jkey_parts_len == jvalue_parts_len);
+#endif
+
+ auto key_parts = std::vector<rocksdb::Slice>();
+ auto value_parts = std::vector<rocksdb::Slice>();
+ auto jparts_to_free = std::vector<std::tuple<jbyteArray, jbyte*, jobject>>();
+
+ // convert java key_parts/value_parts byte[][] to Slice(s)
+ for (jsize i = 0; i < jkey_parts_len; ++i) {
+ const jobject jobj_key_part = env->GetObjectArrayElement(jkey_parts, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ free_parts(env, jparts_to_free);
+ return;
+ }
+ const jobject jobj_value_part = env->GetObjectArrayElement(jvalue_parts, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jparts_to_free);
+ return;
+ }
+
+ const jbyteArray jba_key_part = reinterpret_cast<jbyteArray>(jobj_key_part);
+ const jsize jkey_part_len = env->GetArrayLength(jba_key_part);
+ if (env->EnsureLocalCapacity(jkey_part_len) != 0) {
+ // out of memory
+ env->DeleteLocalRef(jobj_value_part);
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jparts_to_free);
+ return;
+ }
+ jbyte* jkey_part = env->GetByteArrayElements(jba_key_part, nullptr);
+ if (jkey_part == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jobj_value_part);
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jparts_to_free);
+ return;
+ }
+
+ const jbyteArray jba_value_part =
+ reinterpret_cast<jbyteArray>(jobj_value_part);
+ const jsize jvalue_part_len = env->GetArrayLength(jba_value_part);
+ if (env->EnsureLocalCapacity(jvalue_part_len) != 0) {
+ // out of memory
+ env->DeleteLocalRef(jobj_value_part);
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jparts_to_free);
+ return;
+ }
+ jbyte* jvalue_part = env->GetByteArrayElements(jba_value_part, nullptr);
+ if (jvalue_part == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseByteArrayElements(jba_value_part, jvalue_part, JNI_ABORT);
+ env->DeleteLocalRef(jobj_value_part);
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jparts_to_free);
+ return;
+ }
+
+ jparts_to_free.push_back(
+ std::make_tuple(jba_key_part, jkey_part, jobj_key_part));
+ jparts_to_free.push_back(
+ std::make_tuple(jba_value_part, jvalue_part, jobj_value_part));
+
+ key_parts.push_back(
+ rocksdb::Slice(reinterpret_cast<char*>(jkey_part), jkey_part_len));
+ value_parts.push_back(
+ rocksdb::Slice(reinterpret_cast<char*>(jvalue_part), jvalue_part_len));
+ }
+
+ // call the write_multi function
+ rocksdb::Status s = fn_write_kv_parts(
+ rocksdb::SliceParts(key_parts.data(), (int)key_parts.size()),
+ rocksdb::SliceParts(value_parts.data(), (int)value_parts.size()));
+
+ // cleanup temporary memory
+ free_parts(env, jparts_to_free);
+
+ // return
+ if (s.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: put
+ * Signature: (J[[BI[[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_put__J_3_3BI_3_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len,
+ jlong jcolumn_family_handle, jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKVParts fn_put_parts =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::SliceParts&,
+ const rocksdb::SliceParts&, bool)>(&rocksdb::Transaction::Put, txn,
+ column_family_handle, _1, _2,
+ jassume_tracked);
+ txn_write_kv_parts_helper(env, fn_put_parts, jkey_parts, jkey_parts_len,
+ jvalue_parts, jvalue_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: put
+ * Signature: (J[[BI[[BI)V
+ */
+void Java_org_rocksdb_Transaction_put__J_3_3BI_3_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKVParts fn_put_parts =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::SliceParts&, const rocksdb::SliceParts&)>(
+ &rocksdb::Transaction::Put, txn, _1, _2);
+ txn_write_kv_parts_helper(env, fn_put_parts, jkey_parts, jkey_parts_len,
+ jvalue_parts, jvalue_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: merge
+ * Signature: (J[BI[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_merge__J_3BI_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len,
+ jlong jcolumn_family_handle, jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKV fn_merge = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::Slice&,
+ const rocksdb::Slice&, bool)>(&rocksdb::Transaction::Merge, txn,
+ column_family_handle, _1, _2,
+ jassume_tracked);
+ txn_write_kv_helper(env, fn_merge, jkey, jkey_part_len, jval, jval_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: merge
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_Transaction_merge__J_3BI_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKV fn_merge = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::Slice&, const rocksdb::Slice&)>(
+ &rocksdb::Transaction::Merge, txn, _1, _2);
+ txn_write_kv_helper(env, fn_merge, jkey, jkey_part_len, jval, jval_len);
+}
+
+typedef std::function<rocksdb::Status(const rocksdb::Slice&)> FnWriteK;
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+void txn_write_k_helper(JNIEnv* env, const FnWriteK& fn_write_k,
+ const jbyteArray& jkey, const jint& jkey_part_len) {
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_part_len);
+
+ rocksdb::Status s = fn_write_k(key_slice);
+
+ // trigger java unref on key.
+ // by passing JNI_ABORT, it will simply release the reference without
+ // copying the result back to the java byte array.
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+
+ if (s.ok()) {
+ return;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: delete
+ * Signature: (J[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_delete__J_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jlong jcolumn_family_handle, jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteK fn_delete = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::Slice&, bool)>(
+ &rocksdb::Transaction::Delete, txn, column_family_handle, _1,
+ jassume_tracked);
+ txn_write_k_helper(env, fn_delete, jkey, jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: delete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_Transaction_delete__J_3BI(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteK fn_delete = std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::Slice&)>(&rocksdb::Transaction::Delete, txn, _1);
+ txn_write_k_helper(env, fn_delete, jkey, jkey_part_len);
+}
+
+typedef std::function<rocksdb::Status(const rocksdb::SliceParts&)>
+ FnWriteKParts;
+
+// TODO(AR) consider refactoring to share this between here and rocksjni.cc
+void txn_write_k_parts_helper(JNIEnv* env,
+ const FnWriteKParts& fn_write_k_parts,
+ const jobjectArray& jkey_parts,
+ const jint& jkey_parts_len) {
+ std::vector<rocksdb::Slice> key_parts;
+ std::vector<std::tuple<jbyteArray, jbyte*, jobject>> jkey_parts_to_free;
+
+ // convert java key_parts byte[][] to Slice(s)
+ for (jint i = 0; i < jkey_parts_len; ++i) {
+ const jobject jobj_key_part = env->GetObjectArrayElement(jkey_parts, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ free_parts(env, jkey_parts_to_free);
+ return;
+ }
+
+ const jbyteArray jba_key_part = reinterpret_cast<jbyteArray>(jobj_key_part);
+ const jsize jkey_part_len = env->GetArrayLength(jba_key_part);
+ if (env->EnsureLocalCapacity(jkey_part_len) != 0) {
+ // out of memory
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jkey_parts_to_free);
+ return;
+ }
+ jbyte* jkey_part = env->GetByteArrayElements(jba_key_part, nullptr);
+ if (jkey_part == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jobj_key_part);
+ free_parts(env, jkey_parts_to_free);
+ return;
+ }
+
+ jkey_parts_to_free.push_back(std::tuple<jbyteArray, jbyte*, jobject>(
+ jba_key_part, jkey_part, jobj_key_part));
+
+ key_parts.push_back(
+ rocksdb::Slice(reinterpret_cast<char*>(jkey_part), jkey_part_len));
+ }
+
+ // call the write_multi function
+ rocksdb::Status s = fn_write_k_parts(
+ rocksdb::SliceParts(key_parts.data(), (int)key_parts.size()));
+
+ // cleanup temporary memory
+ free_parts(env, jkey_parts_to_free);
+
+ // return
+ if (s.ok()) {
+ return;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: delete
+ * Signature: (J[[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_delete__J_3_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jlong jcolumn_family_handle,
+ jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKParts fn_delete_parts =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::SliceParts&, bool)>(
+ &rocksdb::Transaction::Delete, txn, column_family_handle, _1,
+ jassume_tracked);
+ txn_write_k_parts_helper(env, fn_delete_parts, jkey_parts, jkey_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: delete
+ * Signature: (J[[BI)V
+ */
+void Java_org_rocksdb_Transaction_delete__J_3_3BI(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle,
+ jobjectArray jkey_parts,
+ jint jkey_parts_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKParts fn_delete_parts =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::SliceParts&)>(&rocksdb::Transaction::Delete, txn, _1);
+ txn_write_k_parts_helper(env, fn_delete_parts, jkey_parts, jkey_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: singleDelete
+ * Signature: (J[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_singleDelete__J_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jlong jcolumn_family_handle, jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteK fn_single_delete =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::Slice&, bool)>(
+ &rocksdb::Transaction::SingleDelete, txn, column_family_handle, _1,
+ jassume_tracked);
+ txn_write_k_helper(env, fn_single_delete, jkey, jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: singleDelete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_Transaction_singleDelete__J_3BI(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jbyteArray jkey,
+ jint jkey_part_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteK fn_single_delete =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::Slice&)>(&rocksdb::Transaction::SingleDelete, txn, _1);
+ txn_write_k_helper(env, fn_single_delete, jkey, jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: singleDelete
+ * Signature: (J[[BIJZ)V
+ */
+void Java_org_rocksdb_Transaction_singleDelete__J_3_3BIJZ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jlong jcolumn_family_handle,
+ jboolean jassume_tracked) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKParts fn_single_delete_parts =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::SliceParts&, bool)>(
+ &rocksdb::Transaction::SingleDelete, txn, column_family_handle, _1,
+ jassume_tracked);
+ txn_write_k_parts_helper(env, fn_single_delete_parts, jkey_parts,
+ jkey_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: singleDelete
+ * Signature: (J[[BI)V
+ */
+void Java_org_rocksdb_Transaction_singleDelete__J_3_3BI(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jobjectArray jkey_parts,
+ jint jkey_parts_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKParts fn_single_delete_parts = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(const rocksdb::SliceParts&)>(
+ &rocksdb::Transaction::SingleDelete, txn, _1);
+ txn_write_k_parts_helper(env, fn_single_delete_parts, jkey_parts,
+ jkey_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: putUntracked
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_Transaction_putUntracked__J_3BI_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len,
+ jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKV fn_put_untracked = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(rocksdb::ColumnFamilyHandle*,
+ const rocksdb::Slice&, const rocksdb::Slice&)>(
+ &rocksdb::Transaction::PutUntracked, txn, column_family_handle, _1, _2);
+ txn_write_kv_helper(env, fn_put_untracked, jkey, jkey_part_len, jval,
+ jval_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: putUntracked
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_Transaction_putUntracked__J_3BI_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKV fn_put_untracked = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(const rocksdb::Slice&, const rocksdb::Slice&)>(
+ &rocksdb::Transaction::PutUntracked, txn, _1, _2);
+ txn_write_kv_helper(env, fn_put_untracked, jkey, jkey_part_len, jval,
+ jval_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: putUntracked
+ * Signature: (J[[BI[[BIJ)V
+ */
+void Java_org_rocksdb_Transaction_putUntracked__J_3_3BI_3_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len,
+ jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKVParts fn_put_parts_untracked =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::SliceParts&,
+ const rocksdb::SliceParts&)>(&rocksdb::Transaction::PutUntracked, txn,
+ column_family_handle, _1, _2);
+ txn_write_kv_parts_helper(env, fn_put_parts_untracked, jkey_parts,
+ jkey_parts_len, jvalue_parts, jvalue_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: putUntracked
+ * Signature: (J[[BI[[BI)V
+ */
+void Java_org_rocksdb_Transaction_putUntracked__J_3_3BI_3_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKVParts fn_put_parts_untracked =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ const rocksdb::SliceParts&, const rocksdb::SliceParts&)>(
+ &rocksdb::Transaction::PutUntracked, txn, _1, _2);
+ txn_write_kv_parts_helper(env, fn_put_parts_untracked, jkey_parts,
+ jkey_parts_len, jvalue_parts, jvalue_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: mergeUntracked
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_Transaction_mergeUntracked__J_3BI_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len,
+ jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKV fn_merge_untracked = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(rocksdb::ColumnFamilyHandle*,
+ const rocksdb::Slice&, const rocksdb::Slice&)>(
+ &rocksdb::Transaction::MergeUntracked, txn, column_family_handle, _1, _2);
+ txn_write_kv_helper(env, fn_merge_untracked, jkey, jkey_part_len, jval,
+ jval_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: mergeUntracked
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_Transaction_mergeUntracked__J_3BI_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jbyteArray jval, jint jval_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKV fn_merge_untracked = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(const rocksdb::Slice&, const rocksdb::Slice&)>(
+ &rocksdb::Transaction::MergeUntracked, txn, _1, _2);
+ txn_write_kv_helper(env, fn_merge_untracked, jkey, jkey_part_len, jval,
+ jval_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: deleteUntracked
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_Transaction_deleteUntracked__J_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteK fn_delete_untracked =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::Slice&)>(
+ &rocksdb::Transaction::DeleteUntracked, txn, column_family_handle,
+ _1);
+ txn_write_k_helper(env, fn_delete_untracked, jkey, jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: deleteUntracked
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_Transaction_deleteUntracked__J_3BI(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jbyteArray jkey,
+ jint jkey_part_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteK fn_delete_untracked = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(const rocksdb::Slice&)>(
+ &rocksdb::Transaction::DeleteUntracked, txn, _1);
+ txn_write_k_helper(env, fn_delete_untracked, jkey, jkey_part_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: deleteUntracked
+ * Signature: (J[[BIJ)V
+ */
+void Java_org_rocksdb_Transaction_deleteUntracked__J_3_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len, jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ FnWriteKParts fn_delete_untracked_parts =
+ std::bind<rocksdb::Status (rocksdb::Transaction::*)(
+ rocksdb::ColumnFamilyHandle*, const rocksdb::SliceParts&)>(
+ &rocksdb::Transaction::DeleteUntracked, txn, column_family_handle,
+ _1);
+ txn_write_k_parts_helper(env, fn_delete_untracked_parts, jkey_parts,
+ jkey_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: deleteUntracked
+ * Signature: (J[[BI)V
+ */
+void Java_org_rocksdb_Transaction_deleteUntracked__J_3_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
+ jint jkey_parts_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ FnWriteKParts fn_delete_untracked_parts = std::bind<rocksdb::Status (
+ rocksdb::Transaction::*)(const rocksdb::SliceParts&)>(
+ &rocksdb::Transaction::DeleteUntracked, txn, _1);
+ txn_write_k_parts_helper(env, fn_delete_untracked_parts, jkey_parts,
+ jkey_parts_len);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: putLogData
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_Transaction_putLogData(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_part_len);
+ txn->PutLogData(key_slice);
+
+ // trigger java unref on key.
+ // by passing JNI_ABORT, it will simply release the reference without
+ // copying the result back to the java byte array.
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: disableIndexing
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_disableIndexing(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->DisableIndexing();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: enableIndexing
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_enableIndexing(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->EnableIndexing();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getNumKeys
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getNumKeys(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return txn->GetNumKeys();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getNumPuts
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getNumPuts(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return txn->GetNumPuts();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getNumDeletes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getNumDeletes(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return txn->GetNumDeletes();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getNumMerges
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getNumMerges(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return txn->GetNumMerges();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getElapsedTime
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getElapsedTime(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return txn->GetElapsedTime();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getWriteBatch
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getWriteBatch(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return reinterpret_cast<jlong>(txn->GetWriteBatch());
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setLockTimeout
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Transaction_setLockTimeout(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong jlock_timeout) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->SetLockTimeout(jlock_timeout);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getWriteOptions
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getWriteOptions(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return reinterpret_cast<jlong>(txn->GetWriteOptions());
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setWriteOptions
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Transaction_setWriteOptions(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong jwrite_options_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ txn->SetWriteOptions(*write_options);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: undo
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_Transaction_undoGetForUpdate__J_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
+ jint jkey_part_len, jlong jcolumn_family_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* column_family_handle =
+ reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcolumn_family_handle);
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_part_len);
+ txn->UndoGetForUpdate(column_family_handle, key_slice);
+
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: undoGetForUpdate
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_Transaction_undoGetForUpdate__J_3BI(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jbyteArray jkey,
+ jint jkey_part_len) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ jbyte* key = env->GetByteArrayElements(jkey, nullptr);
+ if (key == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_part_len);
+ txn->UndoGetForUpdate(key_slice);
+
+ env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: rebuildFromWriteBatch
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Transaction_rebuildFromWriteBatch(
+ JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jwrite_batch_handle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ auto* write_batch =
+ reinterpret_cast<rocksdb::WriteBatch*>(jwrite_batch_handle);
+ rocksdb::Status s = txn->RebuildFromWriteBatch(write_batch);
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getCommitTimeWriteBatch
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getCommitTimeWriteBatch(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return reinterpret_cast<jlong>(txn->GetCommitTimeWriteBatch());
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setLogNumber
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Transaction_setLogNumber(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong jhandle,
+ jlong jlog_number) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ txn->SetLogNumber(jlog_number);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getLogNumber
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getLogNumber(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return txn->GetLogNumber();
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: setName
+ * Signature: (JLjava/lang/String;)V
+ */
+void Java_org_rocksdb_Transaction_setName(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle, jstring jname) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ const char* name = env->GetStringUTFChars(jname, nullptr);
+ if (name == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Status s = txn->SetName(name);
+
+ env->ReleaseStringUTFChars(jname, name);
+
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getName
+ * Signature: (J)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_Transaction_getName(JNIEnv* env, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::TransactionName name = txn->GetName();
+ return env->NewStringUTF(name.data());
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getID
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getID(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::TransactionID id = txn->GetID();
+ return static_cast<jlong>(id);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: isDeadlockDetect
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_Transaction_isDeadlockDetect(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ return static_cast<jboolean>(txn->IsDeadlockDetect());
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getWaitingTxns
+ * Signature: (J)Lorg/rocksdb/Transaction/WaitingTransactions;
+ */
+jobject Java_org_rocksdb_Transaction_getWaitingTxns(JNIEnv* env,
+ jobject jtransaction_obj,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ uint32_t column_family_id;
+ std::string key;
+ std::vector<rocksdb::TransactionID> waiting_txns =
+ txn->GetWaitingTxns(&column_family_id, &key);
+ jobject jwaiting_txns = rocksdb::TransactionJni::newWaitingTransactions(
+ env, jtransaction_obj, column_family_id, key, waiting_txns);
+ return jwaiting_txns;
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getState
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_Transaction_getState(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ rocksdb::Transaction::TransactionState txn_status = txn->GetState();
+ switch (txn_status) {
+ case rocksdb::Transaction::TransactionState::STARTED:
+ return 0x0;
+
+ case rocksdb::Transaction::TransactionState::AWAITING_PREPARE:
+ return 0x1;
+
+ case rocksdb::Transaction::TransactionState::PREPARED:
+ return 0x2;
+
+ case rocksdb::Transaction::TransactionState::AWAITING_COMMIT:
+ return 0x3;
+
+ case rocksdb::Transaction::TransactionState::COMMITED:
+ return 0x4;
+
+ case rocksdb::Transaction::TransactionState::AWAITING_ROLLBACK:
+ return 0x5;
+
+ case rocksdb::Transaction::TransactionState::ROLLEDBACK:
+ return 0x6;
+
+ case rocksdb::Transaction::TransactionState::LOCKS_STOLEN:
+ return 0x7;
+ }
+
+ assert(false);
+ return static_cast<jbyte>(-1);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: getId
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_Transaction_getId(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jhandle) {
+ auto* txn = reinterpret_cast<rocksdb::Transaction*>(jhandle);
+ uint64_t id = txn->GetId();
+ return static_cast<jlong>(id);
+}
+
+/*
+ * Class: org_rocksdb_Transaction
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_Transaction_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ delete reinterpret_cast<rocksdb::Transaction*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/transaction_db.cc b/src/rocksdb/java/rocksjni/transaction_db.cc
new file mode 100644
index 00000000..c2c40bf1
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_db.cc
@@ -0,0 +1,453 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::TransactionDB.
+
+#include <jni.h>
+#include <functional>
+#include <memory>
+#include <utility>
+
+#include "include/org_rocksdb_TransactionDB.h"
+
+#include "rocksdb/options.h"
+#include "rocksdb/utilities/transaction.h"
+#include "rocksdb/utilities/transaction_db.h"
+
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: open
+ * Signature: (JJLjava/lang/String;)J
+ */
+jlong Java_org_rocksdb_TransactionDB_open__JJLjava_lang_String_2(
+ JNIEnv* env, jclass, jlong joptions_handle,
+ jlong jtxn_db_options_handle, jstring jdb_path) {
+ auto* options = reinterpret_cast<rocksdb::Options*>(joptions_handle);
+ auto* txn_db_options =
+ reinterpret_cast<rocksdb::TransactionDBOptions*>(jtxn_db_options_handle);
+ rocksdb::TransactionDB* tdb = nullptr;
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ rocksdb::Status s =
+ rocksdb::TransactionDB::Open(*options, *txn_db_options, db_path, &tdb);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(tdb);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+ }
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: open
+ * Signature: (JJLjava/lang/String;[[B[J)[J
+ */
+jlongArray Java_org_rocksdb_TransactionDB_open__JJLjava_lang_String_2_3_3B_3J(
+ JNIEnv* env, jclass, jlong jdb_options_handle,
+ jlong jtxn_db_options_handle, jstring jdb_path, jobjectArray jcolumn_names,
+ jlongArray jcolumn_options_handles) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ const jsize len_cols = env->GetArrayLength(jcolumn_names);
+ if (env->EnsureLocalCapacity(len_cols) != 0) {
+ // out of memory
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ jlong* jco = env->GetLongArrayElements(jcolumn_options_handles, nullptr);
+ if (jco == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+ std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
+ for (int i = 0; i < len_cols; i++) {
+ const jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+ const jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
+ jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, nullptr);
+ if (jcf_name == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jcn);
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ const int jcf_name_len = env->GetArrayLength(jcn_ba);
+ if (env->EnsureLocalCapacity(jcf_name_len) != 0) {
+ // out of memory
+ env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
+ env->DeleteLocalRef(jcn);
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+ const std::string cf_name(reinterpret_cast<char*>(jcf_name), jcf_name_len);
+ const rocksdb::ColumnFamilyOptions* cf_options =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[i]);
+ column_families.push_back(
+ rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
+
+ env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
+ env->DeleteLocalRef(jcn);
+ }
+ env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
+
+ auto* db_options = reinterpret_cast<rocksdb::DBOptions*>(jdb_options_handle);
+ auto* txn_db_options =
+ reinterpret_cast<rocksdb::TransactionDBOptions*>(jtxn_db_options_handle);
+ std::vector<rocksdb::ColumnFamilyHandle*> handles;
+ rocksdb::TransactionDB* tdb = nullptr;
+ const rocksdb::Status s = rocksdb::TransactionDB::Open(
+ *db_options, *txn_db_options, db_path, column_families, &handles, &tdb);
+
+ // check if open operation was successful
+ if (s.ok()) {
+ const jsize resultsLen = 1 + len_cols; // db handle + column family handles
+ std::unique_ptr<jlong[]> results =
+ std::unique_ptr<jlong[]>(new jlong[resultsLen]);
+ results[0] = reinterpret_cast<jlong>(tdb);
+ for (int i = 1; i <= len_cols; i++) {
+ results[i] = reinterpret_cast<jlong>(handles[i - 1]);
+ }
+
+ jlongArray jresults = env->NewLongArray(resultsLen);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jresults);
+ return nullptr;
+ }
+ return jresults;
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return nullptr;
+ }
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionDB_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ assert(txn_db != nullptr);
+ delete txn_db;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: closeDatabase
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionDB_closeDatabase(
+ JNIEnv* env, jclass, jlong jhandle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ assert(txn_db != nullptr);
+ rocksdb::Status s = txn_db->Close();
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: beginTransaction
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_TransactionDB_beginTransaction__JJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ rocksdb::Transaction* txn = txn_db->BeginTransaction(*write_options);
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: beginTransaction
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_TransactionDB_beginTransaction__JJJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle,
+ jlong jtxn_options_handle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* txn_options =
+ reinterpret_cast<rocksdb::TransactionOptions*>(jtxn_options_handle);
+ rocksdb::Transaction* txn =
+ txn_db->BeginTransaction(*write_options, *txn_options);
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: beginTransaction_withOld
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_TransactionDB_beginTransaction_1withOld__JJJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle,
+ jlong jold_txn_handle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* old_txn = reinterpret_cast<rocksdb::Transaction*>(jold_txn_handle);
+ rocksdb::TransactionOptions txn_options;
+ rocksdb::Transaction* txn =
+ txn_db->BeginTransaction(*write_options, txn_options, old_txn);
+
+ // RocksJava relies on the assumption that
+ // we do not allocate a new Transaction object
+ // when providing an old_txn
+ assert(txn == old_txn);
+
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: beginTransaction_withOld
+ * Signature: (JJJJ)J
+ */
+jlong Java_org_rocksdb_TransactionDB_beginTransaction_1withOld__JJJJ(
+ JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle,
+ jlong jtxn_options_handle, jlong jold_txn_handle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ auto* write_options =
+ reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle);
+ auto* txn_options =
+ reinterpret_cast<rocksdb::TransactionOptions*>(jtxn_options_handle);
+ auto* old_txn = reinterpret_cast<rocksdb::Transaction*>(jold_txn_handle);
+ rocksdb::Transaction* txn =
+ txn_db->BeginTransaction(*write_options, *txn_options, old_txn);
+
+ // RocksJava relies on the assumption that
+ // we do not allocate a new Transaction object
+ // when providing an old_txn
+ assert(txn == old_txn);
+
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: getTransactionByName
+ * Signature: (JLjava/lang/String;)J
+ */
+jlong Java_org_rocksdb_TransactionDB_getTransactionByName(
+ JNIEnv* env, jobject, jlong jhandle, jstring jname) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ const char* name = env->GetStringUTFChars(jname, nullptr);
+ if (name == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ rocksdb::Transaction* txn = txn_db->GetTransactionByName(name);
+ env->ReleaseStringUTFChars(jname, name);
+ return reinterpret_cast<jlong>(txn);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: getAllPreparedTransactions
+ * Signature: (J)[J
+ */
+jlongArray Java_org_rocksdb_TransactionDB_getAllPreparedTransactions(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ std::vector<rocksdb::Transaction*> txns;
+ txn_db->GetAllPreparedTransactions(&txns);
+
+ const size_t size = txns.size();
+ assert(size < UINT32_MAX); // does it fit in a jint?
+
+ const jsize len = static_cast<jsize>(size);
+ std::vector<jlong> tmp(len);
+ for (jsize i = 0; i < len; ++i) {
+ tmp[i] = reinterpret_cast<jlong>(txns[i]);
+ }
+
+ jlongArray jtxns = env->NewLongArray(len);
+ if (jtxns == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ env->SetLongArrayRegion(jtxns, 0, len, tmp.data());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jtxns);
+ return nullptr;
+ }
+
+ return jtxns;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: getLockStatusData
+ * Signature: (J)Ljava/util/Map;
+ */
+jobject Java_org_rocksdb_TransactionDB_getLockStatusData(
+ JNIEnv* env, jobject, jlong jhandle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ const std::unordered_multimap<uint32_t, rocksdb::KeyLockInfo>
+ lock_status_data = txn_db->GetLockStatusData();
+ const jobject jlock_status_data = rocksdb::HashMapJni::construct(
+ env, static_cast<uint32_t>(lock_status_data.size()));
+ if (jlock_status_data == nullptr) {
+ // exception occurred
+ return nullptr;
+ }
+
+ const rocksdb::HashMapJni::FnMapKV<const int32_t, const rocksdb::KeyLockInfo, jobject, jobject>
+ fn_map_kv =
+ [env](
+ const std::pair<const int32_t, const rocksdb::KeyLockInfo>&
+ pair) {
+ const jobject jlong_column_family_id =
+ rocksdb::LongJni::valueOf(env, pair.first);
+ if (jlong_column_family_id == nullptr) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+ const jobject jkey_lock_info =
+ rocksdb::KeyLockInfoJni::construct(env, pair.second);
+ if (jkey_lock_info == nullptr) {
+ // an error occurred
+ return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
+ }
+ return std::unique_ptr<std::pair<jobject, jobject>>(
+ new std::pair<jobject, jobject>(jlong_column_family_id,
+ jkey_lock_info));
+ };
+
+ if (!rocksdb::HashMapJni::putAll(env, jlock_status_data,
+ lock_status_data.begin(),
+ lock_status_data.end(), fn_map_kv)) {
+ // exception occcurred
+ return nullptr;
+ }
+
+ return jlock_status_data;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: getDeadlockInfoBuffer
+ * Signature: (J)[Lorg/rocksdb/TransactionDB/DeadlockPath;
+ */
+jobjectArray Java_org_rocksdb_TransactionDB_getDeadlockInfoBuffer(
+ JNIEnv* env, jobject jobj, jlong jhandle) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ const std::vector<rocksdb::DeadlockPath> deadlock_info_buffer =
+ txn_db->GetDeadlockInfoBuffer();
+
+ const jsize deadlock_info_buffer_len =
+ static_cast<jsize>(deadlock_info_buffer.size());
+ jobjectArray jdeadlock_info_buffer =
+ env->NewObjectArray(deadlock_info_buffer_len,
+ rocksdb::DeadlockPathJni::getJClass(env), nullptr);
+ if (jdeadlock_info_buffer == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+ jsize jdeadlock_info_buffer_offset = 0;
+
+ auto buf_end = deadlock_info_buffer.end();
+ for (auto buf_it = deadlock_info_buffer.begin(); buf_it != buf_end;
+ ++buf_it) {
+ const rocksdb::DeadlockPath deadlock_path = *buf_it;
+ const std::vector<rocksdb::DeadlockInfo> deadlock_infos =
+ deadlock_path.path;
+ const jsize deadlock_infos_len =
+ static_cast<jsize>(deadlock_info_buffer.size());
+ jobjectArray jdeadlock_infos = env->NewObjectArray(
+ deadlock_infos_len, rocksdb::DeadlockInfoJni::getJClass(env), nullptr);
+ if (jdeadlock_infos == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->DeleteLocalRef(jdeadlock_info_buffer);
+ return nullptr;
+ }
+ jsize jdeadlock_infos_offset = 0;
+
+ auto infos_end = deadlock_infos.end();
+ for (auto infos_it = deadlock_infos.begin(); infos_it != infos_end;
+ ++infos_it) {
+ const rocksdb::DeadlockInfo deadlock_info = *infos_it;
+ const jobject jdeadlock_info = rocksdb::TransactionDBJni::newDeadlockInfo(
+ env, jobj, deadlock_info.m_txn_id, deadlock_info.m_cf_id,
+ deadlock_info.m_waiting_key, deadlock_info.m_exclusive);
+ if (jdeadlock_info == nullptr) {
+ // exception occcurred
+ env->DeleteLocalRef(jdeadlock_info_buffer);
+ return nullptr;
+ }
+ env->SetObjectArrayElement(jdeadlock_infos, jdeadlock_infos_offset++,
+ jdeadlock_info);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException or
+ // ArrayStoreException
+ env->DeleteLocalRef(jdeadlock_info);
+ env->DeleteLocalRef(jdeadlock_info_buffer);
+ return nullptr;
+ }
+ }
+
+ const jobject jdeadlock_path = rocksdb::DeadlockPathJni::construct(
+ env, jdeadlock_infos, deadlock_path.limit_exceeded);
+ if (jdeadlock_path == nullptr) {
+ // exception occcurred
+ env->DeleteLocalRef(jdeadlock_info_buffer);
+ return nullptr;
+ }
+ env->SetObjectArrayElement(jdeadlock_info_buffer,
+ jdeadlock_info_buffer_offset++, jdeadlock_path);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException or ArrayStoreException
+ env->DeleteLocalRef(jdeadlock_path);
+ env->DeleteLocalRef(jdeadlock_info_buffer);
+ return nullptr;
+ }
+ }
+
+ return jdeadlock_info_buffer;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDB
+ * Method: setDeadlockInfoBufferSize
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_TransactionDB_setDeadlockInfoBufferSize(
+ JNIEnv*, jobject, jlong jhandle, jint jdeadlock_info_buffer_size) {
+ auto* txn_db = reinterpret_cast<rocksdb::TransactionDB*>(jhandle);
+ txn_db->SetDeadlockInfoBufferSize(jdeadlock_info_buffer_size);
+}
diff --git a/src/rocksdb/java/rocksjni/transaction_db_options.cc b/src/rocksdb/java/rocksjni/transaction_db_options.cc
new file mode 100644
index 00000000..391accc3
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_db_options.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::TransactionDBOptions.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_TransactionDBOptions.h"
+
+#include "rocksdb/utilities/transaction_db.h"
+
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: newTransactionDBOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_TransactionDBOptions_newTransactionDBOptions(
+ JNIEnv* /*env*/, jclass /*jcls*/) {
+ rocksdb::TransactionDBOptions* opts = new rocksdb::TransactionDBOptions();
+ return reinterpret_cast<jlong>(opts);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: getMaxNumLocks
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionDBOptions_getMaxNumLocks(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ return opts->max_num_locks;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: setMaxNumLocks
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionDBOptions_setMaxNumLocks(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jlong jmax_num_locks) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ opts->max_num_locks = jmax_num_locks;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: getNumStripes
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionDBOptions_getNumStripes(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ return opts->num_stripes;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: setNumStripes
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionDBOptions_setNumStripes(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong jnum_stripes) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ opts->num_stripes = jnum_stripes;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: getTransactionLockTimeout
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionDBOptions_getTransactionLockTimeout(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ return opts->transaction_lock_timeout;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: setTransactionLockTimeout
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionDBOptions_setTransactionLockTimeout(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jtransaction_lock_timeout) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ opts->transaction_lock_timeout = jtransaction_lock_timeout;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: getDefaultLockTimeout
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionDBOptions_getDefaultLockTimeout(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ return opts->default_lock_timeout;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: setDefaultLockTimeout
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionDBOptions_setDefaultLockTimeout(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jdefault_lock_timeout) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ opts->default_lock_timeout = jdefault_lock_timeout;
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: getWritePolicy
+ * Signature: (J)B
+ */
+jbyte Java_org_rocksdb_TransactionDBOptions_getWritePolicy(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ return rocksdb::TxnDBWritePolicyJni::toJavaTxnDBWritePolicy(
+ opts->write_policy);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: setWritePolicy
+ * Signature: (JB)V
+ */
+void Java_org_rocksdb_TransactionDBOptions_setWritePolicy(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jbyte jwrite_policy) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+ opts->write_policy =
+ rocksdb::TxnDBWritePolicyJni::toCppTxnDBWritePolicy(jwrite_policy);
+}
+
+/*
+ * Class: org_rocksdb_TransactionDBOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionDBOptions_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ delete reinterpret_cast<rocksdb::TransactionDBOptions*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/transaction_log.cc b/src/rocksdb/java/rocksjni/transaction_log.cc
new file mode 100644
index 00000000..8186a846
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_log.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::Iterator methods from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "include/org_rocksdb_TransactionLogIterator.h"
+#include "rocksdb/transaction_log.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_TransactionLogIterator
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionLogIterator_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ delete reinterpret_cast<rocksdb::TransactionLogIterator*>(handle);
+}
+
+/*
+ * Class: org_rocksdb_TransactionLogIterator
+ * Method: isValid
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_TransactionLogIterator_isValid(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<rocksdb::TransactionLogIterator*>(handle)->Valid();
+}
+
+/*
+ * Class: org_rocksdb_TransactionLogIterator
+ * Method: next
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionLogIterator_next(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::TransactionLogIterator*>(handle)->Next();
+}
+
+/*
+ * Class: org_rocksdb_TransactionLogIterator
+ * Method: status
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionLogIterator_status(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong handle) {
+ rocksdb::Status s =
+ reinterpret_cast<rocksdb::TransactionLogIterator*>(handle)->status();
+ if (!s.ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ }
+}
+
+/*
+ * Class: org_rocksdb_TransactionLogIterator
+ * Method: getBatch
+ * Signature: (J)Lorg/rocksdb/TransactionLogIterator$BatchResult
+ */
+jobject Java_org_rocksdb_TransactionLogIterator_getBatch(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong handle) {
+ rocksdb::BatchResult batch_result =
+ reinterpret_cast<rocksdb::TransactionLogIterator*>(handle)->GetBatch();
+ return rocksdb::BatchResultJni::construct(env, batch_result);
+}
diff --git a/src/rocksdb/java/rocksjni/transaction_notifier.cc b/src/rocksdb/java/rocksjni/transaction_notifier.cc
new file mode 100644
index 00000000..b60076e1
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_notifier.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::TransactionNotifier.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_AbstractTransactionNotifier.h"
+#include "rocksjni/transaction_notifier_jnicallback.h"
+
+/*
+ * Class: org_rocksdb_AbstractTransactionNotifier
+ * Method: createNewTransactionNotifier
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_AbstractTransactionNotifier_createNewTransactionNotifier(
+ JNIEnv* env, jobject jobj) {
+ auto* transaction_notifier =
+ new rocksdb::TransactionNotifierJniCallback(env, jobj);
+ auto* sptr_transaction_notifier =
+ new std::shared_ptr<rocksdb::TransactionNotifierJniCallback>(
+ transaction_notifier);
+ return reinterpret_cast<jlong>(sptr_transaction_notifier);
+}
+
+/*
+ * Class: org_rocksdb_AbstractTransactionNotifier
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_AbstractTransactionNotifier_disposeInternal(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ // TODO(AR) refactor to use JniCallback::JniCallback
+ // when https://github.com/facebook/rocksdb/pull/1241/ is merged
+ std::shared_ptr<rocksdb::TransactionNotifierJniCallback>* handle =
+ reinterpret_cast<
+ std::shared_ptr<rocksdb::TransactionNotifierJniCallback>*>(jhandle);
+ delete handle;
+}
diff --git a/src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.cc b/src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.cc
new file mode 100644
index 00000000..85f2a194
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::TransactionNotifier.
+
+#include "rocksjni/transaction_notifier_jnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+
+TransactionNotifierJniCallback::TransactionNotifierJniCallback(JNIEnv* env,
+ jobject jtransaction_notifier) : JniCallback(env, jtransaction_notifier) {
+ // we cache the method id for the JNI callback
+ m_jsnapshot_created_methodID =
+ AbstractTransactionNotifierJni::getSnapshotCreatedMethodId(env);
+}
+
+void TransactionNotifierJniCallback::SnapshotCreated(
+ const Snapshot* newSnapshot) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ assert(env != nullptr);
+
+ env->CallVoidMethod(m_jcallback_obj,
+ m_jsnapshot_created_methodID, reinterpret_cast<jlong>(newSnapshot));
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallVoidMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ releaseJniEnv(attached_thread);
+}
+} // namespace rocksdb
diff --git a/src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.h b/src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.h
new file mode 100644
index 00000000..8f67cdb8
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_notifier_jnicallback.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::TransactionNotifier.
+
+#ifndef JAVA_ROCKSJNI_TRANSACTION_NOTIFIER_JNICALLBACK_H_
+#define JAVA_ROCKSJNI_TRANSACTION_NOTIFIER_JNICALLBACK_H_
+
+#include <jni.h>
+
+#include "rocksdb/utilities/transaction.h"
+#include "rocksjni/jnicallback.h"
+
+namespace rocksdb {
+
+/**
+ * This class acts as a bridge between C++
+ * and Java. The methods in this class will be
+ * called back from the RocksDB TransactionDB or OptimisticTransactionDB (C++),
+ * we then callback to the appropriate Java method
+ * this enables TransactionNotifier to be implemented in Java.
+ *
+ * Unlike RocksJava's Comparator JNI Callback, we do not attempt
+ * to reduce Java object allocations by caching the Snapshot object
+ * presented to the callback. This could be revisited in future
+ * if performance is lacking.
+ */
+class TransactionNotifierJniCallback: public JniCallback,
+ public TransactionNotifier {
+ public:
+ TransactionNotifierJniCallback(JNIEnv* env, jobject jtransaction_notifier);
+ virtual void SnapshotCreated(const Snapshot* newSnapshot);
+
+ private:
+ jmethodID m_jsnapshot_created_methodID;
+};
+} // namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_TRANSACTION_NOTIFIER_JNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/transaction_options.cc b/src/rocksdb/java/rocksjni/transaction_options.cc
new file mode 100644
index 00000000..d18a5294
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/transaction_options.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++
+// for rocksdb::TransactionOptions.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_TransactionOptions.h"
+
+#include "rocksdb/utilities/transaction_db.h"
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: newTransactionOptions
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_TransactionOptions_newTransactionOptions(
+ JNIEnv* /*env*/, jclass /*jcls*/) {
+ auto* opts = new rocksdb::TransactionOptions();
+ return reinterpret_cast<jlong>(opts);
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: isSetSnapshot
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_TransactionOptions_isSetSnapshot(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ return opts->set_snapshot;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: setSetSnapshot
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_TransactionOptions_setSetSnapshot(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean jset_snapshot) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ opts->set_snapshot = jset_snapshot;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: isDeadlockDetect
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_TransactionOptions_isDeadlockDetect(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ return opts->deadlock_detect;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: setDeadlockDetect
+ * Signature: (JZ)V
+ */
+void Java_org_rocksdb_TransactionOptions_setDeadlockDetect(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jboolean jdeadlock_detect) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ opts->deadlock_detect = jdeadlock_detect;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: getLockTimeout
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionOptions_getLockTimeout(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ return opts->lock_timeout;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: setLockTimeout
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionOptions_setLockTimeout(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong jlock_timeout) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ opts->lock_timeout = jlock_timeout;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: getExpiration
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionOptions_getExpiration(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ return opts->expiration;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: setExpiration
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionOptions_setExpiration(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle,
+ jlong jexpiration) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ opts->expiration = jexpiration;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: getDeadlockDetectDepth
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionOptions_getDeadlockDetectDepth(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ return opts->deadlock_detect_depth;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: setDeadlockDetectDepth
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionOptions_setDeadlockDetectDepth(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jdeadlock_detect_depth) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ opts->deadlock_detect_depth = jdeadlock_detect_depth;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: getMaxWriteBatchSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_TransactionOptions_getMaxWriteBatchSize(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ return opts->max_write_batch_size;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: setMaxWriteBatchSize
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_TransactionOptions_setMaxWriteBatchSize(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
+ jlong jmax_write_batch_size) {
+ auto* opts = reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+ opts->max_write_batch_size = jmax_write_batch_size;
+}
+
+/*
+ * Class: org_rocksdb_TransactionOptions
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TransactionOptions_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jhandle) {
+ delete reinterpret_cast<rocksdb::TransactionOptions*>(jhandle);
+}
diff --git a/src/rocksdb/java/rocksjni/ttl.cc b/src/rocksdb/java/rocksjni/ttl.cc
new file mode 100644
index 00000000..4b071e7b
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/ttl.cc
@@ -0,0 +1,207 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::TtlDB methods.
+// from Java side.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "include/org_rocksdb_TtlDB.h"
+#include "rocksdb/utilities/db_ttl.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_TtlDB
+ * Method: open
+ * Signature: (JLjava/lang/String;IZ)J
+ */
+jlong Java_org_rocksdb_TtlDB_open(
+ JNIEnv* env, jclass, jlong joptions_handle, jstring jdb_path, jint jttl,
+ jboolean jread_only) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ auto* opt = reinterpret_cast<rocksdb::Options*>(joptions_handle);
+ rocksdb::DBWithTTL* db = nullptr;
+ rocksdb::Status s =
+ rocksdb::DBWithTTL::Open(*opt, db_path, &db, jttl, jread_only);
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ // as TTLDB extends RocksDB on the java side, we can reuse
+ // the RocksDB portal here.
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(db);
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+ }
+}
+
+/*
+ * Class: org_rocksdb_TtlDB
+ * Method: openCF
+ * Signature: (JLjava/lang/String;[[B[J[IZ)[J
+ */
+jlongArray Java_org_rocksdb_TtlDB_openCF(
+ JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
+ jobjectArray jcolumn_names, jlongArray jcolumn_options,
+ jintArray jttls, jboolean jread_only) {
+ const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
+ if (db_path == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ const jsize len_cols = env->GetArrayLength(jcolumn_names);
+ jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr);
+ if (jco == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
+ jboolean has_exception = JNI_FALSE;
+ rocksdb::JniUtil::byteStrings<std::string>(
+ env, jcolumn_names,
+ [](const char* str_data, const size_t str_len) {
+ return std::string(str_data, str_len);
+ },
+ [&jco, &column_families](size_t idx, std::string cf_name) {
+ rocksdb::ColumnFamilyOptions* cf_options =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[idx]);
+ column_families.push_back(
+ rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options));
+ },
+ &has_exception);
+
+ env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
+
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+
+ std::vector<int32_t> ttl_values;
+ jint* jttlv = env->GetIntArrayElements(jttls, nullptr);
+ if (jttlv == nullptr) {
+ // exception thrown: OutOfMemoryError
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+ return nullptr;
+ }
+ const jsize len_ttls = env->GetArrayLength(jttls);
+ for (jsize i = 0; i < len_ttls; i++) {
+ ttl_values.push_back(jttlv[i]);
+ }
+ env->ReleaseIntArrayElements(jttls, jttlv, JNI_ABORT);
+
+ auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle);
+ std::vector<rocksdb::ColumnFamilyHandle*> handles;
+ rocksdb::DBWithTTL* db = nullptr;
+ rocksdb::Status s = rocksdb::DBWithTTL::Open(
+ *opt, db_path, column_families, &handles, &db, ttl_values, jread_only);
+
+ // we have now finished with db_path
+ env->ReleaseStringUTFChars(jdb_path, db_path);
+
+ // check if open operation was successful
+ if (s.ok()) {
+ const jsize resultsLen = 1 + len_cols; // db handle + column family handles
+ std::unique_ptr<jlong[]> results =
+ std::unique_ptr<jlong[]>(new jlong[resultsLen]);
+ results[0] = reinterpret_cast<jlong>(db);
+ for (int i = 1; i <= len_cols; i++) {
+ results[i] = reinterpret_cast<jlong>(handles[i - 1]);
+ }
+
+ jlongArray jresults = env->NewLongArray(resultsLen);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jresults);
+ return nullptr;
+ }
+
+ return jresults;
+ } else {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return NULL;
+ }
+}
+
+/*
+ * Class: org_rocksdb_TtlDB
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TtlDB_disposeInternal(
+ JNIEnv*, jobject, jlong jhandle) {
+ auto* ttl_db = reinterpret_cast<rocksdb::DBWithTTL*>(jhandle);
+ assert(ttl_db != nullptr);
+ delete ttl_db;
+}
+
+/*
+ * Class: org_rocksdb_TtlDB
+ * Method: closeDatabase
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_TtlDB_closeDatabase(
+ JNIEnv* /* env */, jclass, jlong /* jhandle */) {
+ //auto* ttl_db = reinterpret_cast<rocksdb::DBWithTTL*>(jhandle);
+ //assert(ttl_db != nullptr);
+ //rocksdb::Status s = ttl_db->Close();
+ //rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+
+ //TODO(AR) this is disabled until https://github.com/facebook/rocksdb/issues/4818 is resolved!
+}
+
+/*
+ * Class: org_rocksdb_TtlDB
+ * Method: createColumnFamilyWithTtl
+ * Signature: (JLorg/rocksdb/ColumnFamilyDescriptor;[BJI)J;
+ */
+jlong Java_org_rocksdb_TtlDB_createColumnFamilyWithTtl(
+ JNIEnv* env, jobject, jlong jdb_handle, jbyteArray jcolumn_name,
+ jlong jcolumn_options, jint jttl) {
+ jbyte* cfname = env->GetByteArrayElements(jcolumn_name, nullptr);
+ if (cfname == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ const jsize len = env->GetArrayLength(jcolumn_name);
+
+ auto* cfOptions =
+ reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcolumn_options);
+
+ auto* db_handle = reinterpret_cast<rocksdb::DBWithTTL*>(jdb_handle);
+ rocksdb::ColumnFamilyHandle* handle;
+ rocksdb::Status s = db_handle->CreateColumnFamilyWithTtl(
+ *cfOptions, std::string(reinterpret_cast<char*>(cfname), len), &handle,
+ jttl);
+
+ env->ReleaseByteArrayElements(jcolumn_name, cfname, 0);
+
+ if (s.ok()) {
+ return reinterpret_cast<jlong>(handle);
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+ return 0;
+}
diff --git a/src/rocksdb/java/rocksjni/wal_filter.cc b/src/rocksdb/java/rocksjni/wal_filter.cc
new file mode 100644
index 00000000..c74e5425
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/wal_filter.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ for
+// rocksdb::WalFilter.
+
+#include <jni.h>
+
+#include "include/org_rocksdb_AbstractWalFilter.h"
+#include "rocksjni/wal_filter_jnicallback.h"
+
+/*
+ * Class: org_rocksdb_AbstractWalFilter
+ * Method: createNewWalFilter
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_AbstractWalFilter_createNewWalFilter(
+ JNIEnv* env, jobject jobj) {
+ auto* wal_filter = new rocksdb::WalFilterJniCallback(env, jobj);
+ return reinterpret_cast<jlong>(wal_filter);
+} \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc b/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc
new file mode 100644
index 00000000..8fd90925
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc
@@ -0,0 +1,144 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::WalFilter.
+
+#include "rocksjni/wal_filter_jnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+WalFilterJniCallback::WalFilterJniCallback(
+ JNIEnv* env, jobject jwal_filter)
+ : JniCallback(env, jwal_filter) {
+ // Note: The name of a WalFilter will not change during it's lifetime,
+ // so we cache it in a global var
+ jmethodID jname_mid = AbstractWalFilterJni::getNameMethodId(env);
+ if(jname_mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+ jstring jname = (jstring)env->CallObjectMethod(m_jcallback_obj, jname_mid);
+ if(env->ExceptionCheck()) {
+ // exception thrown
+ return;
+ }
+ jboolean has_exception = JNI_FALSE;
+ m_name = JniUtil::copyString(env, jname,
+ &has_exception); // also releases jname
+ if (has_exception == JNI_TRUE) {
+ // exception thrown
+ return;
+ }
+
+ m_column_family_log_number_map_mid =
+ AbstractWalFilterJni::getColumnFamilyLogNumberMapMethodId(env);
+ if(m_column_family_log_number_map_mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ m_log_record_found_proxy_mid =
+ AbstractWalFilterJni::getLogRecordFoundProxyMethodId(env);
+ if(m_log_record_found_proxy_mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+}
+
+void WalFilterJniCallback::ColumnFamilyLogNumberMap(
+ const std::map<uint32_t, uint64_t>& cf_lognumber_map,
+ const std::map<std::string, uint32_t>& cf_name_id_map) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return;
+ }
+
+ jobject jcf_lognumber_map =
+ rocksdb::HashMapJni::fromCppMap(env, &cf_lognumber_map);
+ if (jcf_lognumber_map == nullptr) {
+ // exception occurred
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ jobject jcf_name_id_map =
+ rocksdb::HashMapJni::fromCppMap(env, &cf_name_id_map);
+ if (jcf_name_id_map == nullptr) {
+ // exception occurred
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jcf_lognumber_map);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ env->CallVoidMethod(m_jcallback_obj,
+ m_column_family_log_number_map_mid,
+ jcf_lognumber_map,
+ jcf_name_id_map);
+
+ env->DeleteLocalRef(jcf_lognumber_map);
+ env->DeleteLocalRef(jcf_name_id_map);
+
+ if(env->ExceptionCheck()) {
+ // exception thrown from CallVoidMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+
+ releaseJniEnv(attached_thread);
+}
+
+ WalFilter::WalProcessingOption WalFilterJniCallback::LogRecordFound(
+ unsigned long long log_number, const std::string& log_file_name,
+ const WriteBatch& batch, WriteBatch* new_batch, bool* batch_changed) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+
+ jstring jlog_file_name = JniUtil::toJavaString(env, &log_file_name);
+ if (jlog_file_name == nullptr) {
+ // exception occcurred
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+
+ jshort jlog_record_found_result = env->CallShortMethod(m_jcallback_obj,
+ m_log_record_found_proxy_mid,
+ static_cast<jlong>(log_number),
+ jlog_file_name,
+ reinterpret_cast<jlong>(&batch),
+ reinterpret_cast<jlong>(new_batch));
+
+ env->DeleteLocalRef(jlog_file_name);
+
+ if (env->ExceptionCheck()) {
+ // exception thrown from CallShortMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+
+ // unpack WalProcessingOption and batch_changed from jlog_record_found_result
+ jbyte jwal_processing_option_value = (jlog_record_found_result >> 8) & 0xFF;
+ jbyte jbatch_changed_value = jlog_record_found_result & 0xFF;
+
+ releaseJniEnv(attached_thread);
+
+ *batch_changed = jbatch_changed_value == JNI_TRUE;
+
+ return WalProcessingOptionJni::toCppWalProcessingOption(
+ jwal_processing_option_value);
+}
+
+const char* WalFilterJniCallback::Name() const {
+ return m_name.get();
+}
+
+} // namespace rocksdb \ No newline at end of file
diff --git a/src/rocksdb/java/rocksjni/wal_filter_jnicallback.h b/src/rocksdb/java/rocksjni/wal_filter_jnicallback.h
new file mode 100644
index 00000000..df6394ce
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/wal_filter_jnicallback.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::WalFilter.
+
+#ifndef JAVA_ROCKSJNI_WAL_FILTER_JNICALLBACK_H_
+#define JAVA_ROCKSJNI_WAL_FILTER_JNICALLBACK_H_
+
+#include <jni.h>
+#include <map>
+#include <memory>
+#include <string>
+
+#include "rocksdb/wal_filter.h"
+#include "rocksjni/jnicallback.h"
+
+namespace rocksdb {
+
+class WalFilterJniCallback : public JniCallback, public WalFilter {
+ public:
+ WalFilterJniCallback(
+ JNIEnv* env, jobject jwal_filter);
+ virtual void ColumnFamilyLogNumberMap(
+ const std::map<uint32_t, uint64_t>& cf_lognumber_map,
+ const std::map<std::string, uint32_t>& cf_name_id_map);
+ virtual WalFilter::WalProcessingOption LogRecordFound(
+ unsigned long long log_number, const std::string& log_file_name,
+ const WriteBatch& batch, WriteBatch* new_batch, bool* batch_changed);
+ virtual const char* Name() const;
+
+ private:
+ std::unique_ptr<const char[]> m_name;
+ jmethodID m_column_family_log_number_map_mid;
+ jmethodID m_log_record_found_proxy_mid;
+};
+
+} //namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_WAL_FILTER_JNICALLBACK_H_
diff --git a/src/rocksdb/java/rocksjni/write_batch.cc b/src/rocksdb/java/rocksjni/write_batch.cc
new file mode 100644
index 00000000..f1b77446
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/write_batch.cc
@@ -0,0 +1,604 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::WriteBatch methods from Java side.
+#include <memory>
+
+#include "db/memtable.h"
+#include "db/write_batch_internal.h"
+#include "include/org_rocksdb_WriteBatch.h"
+#include "include/org_rocksdb_WriteBatch_Handler.h"
+#include "rocksdb/db.h"
+#include "rocksdb/env.h"
+#include "rocksdb/memtablerep.h"
+#include "rocksdb/status.h"
+#include "rocksdb/write_batch.h"
+#include "rocksdb/write_buffer_manager.h"
+#include "rocksjni/portal.h"
+#include "rocksjni/writebatchhandlerjnicallback.h"
+#include "table/scoped_arena_iterator.h"
+#include "util/logging.h"
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: newWriteBatch
+ * Signature: (I)J
+ */
+jlong Java_org_rocksdb_WriteBatch_newWriteBatch__I(JNIEnv* /*env*/,
+ jclass /*jcls*/,
+ jint jreserved_bytes) {
+ auto* wb = new rocksdb::WriteBatch(static_cast<size_t>(jreserved_bytes));
+ return reinterpret_cast<jlong>(wb);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: newWriteBatch
+ * Signature: ([BI)J
+ */
+jlong Java_org_rocksdb_WriteBatch_newWriteBatch___3BI(JNIEnv* env,
+ jclass /*jcls*/,
+ jbyteArray jserialized,
+ jint jserialized_length) {
+ jboolean has_exception = JNI_FALSE;
+ std::string serialized = rocksdb::JniUtil::byteString<std::string>(
+ env, jserialized, jserialized_length,
+ [](const char* str, const size_t len) { return std::string(str, len); },
+ &has_exception);
+ if (has_exception == JNI_TRUE) {
+ // exception occurred
+ return 0;
+ }
+
+ auto* wb = new rocksdb::WriteBatch(serialized);
+ return reinterpret_cast<jlong>(wb);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: count0
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_WriteBatch_count0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return static_cast<jint>(wb->Count());
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: clear0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatch_clear0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ wb->Clear();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: setSavePoint0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatch_setSavePoint0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ wb->SetSavePoint();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: rollbackToSavePoint0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatch_rollbackToSavePoint0(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ auto s = wb->RollbackToSavePoint();
+
+ if (s.ok()) {
+ return;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: popSavePoint
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatch_popSavePoint(JNIEnv* env, jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ auto s = wb->PopSavePoint();
+
+ if (s.ok()) {
+ return;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: setMaxBytes
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_WriteBatch_setMaxBytes(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jwb_handle,
+ jlong jmax_bytes) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ wb->SetMaxBytes(static_cast<size_t>(jmax_bytes));
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: put
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_WriteBatch_put__J_3BI_3BI(JNIEnv* env, jobject jobj,
+ jlong jwb_handle,
+ jbyteArray jkey, jint jkey_len,
+ jbyteArray jentry_value,
+ jint jentry_value_len) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto put = [&wb](rocksdb::Slice key, rocksdb::Slice value) {
+ return wb->Put(key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ put, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: put
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatch_put__J_3BI_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwb_handle, jbyteArray jkey, jint jkey_len,
+ jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto put = [&wb, &cf_handle](rocksdb::Slice key, rocksdb::Slice value) {
+ return wb->Put(cf_handle, key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ put, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: merge
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_WriteBatch_merge__J_3BI_3BI(
+ JNIEnv* env, jobject jobj, jlong jwb_handle, jbyteArray jkey, jint jkey_len,
+ jbyteArray jentry_value, jint jentry_value_len) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto merge = [&wb](rocksdb::Slice key, rocksdb::Slice value) {
+ return wb->Merge(key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ merge, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: merge
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatch_merge__J_3BI_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwb_handle, jbyteArray jkey, jint jkey_len,
+ jbyteArray jentry_value, jint jentry_value_len, jlong jcf_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto merge = [&wb, &cf_handle](rocksdb::Slice key, rocksdb::Slice value) {
+ return wb->Merge(cf_handle, key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ merge, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: delete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WriteBatch_delete__J_3BI(JNIEnv* env, jobject jobj,
+ jlong jwb_handle,
+ jbyteArray jkey, jint jkey_len) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto remove = [&wb](rocksdb::Slice key) { return wb->Delete(key); };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(remove, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: delete
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatch_delete__J_3BIJ(JNIEnv* env, jobject jobj,
+ jlong jwb_handle,
+ jbyteArray jkey, jint jkey_len,
+ jlong jcf_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto remove = [&wb, &cf_handle](rocksdb::Slice key) {
+ return wb->Delete(cf_handle, key);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(remove, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: singleDelete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WriteBatch_singleDelete__J_3BI(JNIEnv* env, jobject jobj,
+ jlong jwb_handle,
+ jbyteArray jkey,
+ jint jkey_len) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto single_delete = [&wb](rocksdb::Slice key) {
+ return wb->SingleDelete(key);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(single_delete, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: singleDelete
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatch_singleDelete__J_3BIJ(JNIEnv* env, jobject jobj,
+ jlong jwb_handle,
+ jbyteArray jkey,
+ jint jkey_len,
+ jlong jcf_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto single_delete = [&wb, &cf_handle](rocksdb::Slice key) {
+ return wb->SingleDelete(cf_handle, key);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(single_delete, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: deleteRange
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_WriteBatch_deleteRange__J_3BI_3BI(
+ JNIEnv* env, jobject jobj, jlong jwb_handle, jbyteArray jbegin_key,
+ jint jbegin_key_len, jbyteArray jend_key, jint jend_key_len) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto deleteRange = [&wb](rocksdb::Slice beginKey, rocksdb::Slice endKey) {
+ return wb->DeleteRange(beginKey, endKey);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::kv_op(deleteRange, env, jobj, jbegin_key,
+ jbegin_key_len, jend_key, jend_key_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: deleteRange
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatch_deleteRange__J_3BI_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwb_handle, jbyteArray jbegin_key,
+ jint jbegin_key_len, jbyteArray jend_key, jint jend_key_len,
+ jlong jcf_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto deleteRange = [&wb, &cf_handle](rocksdb::Slice beginKey,
+ rocksdb::Slice endKey) {
+ return wb->DeleteRange(cf_handle, beginKey, endKey);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::kv_op(deleteRange, env, jobj, jbegin_key,
+ jbegin_key_len, jend_key, jend_key_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: putLogData
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WriteBatch_putLogData(JNIEnv* env, jobject jobj,
+ jlong jwb_handle, jbyteArray jblob,
+ jint jblob_len) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+ auto putLogData = [&wb](rocksdb::Slice blob) { return wb->PutLogData(blob); };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(putLogData, env, jobj, jblob, jblob_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: iterate
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_WriteBatch_iterate(JNIEnv* env, jobject /*jobj*/,
+ jlong jwb_handle,
+ jlong handlerHandle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ rocksdb::Status s = wb->Iterate(
+ reinterpret_cast<rocksdb::WriteBatchHandlerJniCallback*>(handlerHandle));
+
+ if (s.ok()) {
+ return;
+ }
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: data
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_WriteBatch_data(JNIEnv* env, jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ auto data = wb->Data();
+ return rocksdb::JniUtil::copyBytes(env, data);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: getDataSize
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_WriteBatch_getDataSize(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ auto data_size = wb->GetDataSize();
+ return static_cast<jlong>(data_size);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasPut
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteBatch_hasPut(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasPut();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasDelete
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WriteBatch_hasDelete(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasDelete();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasSingleDelete
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasSingleDelete(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasSingleDelete();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasDeleteRange
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasDeleteRange(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasDeleteRange();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasMerge
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasMerge(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasMerge();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasBeginPrepare
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasBeginPrepare(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasBeginPrepare();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasEndPrepare
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasEndPrepare(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasEndPrepare();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasCommit
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasCommit(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasCommit();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: hasRollback
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_rocksdb_WriteBatch_hasRollback(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return wb->HasRollback();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: markWalTerminationPoint
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatch_markWalTerminationPoint(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ wb->MarkWalTerminationPoint();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: getWalTerminationPoint
+ * Signature: (J)Lorg/rocksdb/WriteBatch/SavePoint;
+ */
+jobject Java_org_rocksdb_WriteBatch_getWalTerminationPoint(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ auto save_point = wb->GetWalTerminationPoint();
+ return rocksdb::WriteBatchSavePointJni::construct(env, save_point);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatch_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(handle);
+ assert(wb != nullptr);
+ delete wb;
+}
+
+/*
+ * Class: org_rocksdb_WriteBatch_Handler
+ * Method: createNewHandler0
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_WriteBatch_00024Handler_createNewHandler0(JNIEnv* env,
+ jobject jobj) {
+ auto* wbjnic = new rocksdb::WriteBatchHandlerJniCallback(env, jobj);
+ return reinterpret_cast<jlong>(wbjnic);
+}
diff --git a/src/rocksdb/java/rocksjni/write_batch_test.cc b/src/rocksdb/java/rocksjni/write_batch_test.cc
new file mode 100644
index 00000000..266fb4ab
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/write_batch_test.cc
@@ -0,0 +1,194 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::WriteBatch methods testing from Java side.
+#include <memory>
+
+#include "db/memtable.h"
+#include "db/write_batch_internal.h"
+#include "include/org_rocksdb_WriteBatch.h"
+#include "include/org_rocksdb_WriteBatchTest.h"
+#include "include/org_rocksdb_WriteBatchTestInternalHelper.h"
+#include "include/org_rocksdb_WriteBatch_Handler.h"
+#include "options/cf_options.h"
+#include "rocksdb/db.h"
+#include "rocksdb/env.h"
+#include "rocksdb/memtablerep.h"
+#include "rocksdb/status.h"
+#include "rocksdb/write_batch.h"
+#include "rocksdb/write_buffer_manager.h"
+#include "rocksjni/portal.h"
+#include "table/scoped_arena_iterator.h"
+#include "util/string_util.h"
+#include "util/testharness.h"
+
+/*
+ * Class: org_rocksdb_WriteBatchTest
+ * Method: getContents
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_WriteBatchTest_getContents(JNIEnv* env,
+ jclass /*jclazz*/,
+ jlong jwb_handle) {
+ auto* b = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(b != nullptr);
+
+ // todo: Currently the following code is directly copied from
+ // db/write_bench_test.cc. It could be implemented in java once
+ // all the necessary components can be accessed via jni api.
+
+ rocksdb::InternalKeyComparator cmp(rocksdb::BytewiseComparator());
+ auto factory = std::make_shared<rocksdb::SkipListFactory>();
+ rocksdb::Options options;
+ rocksdb::WriteBufferManager wb(options.db_write_buffer_size);
+ options.memtable_factory = factory;
+ rocksdb::MemTable* mem = new rocksdb::MemTable(
+ cmp, rocksdb::ImmutableCFOptions(options),
+ rocksdb::MutableCFOptions(options), &wb, rocksdb::kMaxSequenceNumber,
+ 0 /* column_family_id */);
+ mem->Ref();
+ std::string state;
+ rocksdb::ColumnFamilyMemTablesDefault cf_mems_default(mem);
+ rocksdb::Status s =
+ rocksdb::WriteBatchInternal::InsertInto(b, &cf_mems_default, nullptr);
+ int count = 0;
+ rocksdb::Arena arena;
+ rocksdb::ScopedArenaIterator iter(
+ mem->NewIterator(rocksdb::ReadOptions(), &arena));
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
+ rocksdb::ParsedInternalKey ikey;
+ ikey.clear();
+ bool parsed = rocksdb::ParseInternalKey(iter->key(), &ikey);
+ if (!parsed) {
+ assert(parsed);
+ }
+ switch (ikey.type) {
+ case rocksdb::kTypeValue:
+ state.append("Put(");
+ state.append(ikey.user_key.ToString());
+ state.append(", ");
+ state.append(iter->value().ToString());
+ state.append(")");
+ count++;
+ break;
+ case rocksdb::kTypeMerge:
+ state.append("Merge(");
+ state.append(ikey.user_key.ToString());
+ state.append(", ");
+ state.append(iter->value().ToString());
+ state.append(")");
+ count++;
+ break;
+ case rocksdb::kTypeDeletion:
+ state.append("Delete(");
+ state.append(ikey.user_key.ToString());
+ state.append(")");
+ count++;
+ break;
+ case rocksdb::kTypeSingleDeletion:
+ state.append("SingleDelete(");
+ state.append(ikey.user_key.ToString());
+ state.append(")");
+ count++;
+ break;
+ case rocksdb::kTypeRangeDeletion:
+ state.append("DeleteRange(");
+ state.append(ikey.user_key.ToString());
+ state.append(", ");
+ state.append(iter->value().ToString());
+ state.append(")");
+ count++;
+ break;
+ case rocksdb::kTypeLogData:
+ state.append("LogData(");
+ state.append(ikey.user_key.ToString());
+ state.append(")");
+ count++;
+ break;
+ default:
+ assert(false);
+ state.append("Err:Expected(");
+ state.append(std::to_string(ikey.type));
+ state.append(")");
+ count++;
+ break;
+ }
+ state.append("@");
+ state.append(rocksdb::NumberToString(ikey.sequence));
+ }
+ if (!s.ok()) {
+ state.append(s.ToString());
+ } else if (rocksdb::WriteBatchInternal::Count(b) != count) {
+ state.append("Err:CountMismatch(expected=");
+ state.append(std::to_string(rocksdb::WriteBatchInternal::Count(b)));
+ state.append(", actual=");
+ state.append(std::to_string(count));
+ state.append(")");
+ }
+ delete mem->Unref();
+
+ jbyteArray jstate = env->NewByteArray(static_cast<jsize>(state.size()));
+ if (jstate == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(
+ jstate, 0, static_cast<jsize>(state.size()),
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(state.c_str())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jstate);
+ return nullptr;
+ }
+
+ return jstate;
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchTestInternalHelper
+ * Method: setSequence
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence(
+ JNIEnv* /*env*/, jclass /*jclazz*/, jlong jwb_handle, jlong jsn) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ rocksdb::WriteBatchInternal::SetSequence(
+ wb, static_cast<rocksdb::SequenceNumber>(jsn));
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchTestInternalHelper
+ * Method: sequence
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_WriteBatchTestInternalHelper_sequence(JNIEnv* /*env*/,
+ jclass /*jclazz*/,
+ jlong jwb_handle) {
+ auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle);
+ assert(wb != nullptr);
+
+ return static_cast<jlong>(rocksdb::WriteBatchInternal::Sequence(wb));
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchTestInternalHelper
+ * Method: append
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_WriteBatchTestInternalHelper_append(JNIEnv* /*env*/,
+ jclass /*jclazz*/,
+ jlong jwb_handle_1,
+ jlong jwb_handle_2) {
+ auto* wb1 = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle_1);
+ assert(wb1 != nullptr);
+ auto* wb2 = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle_2);
+ assert(wb2 != nullptr);
+
+ rocksdb::WriteBatchInternal::Append(wb1, wb2);
+}
diff --git a/src/rocksdb/java/rocksjni/write_batch_with_index.cc b/src/rocksdb/java/rocksjni/write_batch_with_index.cc
new file mode 100644
index 00000000..12ca299a
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/write_batch_with_index.cc
@@ -0,0 +1,746 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the "bridge" between Java and C++ and enables
+// calling c++ rocksdb::WriteBatchWithIndex methods from Java side.
+
+#include "rocksdb/utilities/write_batch_with_index.h"
+#include "include/org_rocksdb_WBWIRocksIterator.h"
+#include "include/org_rocksdb_WriteBatchWithIndex.h"
+#include "rocksdb/comparator.h"
+#include "rocksjni/portal.h"
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: newWriteBatchWithIndex
+ * Signature: ()J
+ */
+jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__(
+ JNIEnv* /*env*/, jclass /*jcls*/) {
+ auto* wbwi = new rocksdb::WriteBatchWithIndex();
+ return reinterpret_cast<jlong>(wbwi);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: newWriteBatchWithIndex
+ * Signature: (Z)J
+ */
+jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__Z(
+ JNIEnv* /*env*/, jclass /*jcls*/, jboolean joverwrite_key) {
+ auto* wbwi = new rocksdb::WriteBatchWithIndex(
+ rocksdb::BytewiseComparator(), 0, static_cast<bool>(joverwrite_key));
+ return reinterpret_cast<jlong>(wbwi);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: newWriteBatchWithIndex
+ * Signature: (JBIZ)J
+ */
+jlong Java_org_rocksdb_WriteBatchWithIndex_newWriteBatchWithIndex__JBIZ(
+ JNIEnv* /*env*/, jclass /*jcls*/, jlong jfallback_index_comparator_handle,
+ jbyte jcomparator_type, jint jreserved_bytes, jboolean joverwrite_key) {
+ rocksdb::Comparator* fallback_comparator = nullptr;
+ switch (jcomparator_type) {
+ // JAVA_COMPARATOR
+ case 0x0:
+ fallback_comparator = reinterpret_cast<rocksdb::ComparatorJniCallback*>(
+ jfallback_index_comparator_handle);
+ break;
+
+ // JAVA_DIRECT_COMPARATOR
+ case 0x1:
+ fallback_comparator =
+ reinterpret_cast<rocksdb::DirectComparatorJniCallback*>(
+ jfallback_index_comparator_handle);
+ break;
+
+ // JAVA_NATIVE_COMPARATOR_WRAPPER
+ case 0x2:
+ fallback_comparator = reinterpret_cast<rocksdb::Comparator*>(
+ jfallback_index_comparator_handle);
+ break;
+ }
+ auto* wbwi = new rocksdb::WriteBatchWithIndex(
+ fallback_comparator, static_cast<size_t>(jreserved_bytes),
+ static_cast<bool>(joverwrite_key));
+ return reinterpret_cast<jlong>(wbwi);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: count0
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_WriteBatchWithIndex_count0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ return static_cast<jint>(wbwi->GetWriteBatch()->Count());
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: put
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_put__J_3BI_3BI(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len, jbyteArray jentry_value, jint jentry_value_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto put = [&wbwi](rocksdb::Slice key, rocksdb::Slice value) {
+ return wbwi->Put(key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ put, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: put
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_put__J_3BI_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len, jbyteArray jentry_value, jint jentry_value_len,
+ jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto put = [&wbwi, &cf_handle](rocksdb::Slice key, rocksdb::Slice value) {
+ return wbwi->Put(cf_handle, key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ put, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: merge
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_merge__J_3BI_3BI(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len, jbyteArray jentry_value, jint jentry_value_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto merge = [&wbwi](rocksdb::Slice key, rocksdb::Slice value) {
+ return wbwi->Merge(key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ merge, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: merge
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_merge__J_3BI_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len, jbyteArray jentry_value, jint jentry_value_len,
+ jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto merge = [&wbwi, &cf_handle](rocksdb::Slice key, rocksdb::Slice value) {
+ return wbwi->Merge(cf_handle, key, value);
+ };
+ std::unique_ptr<rocksdb::Status> status = rocksdb::JniUtil::kv_op(
+ merge, env, jobj, jkey, jkey_len, jentry_value, jentry_value_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: delete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_delete__J_3BI(JNIEnv* env,
+ jobject jobj,
+ jlong jwbwi_handle,
+ jbyteArray jkey,
+ jint jkey_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto remove = [&wbwi](rocksdb::Slice key) { return wbwi->Delete(key); };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(remove, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: delete
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_delete__J_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len, jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto remove = [&wbwi, &cf_handle](rocksdb::Slice key) {
+ return wbwi->Delete(cf_handle, key);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(remove, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: singleDelete
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_singleDelete__J_3BI(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto single_delete = [&wbwi](rocksdb::Slice key) {
+ return wbwi->SingleDelete(key);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(single_delete, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: singleDelete
+ * Signature: (J[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_singleDelete__J_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jkey,
+ jint jkey_len, jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto single_delete = [&wbwi, &cf_handle](rocksdb::Slice key) {
+ return wbwi->SingleDelete(cf_handle, key);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(single_delete, env, jobj, jkey, jkey_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: deleteRange
+ * Signature: (J[BI[BI)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_deleteRange__J_3BI_3BI(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jbegin_key,
+ jint jbegin_key_len, jbyteArray jend_key, jint jend_key_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto deleteRange = [&wbwi](rocksdb::Slice beginKey, rocksdb::Slice endKey) {
+ return wbwi->DeleteRange(beginKey, endKey);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::kv_op(deleteRange, env, jobj, jbegin_key,
+ jbegin_key_len, jend_key, jend_key_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: deleteRange
+ * Signature: (J[BI[BIJ)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_deleteRange__J_3BI_3BIJ(
+ JNIEnv* env, jobject jobj, jlong jwbwi_handle, jbyteArray jbegin_key,
+ jint jbegin_key_len, jbyteArray jend_key, jint jend_key_len,
+ jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ assert(cf_handle != nullptr);
+ auto deleteRange = [&wbwi, &cf_handle](rocksdb::Slice beginKey,
+ rocksdb::Slice endKey) {
+ return wbwi->DeleteRange(cf_handle, beginKey, endKey);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::kv_op(deleteRange, env, jobj, jbegin_key,
+ jbegin_key_len, jend_key, jend_key_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: putLogData
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_putLogData(JNIEnv* env, jobject jobj,
+ jlong jwbwi_handle,
+ jbyteArray jblob,
+ jint jblob_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+ auto putLogData = [&wbwi](rocksdb::Slice blob) {
+ return wbwi->PutLogData(blob);
+ };
+ std::unique_ptr<rocksdb::Status> status =
+ rocksdb::JniUtil::k_op(putLogData, env, jobj, jblob, jblob_len);
+ if (status != nullptr && !status->ok()) {
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, status);
+ }
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: clear
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_clear0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ wbwi->Clear();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: setSavePoint0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_setSavePoint0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ wbwi->SetSavePoint();
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: rollbackToSavePoint0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_rollbackToSavePoint0(
+ JNIEnv* env, jobject /*jobj*/, jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ auto s = wbwi->RollbackToSavePoint();
+
+ if (s.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: popSavePoint
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_popSavePoint(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ auto s = wbwi->PopSavePoint();
+
+ if (s.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: setMaxBytes
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_setMaxBytes(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle,
+ jlong jmax_bytes) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ wbwi->SetMaxBytes(static_cast<size_t>(jmax_bytes));
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: getWriteBatch
+ * Signature: (J)Lorg/rocksdb/WriteBatch;
+ */
+jobject Java_org_rocksdb_WriteBatchWithIndex_getWriteBatch(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ assert(wbwi != nullptr);
+
+ auto* wb = wbwi->GetWriteBatch();
+
+ // TODO(AR) is the `wb` object owned by us?
+ return rocksdb::WriteBatchJni::construct(env, wb);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: iterator0
+ * Signature: (J)J
+ */
+jlong Java_org_rocksdb_WriteBatchWithIndex_iterator0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* wbwi_iterator = wbwi->NewIterator();
+ return reinterpret_cast<jlong>(wbwi_iterator);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: iterator1
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_WriteBatchWithIndex_iterator1(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle,
+ jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ auto* wbwi_iterator = wbwi->NewIterator(cf_handle);
+ return reinterpret_cast<jlong>(wbwi_iterator);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: iteratorWithBase
+ * Signature: (JJJ)J
+ */
+jlong Java_org_rocksdb_WriteBatchWithIndex_iteratorWithBase(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong jwbwi_handle,
+ jlong jcf_handle,
+ jlong jbi_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+ auto* base_iterator = reinterpret_cast<rocksdb::Iterator*>(jbi_handle);
+ auto* iterator = wbwi->NewIteratorWithBase(cf_handle, base_iterator);
+ return reinterpret_cast<jlong>(iterator);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: getFromBatch
+ * Signature: (JJ[BI)[B
+ */
+jbyteArray JNICALL Java_org_rocksdb_WriteBatchWithIndex_getFromBatch__JJ_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jwbwi_handle, jlong jdbopt_handle,
+ jbyteArray jkey, jint jkey_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* dbopt = reinterpret_cast<rocksdb::DBOptions*>(jdbopt_handle);
+
+ auto getter = [&wbwi, &dbopt](const rocksdb::Slice& key, std::string* value) {
+ return wbwi->GetFromBatch(*dbopt, key, value);
+ };
+
+ return rocksdb::JniUtil::v_op(getter, env, jkey, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: getFromBatch
+ * Signature: (JJ[BIJ)[B
+ */
+jbyteArray Java_org_rocksdb_WriteBatchWithIndex_getFromBatch__JJ_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jwbwi_handle, jlong jdbopt_handle,
+ jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* dbopt = reinterpret_cast<rocksdb::DBOptions*>(jdbopt_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+
+ auto getter = [&wbwi, &cf_handle, &dbopt](const rocksdb::Slice& key,
+ std::string* value) {
+ return wbwi->GetFromBatch(cf_handle, *dbopt, key, value);
+ };
+
+ return rocksdb::JniUtil::v_op(getter, env, jkey, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: getFromBatchAndDB
+ * Signature: (JJJ[BI)[B
+ */
+jbyteArray Java_org_rocksdb_WriteBatchWithIndex_getFromBatchAndDB__JJJ_3BI(
+ JNIEnv* env, jobject /*jobj*/, jlong jwbwi_handle, jlong jdb_handle,
+ jlong jreadopt_handle, jbyteArray jkey, jint jkey_len) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* readopt = reinterpret_cast<rocksdb::ReadOptions*>(jreadopt_handle);
+
+ auto getter = [&wbwi, &db, &readopt](const rocksdb::Slice& key,
+ std::string* value) {
+ return wbwi->GetFromBatchAndDB(db, *readopt, key, value);
+ };
+
+ return rocksdb::JniUtil::v_op(getter, env, jkey, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: getFromBatchAndDB
+ * Signature: (JJJ[BIJ)[B
+ */
+jbyteArray Java_org_rocksdb_WriteBatchWithIndex_getFromBatchAndDB__JJJ_3BIJ(
+ JNIEnv* env, jobject /*jobj*/, jlong jwbwi_handle, jlong jdb_handle,
+ jlong jreadopt_handle, jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle);
+ auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
+ auto* readopt = reinterpret_cast<rocksdb::ReadOptions*>(jreadopt_handle);
+ auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle);
+
+ auto getter = [&wbwi, &db, &cf_handle, &readopt](const rocksdb::Slice& key,
+ std::string* value) {
+ return wbwi->GetFromBatchAndDB(db, *readopt, cf_handle, key, value);
+ };
+
+ return rocksdb::JniUtil::v_op(getter, env, jkey, jkey_len);
+}
+
+/*
+ * Class: org_rocksdb_WriteBatchWithIndex
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBatchWithIndex_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(handle);
+ assert(wbwi != nullptr);
+ delete wbwi;
+}
+
+/* WBWIRocksIterator below */
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
+ assert(it != nullptr);
+ delete it;
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: isValid0
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_WBWIRocksIterator_isValid0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ return reinterpret_cast<rocksdb::WBWIIterator*>(handle)->Valid();
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: seekToFirst0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_seekToFirst0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::WBWIIterator*>(handle)->SeekToFirst();
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: seekToLast0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_seekToLast0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::WBWIIterator*>(handle)->SeekToLast();
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: next0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_next0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::WBWIIterator*>(handle)->Next();
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: prev0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_prev0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle) {
+ reinterpret_cast<rocksdb::WBWIIterator*>(handle)->Prev();
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: seek0
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_seek0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle, jbyteArray jtarget,
+ jint jtarget_len) {
+ auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
+ jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
+ if (target == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice target_slice(reinterpret_cast<char*>(target), jtarget_len);
+
+ it->Seek(target_slice);
+
+ env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: seekForPrev0
+ * Signature: (J[BI)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_seekForPrev0(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong handle,
+ jbyteArray jtarget,
+ jint jtarget_len) {
+ auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
+ jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
+ if (target == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return;
+ }
+
+ rocksdb::Slice target_slice(reinterpret_cast<char*>(target), jtarget_len);
+
+ it->SeekForPrev(target_slice);
+
+ env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: status0
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WBWIRocksIterator_status0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
+ rocksdb::Status s = it->status();
+
+ if (s.ok()) {
+ return;
+ }
+
+ rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
+}
+
+/*
+ * Class: org_rocksdb_WBWIRocksIterator
+ * Method: entry1
+ * Signature: (J)[J
+ */
+jlongArray Java_org_rocksdb_WBWIRocksIterator_entry1(JNIEnv* env,
+ jobject /*jobj*/,
+ jlong handle) {
+ auto* it = reinterpret_cast<rocksdb::WBWIIterator*>(handle);
+ const rocksdb::WriteEntry& we = it->Entry();
+
+ jlong results[3];
+
+ // set the type of the write entry
+ results[0] = rocksdb::WriteTypeJni::toJavaWriteType(we.type);
+
+ // NOTE: key_slice and value_slice will be freed by
+ // org.rocksdb.DirectSlice#close
+
+ auto* key_slice = new rocksdb::Slice(we.key.data(), we.key.size());
+ results[1] = reinterpret_cast<jlong>(key_slice);
+ if (we.type == rocksdb::kDeleteRecord ||
+ we.type == rocksdb::kSingleDeleteRecord ||
+ we.type == rocksdb::kLogDataRecord) {
+ // set native handle of value slice to null if no value available
+ results[2] = 0;
+ } else {
+ auto* value_slice = new rocksdb::Slice(we.value.data(), we.value.size());
+ results[2] = reinterpret_cast<jlong>(value_slice);
+ }
+
+ jlongArray jresults = env->NewLongArray(3);
+ if (jresults == nullptr) {
+ // exception thrown: OutOfMemoryError
+ if (results[2] != 0) {
+ auto* value_slice = reinterpret_cast<rocksdb::Slice*>(results[2]);
+ delete value_slice;
+ }
+ delete key_slice;
+ return nullptr;
+ }
+
+ env->SetLongArrayRegion(jresults, 0, 3, results);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(jresults);
+ if (results[2] != 0) {
+ auto* value_slice = reinterpret_cast<rocksdb::Slice*>(results[2]);
+ delete value_slice;
+ }
+ delete key_slice;
+ return nullptr;
+ }
+
+ return jresults;
+}
diff --git a/src/rocksdb/java/rocksjni/write_buffer_manager.cc b/src/rocksdb/java/rocksjni/write_buffer_manager.cc
new file mode 100644
index 00000000..043f6903
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/write_buffer_manager.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include <jni.h>
+
+#include "include/org_rocksdb_WriteBufferManager.h"
+
+#include "rocksdb/cache.h"
+#include "rocksdb/write_buffer_manager.h"
+
+/*
+ * Class: org_rocksdb_WriteBufferManager
+ * Method: newWriteBufferManager
+ * Signature: (JJ)J
+ */
+jlong Java_org_rocksdb_WriteBufferManager_newWriteBufferManager(
+ JNIEnv* /*env*/, jclass /*jclazz*/, jlong jbuffer_size, jlong jcache_handle) {
+ auto* cache_ptr =
+ reinterpret_cast<std::shared_ptr<rocksdb::Cache> *>(jcache_handle);
+ auto* write_buffer_manager = new std::shared_ptr<rocksdb::WriteBufferManager>(
+ std::make_shared<rocksdb::WriteBufferManager>(jbuffer_size, *cache_ptr));
+ return reinterpret_cast<jlong>(write_buffer_manager);
+}
+
+/*
+ * Class: org_rocksdb_WriteBufferManager
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_WriteBufferManager_disposeInternal(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
+ auto* write_buffer_manager =
+ reinterpret_cast<std::shared_ptr<rocksdb::WriteBufferManager> *>(jhandle);
+ assert(write_buffer_manager != nullptr);
+ delete write_buffer_manager;
+}
diff --git a/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.cc b/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.cc
new file mode 100644
index 00000000..bf900111
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.cc
@@ -0,0 +1,514 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::Comparator.
+
+#include "rocksjni/writebatchhandlerjnicallback.h"
+#include "rocksjni/portal.h"
+
+namespace rocksdb {
+WriteBatchHandlerJniCallback::WriteBatchHandlerJniCallback(
+ JNIEnv* env, jobject jWriteBatchHandler)
+ : JniCallback(env, jWriteBatchHandler), m_env(env) {
+
+ m_jPutCfMethodId = WriteBatchHandlerJni::getPutCfMethodId(env);
+ if(m_jPutCfMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jPutMethodId = WriteBatchHandlerJni::getPutMethodId(env);
+ if(m_jPutMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMergeCfMethodId = WriteBatchHandlerJni::getMergeCfMethodId(env);
+ if(m_jMergeCfMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMergeMethodId = WriteBatchHandlerJni::getMergeMethodId(env);
+ if(m_jMergeMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jDeleteCfMethodId = WriteBatchHandlerJni::getDeleteCfMethodId(env);
+ if(m_jDeleteCfMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jDeleteMethodId = WriteBatchHandlerJni::getDeleteMethodId(env);
+ if(m_jDeleteMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jSingleDeleteCfMethodId =
+ WriteBatchHandlerJni::getSingleDeleteCfMethodId(env);
+ if(m_jSingleDeleteCfMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jSingleDeleteMethodId = WriteBatchHandlerJni::getSingleDeleteMethodId(env);
+ if(m_jSingleDeleteMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jDeleteRangeCfMethodId =
+ WriteBatchHandlerJni::getDeleteRangeCfMethodId(env);
+ if (m_jDeleteRangeCfMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jDeleteRangeMethodId = WriteBatchHandlerJni::getDeleteRangeMethodId(env);
+ if (m_jDeleteRangeMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jLogDataMethodId = WriteBatchHandlerJni::getLogDataMethodId(env);
+ if(m_jLogDataMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jPutBlobIndexCfMethodId =
+ WriteBatchHandlerJni::getPutBlobIndexCfMethodId(env);
+ if(m_jPutBlobIndexCfMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMarkBeginPrepareMethodId =
+ WriteBatchHandlerJni::getMarkBeginPrepareMethodId(env);
+ if(m_jMarkBeginPrepareMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMarkEndPrepareMethodId =
+ WriteBatchHandlerJni::getMarkEndPrepareMethodId(env);
+ if(m_jMarkEndPrepareMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMarkNoopMethodId = WriteBatchHandlerJni::getMarkNoopMethodId(env);
+ if(m_jMarkNoopMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMarkRollbackMethodId = WriteBatchHandlerJni::getMarkRollbackMethodId(env);
+ if(m_jMarkRollbackMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jMarkCommitMethodId = WriteBatchHandlerJni::getMarkCommitMethodId(env);
+ if(m_jMarkCommitMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+
+ m_jContinueMethodId = WriteBatchHandlerJni::getContinueMethodId(env);
+ if(m_jContinueMethodId == nullptr) {
+ // exception thrown
+ return;
+ }
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::PutCF(uint32_t column_family_id,
+ const Slice& key, const Slice& value) {
+ auto put = [this, column_family_id] (
+ jbyteArray j_key, jbyteArray j_value) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jPutCfMethodId,
+ static_cast<jint>(column_family_id),
+ j_key,
+ j_value);
+ };
+ auto status = WriteBatchHandlerJniCallback::kv_op(key, value, put);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+void WriteBatchHandlerJniCallback::Put(const Slice& key, const Slice& value) {
+ auto put = [this] (
+ jbyteArray j_key, jbyteArray j_value) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jPutMethodId,
+ j_key,
+ j_value);
+ };
+ WriteBatchHandlerJniCallback::kv_op(key, value, put);
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::MergeCF(uint32_t column_family_id,
+ const Slice& key, const Slice& value) {
+ auto merge = [this, column_family_id] (
+ jbyteArray j_key, jbyteArray j_value) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jMergeCfMethodId,
+ static_cast<jint>(column_family_id),
+ j_key,
+ j_value);
+ };
+ auto status = WriteBatchHandlerJniCallback::kv_op(key, value, merge);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+void WriteBatchHandlerJniCallback::Merge(const Slice& key, const Slice& value) {
+ auto merge = [this] (
+ jbyteArray j_key, jbyteArray j_value) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jMergeMethodId,
+ j_key,
+ j_value);
+ };
+ WriteBatchHandlerJniCallback::kv_op(key, value, merge);
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::DeleteCF(uint32_t column_family_id,
+ const Slice& key) {
+ auto remove = [this, column_family_id] (jbyteArray j_key) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jDeleteCfMethodId,
+ static_cast<jint>(column_family_id),
+ j_key);
+ };
+ auto status = WriteBatchHandlerJniCallback::k_op(key, remove);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+void WriteBatchHandlerJniCallback::Delete(const Slice& key) {
+ auto remove = [this] (jbyteArray j_key) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jDeleteMethodId,
+ j_key);
+ };
+ WriteBatchHandlerJniCallback::k_op(key, remove);
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::SingleDeleteCF(uint32_t column_family_id,
+ const Slice& key) {
+ auto singleDelete = [this, column_family_id] (jbyteArray j_key) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jSingleDeleteCfMethodId,
+ static_cast<jint>(column_family_id),
+ j_key);
+ };
+ auto status = WriteBatchHandlerJniCallback::k_op(key, singleDelete);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+void WriteBatchHandlerJniCallback::SingleDelete(const Slice& key) {
+ auto singleDelete = [this] (jbyteArray j_key) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jSingleDeleteMethodId,
+ j_key);
+ };
+ WriteBatchHandlerJniCallback::k_op(key, singleDelete);
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::DeleteRangeCF(uint32_t column_family_id,
+ const Slice& beginKey, const Slice& endKey) {
+ auto deleteRange = [this, column_family_id] (
+ jbyteArray j_beginKey, jbyteArray j_endKey) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jDeleteRangeCfMethodId,
+ static_cast<jint>(column_family_id),
+ j_beginKey,
+ j_endKey);
+ };
+ auto status = WriteBatchHandlerJniCallback::kv_op(beginKey, endKey, deleteRange);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+void WriteBatchHandlerJniCallback::DeleteRange(const Slice& beginKey,
+ const Slice& endKey) {
+ auto deleteRange = [this] (
+ jbyteArray j_beginKey, jbyteArray j_endKey) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jDeleteRangeMethodId,
+ j_beginKey,
+ j_endKey);
+ };
+ WriteBatchHandlerJniCallback::kv_op(beginKey, endKey, deleteRange);
+}
+
+void WriteBatchHandlerJniCallback::LogData(const Slice& blob) {
+ auto logData = [this] (jbyteArray j_blob) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jLogDataMethodId,
+ j_blob);
+ };
+ WriteBatchHandlerJniCallback::k_op(blob, logData);
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::PutBlobIndexCF(uint32_t column_family_id,
+ const Slice& key, const Slice& value) {
+ auto putBlobIndex = [this, column_family_id] (
+ jbyteArray j_key, jbyteArray j_value) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jPutBlobIndexCfMethodId,
+ static_cast<jint>(column_family_id),
+ j_key,
+ j_value);
+ };
+ auto status = WriteBatchHandlerJniCallback::kv_op(key, value, putBlobIndex);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::MarkBeginPrepare(bool unprepare) {
+#ifndef DEBUG
+ (void) unprepare;
+#else
+ assert(!unprepare);
+#endif
+ m_env->CallVoidMethod(m_jcallback_obj, m_jMarkBeginPrepareMethodId);
+
+ // check for Exception, in-particular RocksDBException
+ if (m_env->ExceptionCheck()) {
+ // exception thrown
+ jthrowable exception = m_env->ExceptionOccurred();
+ std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
+ if (status == nullptr) {
+ // unkown status or exception occurred extracting status
+ m_env->ExceptionDescribe();
+ return rocksdb::Status::OK(); // TODO(AR) probably need a better error code here
+
+ } else {
+ m_env->ExceptionClear(); // clear the exception, as we have extracted the status
+ return rocksdb::Status(*status);
+ }
+ }
+
+ return rocksdb::Status::OK();
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::MarkEndPrepare(const Slice& xid) {
+ auto markEndPrepare = [this] (
+ jbyteArray j_xid) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jMarkEndPrepareMethodId,
+ j_xid);
+ };
+ auto status = WriteBatchHandlerJniCallback::k_op(xid, markEndPrepare);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::MarkNoop(bool empty_batch) {
+ m_env->CallVoidMethod(m_jcallback_obj, m_jMarkNoopMethodId, static_cast<jboolean>(empty_batch));
+
+ // check for Exception, in-particular RocksDBException
+ if (m_env->ExceptionCheck()) {
+ // exception thrown
+ jthrowable exception = m_env->ExceptionOccurred();
+ std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
+ if (status == nullptr) {
+ // unkown status or exception occurred extracting status
+ m_env->ExceptionDescribe();
+ return rocksdb::Status::OK(); // TODO(AR) probably need a better error code here
+
+ } else {
+ m_env->ExceptionClear(); // clear the exception, as we have extracted the status
+ return rocksdb::Status(*status);
+ }
+ }
+
+ return rocksdb::Status::OK();
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::MarkRollback(const Slice& xid) {
+ auto markRollback = [this] (
+ jbyteArray j_xid) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jMarkRollbackMethodId,
+ j_xid);
+ };
+ auto status = WriteBatchHandlerJniCallback::k_op(xid, markRollback);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+rocksdb::Status WriteBatchHandlerJniCallback::MarkCommit(const Slice& xid) {
+ auto markCommit = [this] (
+ jbyteArray j_xid) {
+ m_env->CallVoidMethod(
+ m_jcallback_obj,
+ m_jMarkCommitMethodId,
+ j_xid);
+ };
+ auto status = WriteBatchHandlerJniCallback::k_op(xid, markCommit);
+ if(status == nullptr) {
+ return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
+ } else {
+ return rocksdb::Status(*status);
+ }
+}
+
+bool WriteBatchHandlerJniCallback::Continue() {
+ jboolean jContinue = m_env->CallBooleanMethod(
+ m_jcallback_obj,
+ m_jContinueMethodId);
+ if(m_env->ExceptionCheck()) {
+ // exception thrown
+ m_env->ExceptionDescribe();
+ }
+
+ return static_cast<bool>(jContinue == JNI_TRUE);
+}
+
+std::unique_ptr<rocksdb::Status> WriteBatchHandlerJniCallback::kv_op(const Slice& key, const Slice& value, std::function<void(jbyteArray, jbyteArray)> kvFn) {
+ const jbyteArray j_key = JniUtil::copyBytes(m_env, key);
+ if (j_key == nullptr) {
+ // exception thrown
+ if (m_env->ExceptionCheck()) {
+ m_env->ExceptionDescribe();
+ }
+ return nullptr;
+ }
+
+ const jbyteArray j_value = JniUtil::copyBytes(m_env, value);
+ if (j_value == nullptr) {
+ // exception thrown
+ if (m_env->ExceptionCheck()) {
+ m_env->ExceptionDescribe();
+ }
+ if (j_key != nullptr) {
+ m_env->DeleteLocalRef(j_key);
+ }
+ return nullptr;
+ }
+
+ kvFn(j_key, j_value);
+
+ // check for Exception, in-particular RocksDBException
+ if (m_env->ExceptionCheck()) {
+ if (j_value != nullptr) {
+ m_env->DeleteLocalRef(j_value);
+ }
+ if (j_key != nullptr) {
+ m_env->DeleteLocalRef(j_key);
+ }
+
+ // exception thrown
+ jthrowable exception = m_env->ExceptionOccurred();
+ std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
+ if (status == nullptr) {
+ // unkown status or exception occurred extracting status
+ m_env->ExceptionDescribe();
+ return nullptr;
+
+ } else {
+ m_env->ExceptionClear(); // clear the exception, as we have extracted the status
+ return status;
+ }
+ }
+
+ if (j_value != nullptr) {
+ m_env->DeleteLocalRef(j_value);
+ }
+ if (j_key != nullptr) {
+ m_env->DeleteLocalRef(j_key);
+ }
+
+ // all OK
+ return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::OK()));
+}
+
+std::unique_ptr<rocksdb::Status> WriteBatchHandlerJniCallback::k_op(const Slice& key, std::function<void(jbyteArray)> kFn) {
+ const jbyteArray j_key = JniUtil::copyBytes(m_env, key);
+ if (j_key == nullptr) {
+ // exception thrown
+ if (m_env->ExceptionCheck()) {
+ m_env->ExceptionDescribe();
+ }
+ return nullptr;
+ }
+
+ kFn(j_key);
+
+ // check for Exception, in-particular RocksDBException
+ if (m_env->ExceptionCheck()) {
+ if (j_key != nullptr) {
+ m_env->DeleteLocalRef(j_key);
+ }
+
+ // exception thrown
+ jthrowable exception = m_env->ExceptionOccurred();
+ std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
+ if (status == nullptr) {
+ // unkown status or exception occurred extracting status
+ m_env->ExceptionDescribe();
+ return nullptr;
+
+ } else {
+ m_env->ExceptionClear(); // clear the exception, as we have extracted the status
+ return status;
+ }
+ }
+
+ if (j_key != nullptr) {
+ m_env->DeleteLocalRef(j_key);
+ }
+
+ // all OK
+ return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::OK()));
+}
+} // namespace rocksdb
diff --git a/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.h b/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.h
new file mode 100644
index 00000000..720f1693
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// This file implements the callback "bridge" between Java and C++ for
+// rocksdb::WriteBatch::Handler.
+
+#ifndef JAVA_ROCKSJNI_WRITEBATCHHANDLERJNICALLBACK_H_
+#define JAVA_ROCKSJNI_WRITEBATCHHANDLERJNICALLBACK_H_
+
+#include <functional>
+#include <jni.h>
+#include <memory>
+#include "rocksjni/jnicallback.h"
+#include "rocksdb/write_batch.h"
+
+namespace rocksdb {
+/**
+ * This class acts as a bridge between C++
+ * and Java. The methods in this class will be
+ * called back from the RocksDB storage engine (C++)
+ * which calls the appropriate Java method.
+ * This enables Write Batch Handlers to be implemented in Java.
+ */
+class WriteBatchHandlerJniCallback : public JniCallback, public WriteBatch::Handler {
+ public:
+ WriteBatchHandlerJniCallback(
+ JNIEnv* env, jobject jWriteBackHandler);
+ Status PutCF(uint32_t column_family_id, const Slice& key,
+ const Slice& value);
+ void Put(const Slice& key, const Slice& value);
+ Status MergeCF(uint32_t column_family_id, const Slice& key,
+ const Slice& value);
+ void Merge(const Slice& key, const Slice& value);
+ Status DeleteCF(uint32_t column_family_id, const Slice& key);
+ void Delete(const Slice& key);
+ Status SingleDeleteCF(uint32_t column_family_id, const Slice& key);
+ void SingleDelete(const Slice& key);
+ Status DeleteRangeCF(uint32_t column_family_id, const Slice& beginKey,
+ const Slice& endKey);
+ void DeleteRange(const Slice& beginKey, const Slice& endKey);
+ void LogData(const Slice& blob);
+ Status PutBlobIndexCF(uint32_t column_family_id, const Slice& key,
+ const Slice& value);
+ Status MarkBeginPrepare(bool);
+ Status MarkEndPrepare(const Slice& xid);
+ Status MarkNoop(bool empty_batch);
+ Status MarkRollback(const Slice& xid);
+ Status MarkCommit(const Slice& xid);
+ bool Continue();
+
+ private:
+ JNIEnv* m_env;
+ jmethodID m_jPutCfMethodId;
+ jmethodID m_jPutMethodId;
+ jmethodID m_jMergeCfMethodId;
+ jmethodID m_jMergeMethodId;
+ jmethodID m_jDeleteCfMethodId;
+ jmethodID m_jDeleteMethodId;
+ jmethodID m_jSingleDeleteCfMethodId;
+ jmethodID m_jSingleDeleteMethodId;
+ jmethodID m_jDeleteRangeCfMethodId;
+ jmethodID m_jDeleteRangeMethodId;
+ jmethodID m_jLogDataMethodId;
+ jmethodID m_jPutBlobIndexCfMethodId;
+ jmethodID m_jMarkBeginPrepareMethodId;
+ jmethodID m_jMarkEndPrepareMethodId;
+ jmethodID m_jMarkNoopMethodId;
+ jmethodID m_jMarkRollbackMethodId;
+ jmethodID m_jMarkCommitMethodId;
+ jmethodID m_jContinueMethodId;
+ /**
+ * @return A pointer to a rocksdb::Status or nullptr if an unexpected exception occurred
+ */
+ std::unique_ptr<rocksdb::Status> kv_op(const Slice& key, const Slice& value, std::function<void(jbyteArray, jbyteArray)> kvFn);
+ /**
+ * @return A pointer to a rocksdb::Status or nullptr if an unexpected exception occurred
+ */
+ std::unique_ptr<rocksdb::Status> k_op(const Slice& key, std::function<void(jbyteArray)> kFn);
+};
+} // namespace rocksdb
+
+#endif // JAVA_ROCKSJNI_WRITEBATCHHANDLERJNICALLBACK_H_