Implement missing compactrangeoptions from Java API (#10880)

Summary:
Add the following missing options to `src/main/java/org/rocksdb/CompactRangeOptions.java` and in `java/rocksjni/options.cc` in RocksJava.

For the descriptions and API see the C++ file `include/rocksdb/options.h`, specifically the struct `CompactRangeOptions`

* full_history_ts_low
* canceled

We changed the handle to return an object (of class `Java_org_rocksdb_CompactRangeOptions`) containing a `ROCKSDB_NAMESPACE::CompactRangeOptions` at (almost certainly) 0-offset, rather than a raw `ROCKSDB_NAMESPACE::CompactRangeOptions`.

The `Java_org_rocksdb_CompactRangeOptions` contains as supplementary fields objects (std::string, std::atomic<bool>) which are passed as pointers to the `ROCKSDB_NAMESPACE::CompactRangeOptions` and which must therefore live for as long as the `ROCKSDB_NAMESPACE::CompactRangeOptions`. By placing them in a `Java_org_rocksdb_CompactRangeOptions` we achieve this.

Because the field offset of the `ROCKSDB_NAMESPACE::CompactRangeOptions` member is (very probably) 0, casting the handle to ROCKSDB_NAMESPACE::CompactRangeOptions works (i.e. old methods didn’t have to be changed), but really that’s a minefield and the correct answer is to cast to the correct type (Java_org_rocksdb_CompactRangeOptions) and then use the ROCKSDB_NAMESPACE::CompactRangeOptions field in that. So the get/set methods for existing parameters have this change.

Testing
-------
We added unit tests for getting and setting the newly implemented fields to `CompactRangeOptionsTest`

Pull Request resolved: https://github.com/facebook/rocksdb/pull/10880

Reviewed By: ajkr

Differential Revision: D41482476

Pulled By: anand1976

fbshipit-source-id: c70795e790436fb3544655920adf6fca62ed34e2
oxigraph-main
Alan Paxton 2 years ago committed by Facebook GitHub Bot
parent 28bf7ba77d
commit 93e0715fad
  1. 178
      java/rocksjni/compact_range_options.cc
  2. 23
      java/rocksjni/portal.h
  3. 59
      java/src/main/java/org/rocksdb/CompactRangeOptions.java
  4. 36
      java/src/test/java/org/rocksdb/CompactRangeOptionsTest.java

@ -12,6 +12,56 @@
#include "rocksdb/options.h"
#include "rocksjni/cplusplus_to_java_convert.h"
#include "rocksjni/portal.h"
#include "util/coding.h"
/**
* @brief Class containing compact range options for Java API
*
* An object of this class is returned as the native handle for
* ROCKSDB_NAMESPACE::CompactRangeOptions It contains objects for various
* parameters which are passed by reference/pointer in CompactRangeOptions. We
* maintain the lifetime of these parameters (`full_history_ts_low`, `canceled`)
* by including their values in this class.
*/
class Java_org_rocksdb_CompactRangeOptions {
public:
ROCKSDB_NAMESPACE::CompactRangeOptions compactRangeOptions;
private:
std::string full_history_ts_low;
std::atomic<bool> canceled;
public:
void set_full_history_ts_low(uint64_t start, uint64_t range) {
full_history_ts_low = "";
ROCKSDB_NAMESPACE::PutFixed64(&full_history_ts_low, start);
ROCKSDB_NAMESPACE::PutFixed64(&full_history_ts_low, range);
compactRangeOptions.full_history_ts_low =
new ROCKSDB_NAMESPACE::Slice(full_history_ts_low);
}
bool read_full_history_ts_low(uint64_t* start, uint64_t* range) {
if (compactRangeOptions.full_history_ts_low == nullptr) return false;
ROCKSDB_NAMESPACE::Slice read_slice(
compactRangeOptions.full_history_ts_low->ToStringView());
if (!ROCKSDB_NAMESPACE::GetFixed64(&read_slice, start)) return false;
return ROCKSDB_NAMESPACE::GetFixed64(&read_slice, range);
}
void set_canceled(bool value) {
if (compactRangeOptions.canceled == nullptr) {
canceled.store(value, std::memory_order_seq_cst);
compactRangeOptions.canceled = &canceled;
} else {
compactRangeOptions.canceled->store(value, std::memory_order_seq_cst);
}
}
bool get_canceled() {
return compactRangeOptions.canceled &&
compactRangeOptions.canceled->load(std::memory_order_seq_cst);
}
};
/*
* Class: org_rocksdb_CompactRangeOptions
@ -20,8 +70,8 @@
*/
jlong Java_org_rocksdb_CompactRangeOptions_newCompactRangeOptions(
JNIEnv* /*env*/, jclass /*jclazz*/) {
auto* options = new ROCKSDB_NAMESPACE::CompactRangeOptions();
return GET_CPLUSPLUS_POINTER(options);
auto* options = new Java_org_rocksdb_CompactRangeOptions();
return GET_CPLUSPLUS_POINTER(&options->compactRangeOptions);
}
/*
@ -32,8 +82,9 @@ jlong Java_org_rocksdb_CompactRangeOptions_newCompactRangeOptions(
jboolean Java_org_rocksdb_CompactRangeOptions_exclusiveManualCompaction(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
return static_cast<jboolean>(options->exclusive_manual_compaction);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return static_cast<jboolean>(
options->compactRangeOptions.exclusive_manual_compaction);
}
/*
@ -45,8 +96,8 @@ void Java_org_rocksdb_CompactRangeOptions_setExclusiveManualCompaction(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
jboolean exclusive_manual_compaction) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->exclusive_manual_compaction =
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.exclusive_manual_compaction =
static_cast<bool>(exclusive_manual_compaction);
}
@ -58,9 +109,10 @@ void Java_org_rocksdb_CompactRangeOptions_setExclusiveManualCompaction(
jint Java_org_rocksdb_CompactRangeOptions_bottommostLevelCompaction(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return ROCKSDB_NAMESPACE::BottommostLevelCompactionJni::
toJavaBottommostLevelCompaction(options->bottommost_level_compaction);
toJavaBottommostLevelCompaction(
options->compactRangeOptions.bottommost_level_compaction);
}
/*
@ -72,8 +124,8 @@ void Java_org_rocksdb_CompactRangeOptions_setBottommostLevelCompaction(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
jint bottommost_level_compaction) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->bottommost_level_compaction =
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.bottommost_level_compaction =
ROCKSDB_NAMESPACE::BottommostLevelCompactionJni::
toCppBottommostLevelCompaction(bottommost_level_compaction);
}
@ -87,8 +139,8 @@ jboolean Java_org_rocksdb_CompactRangeOptions_changeLevel(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
return static_cast<jboolean>(options->change_level);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return static_cast<jboolean>(options->compactRangeOptions.change_level);
}
/*
@ -99,8 +151,8 @@ jboolean Java_org_rocksdb_CompactRangeOptions_changeLevel(JNIEnv* /*env*/,
void Java_org_rocksdb_CompactRangeOptions_setChangeLevel(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jboolean change_level) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->change_level = static_cast<bool>(change_level);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.change_level = static_cast<bool>(change_level);
}
/*
@ -112,8 +164,8 @@ jint Java_org_rocksdb_CompactRangeOptions_targetLevel(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
return static_cast<jint>(options->target_level);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return static_cast<jint>(options->compactRangeOptions.target_level);
}
/*
@ -126,8 +178,8 @@ void Java_org_rocksdb_CompactRangeOptions_setTargetLevel(JNIEnv* /*env*/,
jlong jhandle,
jint target_level) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->target_level = static_cast<int>(target_level);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.target_level = static_cast<int>(target_level);
}
/*
@ -139,8 +191,8 @@ jint Java_org_rocksdb_CompactRangeOptions_targetPathId(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
return static_cast<jint>(options->target_path_id);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return static_cast<jint>(options->compactRangeOptions.target_path_id);
}
/*
@ -153,8 +205,9 @@ void Java_org_rocksdb_CompactRangeOptions_setTargetPathId(JNIEnv* /*env*/,
jlong jhandle,
jint target_path_id) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->target_path_id = static_cast<uint32_t>(target_path_id);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.target_path_id =
static_cast<uint32_t>(target_path_id);
}
/*
@ -166,8 +219,8 @@ jboolean Java_org_rocksdb_CompactRangeOptions_allowWriteStall(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
return static_cast<jboolean>(options->allow_write_stall);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return static_cast<jboolean>(options->compactRangeOptions.allow_write_stall);
}
/*
@ -179,8 +232,9 @@ void Java_org_rocksdb_CompactRangeOptions_setAllowWriteStall(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
jboolean allow_write_stall) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->allow_write_stall = static_cast<bool>(allow_write_stall);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.allow_write_stall =
static_cast<bool>(allow_write_stall);
}
/*
@ -192,8 +246,8 @@ jint Java_org_rocksdb_CompactRangeOptions_maxSubcompactions(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
return static_cast<jint>(options->max_subcompactions);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return static_cast<jint>(options->compactRangeOptions.max_subcompactions);
}
/*
@ -204,8 +258,70 @@ jint Java_org_rocksdb_CompactRangeOptions_maxSubcompactions(JNIEnv* /*env*/,
void Java_org_rocksdb_CompactRangeOptions_setMaxSubcompactions(
JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle, jint max_subcompactions) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
options->max_subcompactions = static_cast<uint32_t>(max_subcompactions);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->compactRangeOptions.max_subcompactions =
static_cast<uint32_t>(max_subcompactions);
}
/*
* Class: org_rocksdb_CompactRangeOptions
* Method: setFullHistoryTSLow
* Signature: (JJJ)V
*/
void Java_org_rocksdb_CompactRangeOptions_setFullHistoryTSLow(JNIEnv*, jobject,
jlong jhandle,
jlong start,
jlong range) {
auto* options =
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->set_full_history_ts_low(start, range);
}
/*
* Class: org_rocksdb_CompactRangeOptions
* Method: fullHistoryTSLow
* Signature: (J)Lorg/rocksdb/CompactRangeOptions/Timestamp;
*/
jobject Java_org_rocksdb_CompactRangeOptions_fullHistoryTSLow(JNIEnv* env,
jobject,
jlong jhandle) {
auto* options =
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
uint64_t start;
uint64_t range;
jobject result = nullptr;
if (options->read_full_history_ts_low(&start, &range)) {
result =
ROCKSDB_NAMESPACE::CompactRangeOptionsTimestampJni::fromCppTimestamp(
env, start, range);
}
return result;
}
/*
* Class: org_rocksdb_CompactRangeOptions
* Method: setCanceled
* Signature: (JZ)V
*/
void Java_org_rocksdb_CompactRangeOptions_setCanceled(JNIEnv*, jobject,
jlong jhandle,
jboolean jcanceled) {
auto* options =
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
options->set_canceled(jcanceled);
}
/*
* Class: org_rocksdb_CompactRangeOptions
* Method: canceled
* Signature: (J)Z
*/
jboolean Java_org_rocksdb_CompactRangeOptions_canceled(JNIEnv*, jobject,
jlong jhandle) {
auto* options =
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
return options->get_canceled();
}
/*
@ -217,6 +333,6 @@ void Java_org_rocksdb_CompactRangeOptions_disposeInternal(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(jhandle);
reinterpret_cast<Java_org_rocksdb_CompactRangeOptions*>(jhandle);
delete options;
}

@ -8702,5 +8702,28 @@ class FileOperationInfoJni : public JavaClass {
"(Ljava/lang/String;JJJJLorg/rocksdb/Status;)V");
}
};
class CompactRangeOptionsTimestampJni : public JavaClass {
public:
static jobject fromCppTimestamp(JNIEnv* env, const uint64_t start,
const uint64_t range) {
jclass jclazz = getJClass(env);
assert(jclazz != nullptr);
static jmethodID ctor = getConstructorMethodId(env, jclazz);
assert(ctor != nullptr);
return env->NewObject(jclazz, ctor, static_cast<jlong>(start),
static_cast<jlong>(range));
}
static jclass getJClass(JNIEnv* env) {
return JavaClass::getJClass(env,
"org/rocksdb/CompactRangeOptions$Timestamp");
}
static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
return env->GetMethodID(clazz, "<init>", "(JJ)V");
}
};
} // namespace ROCKSDB_NAMESPACE
#endif // JAVA_ROCKSJNI_PORTAL_H_

@ -5,6 +5,8 @@
package org.rocksdb;
import java.util.Objects;
/**
* CompactRangeOptions is used by CompactRange() call. In the documentation of the methods "the compaction" refers to
* any compaction that is using this CompactRangeOptions.
@ -69,6 +71,36 @@ public class CompactRangeOptions extends RocksObject {
}
}
public static class Timestamp {
public final long start;
public final long range;
public Timestamp(final long start, final long duration) {
this.start = start;
this.range = duration;
}
public Timestamp() {
this.start = 0;
this.range = 0;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Timestamp timestamp = (Timestamp) o;
return start == timestamp.start && range == timestamp.range;
}
@Override
public int hashCode() {
return Objects.hash(start, range);
}
}
/**
* Construct CompactRangeOptions.
*/
@ -218,6 +250,24 @@ public class CompactRangeOptions extends RocksObject {
return this;
}
public CompactRangeOptions setFullHistoryTSLow(final Timestamp tsLow) {
setFullHistoryTSLow(nativeHandle_, tsLow.start, tsLow.range);
return this;
}
public Timestamp fullHistoryTSLow() {
return fullHistoryTSLow(nativeHandle_);
}
public CompactRangeOptions setCanceled(final boolean canceled) {
setCanceled(nativeHandle_, canceled);
return this;
}
public boolean canceled() {
return canceled(nativeHandle_);
}
private static native long newCompactRangeOptions();
@Override protected final native void disposeInternal(final long handle);
@ -242,4 +292,13 @@ public class CompactRangeOptions extends RocksObject {
private native void setMaxSubcompactions(final long handle,
final int maxSubcompactions);
private native int maxSubcompactions(final long handle);
private native void setFullHistoryTSLow(
final long handle, final long timestampStart, final long timestampRange);
private native Timestamp fullHistoryTSLow(final long handle);
private native void setCanceled(final long handle, final boolean canceled);
private native boolean canceled(final long handle);
}

