Skip to content

Commit

Permalink
Expose OccValidationPolicy to Java API
Browse files Browse the repository at this point in the history
Allow users of RocksDB JNI to specify the OCC Validation Policy
when using OptimisticTransactionOptionsDB.
  • Loading branch information
vjeko committed Apr 29, 2024
1 parent 8897bf2 commit 15fff9e
Show file tree
Hide file tree
Showing 14 changed files with 430 additions and 14 deletions.
4 changes: 4 additions & 0 deletions db_stress_tool/db_stress_test_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3115,6 +3115,10 @@ void StressTest::Open(SharedState* shared, bool reopen) {
} else {
options_.two_write_queues = FLAGS_two_write_queues;
}
if (FLAGS_use_optimistic_txn) {
assert(optimistic_txn_db_->GetValidatePolicy() ==
static_cast<OccValidationPolicy>(FLAGS_occ_validation_policy));
}
txn_db_options.wp_snapshot_cache_bits =
static_cast<size_t>(FLAGS_wp_snapshot_cache_bits);
txn_db_options.wp_commit_cache_bits =
Expand Down
3 changes: 3 additions & 0 deletions include/rocksdb/utilities/optimistic_transaction_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ class OptimisticTransactionDB : public StackableDB {
OptimisticTransactionOptions(),
Transaction* old_txn = nullptr) = 0;

// Get the OCC Validation Policy specified for this instance.
virtual OccValidationPolicy GetValidatePolicy() const = 0;

OptimisticTransactionDB(const OptimisticTransactionDB&) = delete;
void operator=(const OptimisticTransactionDB&) = delete;