@ -99,4 +99,40 @@ public class CompactRangeOptionsTest {
assertThat(opt.maxSubcompactions()).isEqualTo(value);
}
}
@Test
public void fullHistoryTSLow() {
CompactRangeOptions opt = new CompactRangeOptions();
CompactRangeOptions.Timestamp timestamp = new CompactRangeOptions.Timestamp(18, 1);
opt.setFullHistoryTSLow(timestamp);
for (int times = 1; times <= 2; times++) {
// worried slightly about destructive reads, so read it twice
CompactRangeOptions.Timestamp timestampResult = opt.fullHistoryTSLow();
assertThat(timestamp.start).isEqualTo(timestampResult.start);
assertThat(timestamp.range).isEqualTo(timestampResult.range);
assertThat(timestamp).isEqualTo(timestampResult);
}
}
@Test
public void fullHistoryTSLowDefault() {
CompactRangeOptions opt = new CompactRangeOptions();
CompactRangeOptions.Timestamp timestampResult = opt.fullHistoryTSLow();
assertThat(timestampResult).isNull();
}
@Test
public void canceled() {
CompactRangeOptions opt = new CompactRangeOptions();
assertThat(opt.canceled()).isEqualTo(false);
opt.setCanceled(true);
assertThat(opt.canceled()).isEqualTo(true);
opt.setCanceled(false);
assertThat(opt.canceled()).isEqualTo(false);
opt.setCanceled(true);
assertThat(opt.canceled()).isEqualTo(true);
opt.setCanceled(true);
assertThat(opt.canceled()).isEqualTo(true);
}
}

Loading…
Cancel
Save