Expand Down
5 changes: 5 additions & 0 deletions java/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ set(JNI_NATIVE_SOURCES
rocksjni/merge_operator.cc
rocksjni/native_comparator_wrapper_test.cc
rocksjni/optimistic_transaction_db.cc
rocksjni/optimistic_transaction_db_options.cc
rocksjni/optimistic_transaction_options.cc
rocksjni/options.cc
rocksjni/options_util.cc
Expand Down Expand Up @@ -206,9 +207,11 @@ set(JAVA_MAIN_CLASSES
src/main/java/org/rocksdb/MutableOptionValue.java
src/main/java/org/rocksdb/NativeComparatorWrapper.java
src/main/java/org/rocksdb/NativeLibraryLoader.java
src/main/java/org/rocksdb/OccValidationPolicy.java
src/main/java/org/rocksdb/OperationStage.java
src/main/java/org/rocksdb/OperationType.java
src/main/java/org/rocksdb/OptimisticTransactionDB.java
src/main/java/org/rocksdb/OptimisticTransactionDBOptions.java
src/main/java/org/rocksdb/OptimisticTransactionOptions.java
src/main/java/org/rocksdb/OptionString.java
src/main/java/org/rocksdb/Options.java
Expand Down Expand Up @@ -366,6 +369,7 @@ set(JAVA_TEST_CLASSES
src/test/java/org/rocksdb/MutableOptionsGetSetTest.java
src/test/java/org/rocksdb/NativeLibraryLoaderTest.java
src/test/java/org/rocksdb/OptimisticTransactionDBTest.java
src/test/java/org/rocksdb/OptimisticTransactionOptionsDBTest.java
src/test/java/org/rocksdb/OptimisticTransactionOptionsTest.java
src/test/java/org/rocksdb/OptimisticTransactionTest.java
src/test/java/org/rocksdb/OptionsTest.java
Expand Down Expand Up @@ -485,6 +489,7 @@ set(JAVA_TEST_RUNNING_CLASSES
org.rocksdb.NativeComparatorWrapperTest
org.rocksdb.NativeLibraryLoaderTest
org.rocksdb.OptimisticTransactionDBTest
org.rocksdb.OptimisticTransactionOptionsDBTest
org.rocksdb.OptimisticTransactionOptionsTest
org.rocksdb.OptimisticTransactionTest
org.rocksdb.OptionsTest
Expand Down
1 change: 1 addition & 0 deletions java/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ JAVA_TESTS = \
org.rocksdb.NativeLibraryLoaderTest\
org.rocksdb.OptimisticTransactionTest\
org.rocksdb.OptimisticTransactionDBTest\
org.rocksdb.OptimisticTransactionOptionsDBTest\
org.rocksdb.OptimisticTransactionOptionsTest\
org.rocksdb.OptionsUtilTest\
org.rocksdb.OptionsTest\
Expand Down
34 changes: 28 additions & 6 deletions java/rocksjni/optimistic_transaction_db.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ jlong Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2(
/*
* Class: org_rocksdb_OptimisticTransactionDB
* Method: open
* Signature: (JLjava/lang/String;[[B[J)[J
* Signature: (JJLjava/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,
JNIEnv* env, jclass, jlong jdb_options_handle,
jlong jdb_optimistic_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) {
Expand Down Expand Up @@ -103,13 +104,21 @@ Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2_3_3B_3J(
env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
}

auto* db_options =
const auto* db_options =
reinterpret_cast<ROCKSDB_NAMESPACE::DBOptions*>(jdb_options_handle);
std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> handles;
ROCKSDB_NAMESPACE::Status s;
ROCKSDB_NAMESPACE::OptimisticTransactionDB* otdb = nullptr;
const ROCKSDB_NAMESPACE::Status s =
ROCKSDB_NAMESPACE::OptimisticTransactionDB::Open(
*db_options, db_path, column_families, &handles, &otdb);
if (jdb_options_handle) {
const auto* otdb_options =
reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions*>(
jdb_options_handle);
s = ROCKSDB_NAMESPACE::OptimisticTransactionDB::Open(
*db_options, *otdb_options, db_path, column_families, &handles, &otdb);
} else {
s = ROCKSDB_NAMESPACE::OptimisticTransactionDB::Open(
*db_options, db_path, column_families, &handles, &otdb);
}

env->ReleaseStringUTFChars(jdb_path, db_path);

Expand Down Expand Up @@ -257,6 +266,19 @@ jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJJ(
return GET_CPLUSPLUS_POINTER(txn);
}

/*
* Class: org_rocksdb_OptimisticTransactionDB
* Method: getOccValidationPolicy
* Signature: (J)B
*/
jbyte Java_org_rocksdb_OptimisticTransactionDB_getOccValidationPolicy(
JNIEnv*, jclass, jlong jhandle) {
const auto* optimistic_txn_db =
reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
return ROCKSDB_NAMESPACE::OccValidationPolicyJni::toJavaOccValidationPolicy(
optimistic_txn_db->GetValidatePolicy());
}

/*
* Class: org_rocksdb_OptimisticTransactionDB
* Method: getBaseDB
Expand Down
93 changes: 93 additions & 0 deletions java/rocksjni/optimistic_transaction_db_options.cc
Original file line number Diff line number Diff line change
@@ -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 "bridge" between Java and C++
// for ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions.

#include <jni.h>

#include "include/org_rocksdb_OptimisticTransactionOptions.h"
#include "rocksdb/comparator.h"
#include "rocksdb/utilities/optimistic_transaction_db.h"
#include "rocksjni/cplusplus_to_java_convert.h"
#include "rocksjni/portal.h"

/*
* Class: org_rocksdb_OptimisticTransactionDBOptions
* Method: newOptimisticTransactionDBOptions
* Signature: ()J
*/
jlong Java_org_rocksdb_OptimisticTransactionDBOptions_newOptimisticTransactionDBOptions(
JNIEnv* /*env*/, jclass /*jcls*/) {
ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions* opts =
new ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions();
return GET_CPLUSPLUS_POINTER(opts);
}

/*
* Class: org_rocksdb_OptimisticTransactionDBOptions
* Method: setOccValidationPolicy
* Signature: (JB)V
*/
void Java_org_rocksdb_OptimisticTransactionDBOptions_setOccValidationPolicy(
JNIEnv* /*env*/, jclass /*jcls*/, jlong jhandle, jbyte policy) {
auto* opts =
reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions*>(
jhandle);
opts->validate_policy =
ROCKSDB_NAMESPACE::OccValidationPolicyJni::toCppOccValidationPolicy(
policy);
}

/*
* Class: org_rocksdb_OptimisticTransactionDBOptions
* Method: getOccValidationPolicy
* Signature: (J)B
*/
jbyte Java_org_rocksdb_OptimisticTransactionDBOptions_getOccValidationPolicy(
JNIEnv* /*env*/, jclass /*jcls*/, jlong jhandle) {
auto* opts =
reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions*>(
jhandle);
return ROCKSDB_NAMESPACE::OccValidationPolicyJni::toJavaOccValidationPolicy(
opts->validate_policy);
}

/*
* Class: org_rocksdb_OptimisticTransactionDBOptions
* Method: setOccValidationPolicy
* Signature: (JJ)V
*/
void Java_org_rocksdb_OptimisticTransactionDBOptions_setOccLockBuckets(
JNIEnv* /*env*/, jclass /*jcls*/, jlong jhandle, jlong occ_lock_buckets) {
auto* opts =
reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions*>(
jhandle);
opts->occ_lock_buckets = static_cast<uint32_t>(occ_lock_buckets);
}

/*
* Class: org_rocksdb_OptimisticTransactionDBOptions
* Method: getOccValidationPolicy
* Signature: (J)J
*/
jlong Java_org_rocksdb_OptimisticTransactionDBOptions_getOccLockBuckets(
JNIEnv* /*env*/, jclass /*jcls*/, jlong jhandle) {
auto* opts =
reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions*>(
jhandle);
return static_cast<long>(opts->occ_lock_buckets);
}

/*
* Class: org_rocksdb_OptimisticTransactionDBOptions
* Method: disposeInternal
* Signature: (J)V
*/
void Java_org_rocksdb_OptimisticTransactionDBOptions_disposeInternalJni(
JNIEnv* /*env*/, jclass /*jcls*/, jlong jhandle) {
delete reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDBOptions*>(
jhandle);
}
26 changes: 26 additions & 0 deletions java/rocksjni/portal.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "rocksdb/table.h"
#include "rocksdb/utilities/backup_engine.h"
#include "rocksdb/utilities/memory_util.h"
#include "rocksdb/utilities/optimistic_transaction_db.h"
#include "rocksdb/utilities/transaction_db.h"
#include "rocksdb/utilities/write_batch_with_index.h"
#include "rocksjni/compaction_filter_factory_jnicallback.h"
Expand Down Expand Up @@ -6358,6 +6359,31 @@ class TransactionDBJni : public JavaClass {
return jdeadlock_info;
}
};
// The portal class for org.rocksdb.OccValidationPolicy.
class OccValidationPolicyJni {
public:
static jbyte toJavaOccValidationPolicy(
const ROCKSDB_NAMESPACE::OccValidationPolicy policy) {
switch (policy) {
case ROCKSDB_NAMESPACE::OccValidationPolicy::kValidateSerial:
return 0x0;
case ROCKSDB_NAMESPACE::OccValidationPolicy::kValidateParallel:
default:
return 0x1;
}
}

static ROCKSDB_NAMESPACE::OccValidationPolicy toCppOccValidationPolicy(
const jbyte policy) {
switch (policy) {
case 0x0:
return ROCKSDB_NAMESPACE::OccValidationPolicy::kValidateSerial;
case 0x1:
default:
return ROCKSDB_NAMESPACE::OccValidationPolicy::kValidateParallel;
}
}
};

// The portal class for org.rocksdb.TxnDBWritePolicy
class TxnDBWritePolicyJni {
Expand Down
65 changes: 65 additions & 0 deletions java/src/main/java/org/rocksdb/OccValidationPolicy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
// 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).

package org.rocksdb;

/**
* Defines the policy for optimistic concurrency control validation.
* This enum specifies the manner in which the validation occurs
* during the commit stage.
*/
public enum OccValidationPolicy {
/**
* Validate serially at commit stage, AFTER entering the write-group.
* This method processes isolation validation in a single-threaded manner
* within the write-group, potentially suffering from high mutex contention
* as discussed in the following issue:
* <a href="https://github.com/facebook/rocksdb/issues/4402">GitHub 4402</a>
*/
VALIDATE_SERIAL((byte) 0),

/**
* Validate parallelly before the commit stage, BEFORE entering the write-group.
* This approach aims to reduce mutex contention by having each
* transaction acquire locks for its write-set records in a well-defined
* order prior to entering the write-group.
*/
VALIDATE_PARALLEL((byte) 1);

private final byte _value;

/**
* Constructor for the OccValidationPolicy enum.
* @param _value the byte representation that corresponds to
* one of the above enums.
*/
OccValidationPolicy(final byte _value) {
this._value = _value;
}

/**
* Retrieves the byte representation associated with this validation policy.
* @return the byte representation of the validation policy.
*/
public byte getValue() {
return _value;
}

/**
* Given a byte representation of a value, convert it to {@link OccValidationPolicy}.
*
* @param policy the byte representation of the policy.
* @return the matching OccValidationPolicy.
* @throws IllegalArgumentException if no matching policy is found.
*/
public static OccValidationPolicy getOccValidationPolicy(final byte policy) {
for (OccValidationPolicy value : OccValidationPolicy.values()) {
if (value.getValue() == policy) {
return value;
}
}
throw new IllegalArgumentException("Unknown OccValidationPolicy constant : " + policy);
}
}

0 comments on commit 15fff9e

Please sign in to comment.