JNI support for ReadOptions::iterate_lower_bound (#4444)
Summary: Fixes: #4401 Pull Request resolved: https://github.com/facebook/rocksdb/pull/4444 Differential Revision: D10282120 Pulled By: sagar0 fbshipit-source-id: d9ddcc1b132208ae7f806fa2106add6fec1baa11
This commit is contained in:
parent
517d3b8b77
commit
f45c0d20de
@ -6525,6 +6525,31 @@ jlong Java_org_rocksdb_ReadOptions_iterateUpperBound(JNIEnv* /*env*/,
|
||||
return reinterpret_cast<jlong>(upper_bound_slice_handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_ReadOptions
|
||||
* Method: setIterateLowerBound
|
||||
* Signature: (JJ)I
|
||||
*/
|
||||
void Java_org_rocksdb_ReadOptions_setIterateLowerBound(
|
||||
JNIEnv* /*env*/, jobject /*jobj*/, 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* /*env*/,
|
||||
jobject /*jobj*/,
|
||||
jlong jhandle) {
|
||||
auto& lower_bound_slice_handle =
|
||||
reinterpret_cast<rocksdb::ReadOptions*>(jhandle)->iterate_lower_bound;
|
||||
return reinterpret_cast<jlong>(lower_bound_slice_handle);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::ComparatorOptions
|
||||
|
||||
|
@ -27,6 +27,7 @@ public class ReadOptions extends RocksObject {
|
||||
public ReadOptions(ReadOptions other) {
|
||||
super(copyReadOptions(other.nativeHandle_));
|
||||
iterateUpperBoundSlice_ = other.iterateUpperBoundSlice_;
|
||||
iterateLowerBoundSlice_ = other.iterateLowerBoundSlice_;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,15 +424,65 @@ public class ReadOptions extends RocksObject {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the smallest key at which the backward iterator can return an
|
||||
* entry. Once the bound is passed, Valid() will be false.
|
||||
* `iterate_lower_bound` is inclusive ie the bound value is a valid entry.
|
||||
*
|
||||
* If prefix_extractor is not null, the Seek target and `iterate_lower_bound`
|
||||
* need to have the same prefix. This is because ordering is not guaranteed
|
||||
* outside of prefix domain.
|
||||
*
|
||||
* Default: nullptr
|
||||
*
|
||||
* @param iterateLowerBound Slice representing the lower bound
|
||||
* @return the reference to the current ReadOptions.
|
||||
*/
|
||||
public ReadOptions setIterateLowerBound(final Slice iterateLowerBound) {
|
||||
assert(isOwningHandle());
|
||||
if (iterateLowerBound != null) {
|
||||
// Hold onto a reference so it doesn't get garbaged collected out from under us.
|
||||
iterateLowerBoundSlice_ = iterateLowerBound;
|
||||
setIterateLowerBound(nativeHandle_, iterateLowerBoundSlice_.getNativeHandle());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the smallest key at which the backward iterator can return an
|
||||
* entry. Once the bound is passed, Valid() will be false.
|
||||
* `iterate_lower_bound` is inclusive ie the bound value is a valid entry.
|
||||
*
|
||||
* If prefix_extractor is not null, the Seek target and `iterate_lower_bound`
|
||||
* need to have the same prefix. This is because ordering is not guaranteed
|
||||
* outside of prefix domain.
|
||||
*
|
||||
* Default: nullptr
|
||||
*
|
||||
* @return Slice representing current iterate_lower_bound setting, or null if
|
||||
* one does not exist.
|
||||
*/
|
||||
public Slice iterateLowerBound() {
|
||||
assert(isOwningHandle());
|
||||
long lowerBoundSliceHandle = iterateLowerBound(nativeHandle_);
|
||||
if (lowerBoundSliceHandle != 0) {
|
||||
// Disown the new slice - it's owned by the C++ side of the JNI boundary
|
||||
// from the perspective of this method.
|
||||
return new Slice(lowerBoundSliceHandle, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// instance variables
|
||||
// NOTE: If you add new member variables, please update the copy constructor above!
|
||||
//
|
||||
// Hold a reference to any iterate upper bound that was set on this object
|
||||
// Hold a reference to any iterate upper/lower bound that was set on this object
|
||||
// until we're destroyed or it's overwritten. That way the caller can freely
|
||||
// leave scope without us losing the Java Slice object, which during close()
|
||||
// would also reap its associated rocksdb::Slice native object since it's
|
||||
// possibly (likely) to be an owning handle.
|
||||
protected Slice iterateUpperBoundSlice_;
|
||||
protected Slice iterateLowerBoundSlice_;
|
||||
|
||||
private native static long newReadOptions();
|
||||
private native static long copyReadOptions(long handle);
|
||||
@ -465,6 +516,9 @@ public class ReadOptions extends RocksObject {
|
||||
private native void setIterateUpperBound(final long handle,
|
||||
final long upperBoundSliceHandle);
|
||||
private native long iterateUpperBound(final long handle);
|
||||
private native void setIterateLowerBound(final long handle,
|
||||
final long upperBoundSliceHandle);
|
||||
private native long iterateLowerBound(final long handle);
|
||||
|
||||
@Override protected final native void disposeInternal(final long handle);
|
||||
|
||||
|
@ -144,16 +144,34 @@ public class ReadOptionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void iterateLowerBound() {
|
||||
try (final ReadOptions opt = new ReadOptions()) {
|
||||
Slice lowerBound = buildRandomSlice();
|
||||
opt.setIterateLowerBound(lowerBound);
|
||||
assertThat(Arrays.equals(lowerBound.data(), opt.iterateLowerBound().data())).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void iterateLowerBoundNull() {
|
||||
try (final ReadOptions opt = new ReadOptions()) {
|
||||
assertThat(opt.iterateLowerBound()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void copyConstructor() {
|
||||
try (final ReadOptions opt = new ReadOptions()) {
|
||||
opt.setVerifyChecksums(false);
|
||||
opt.setFillCache(false);
|
||||
opt.setIterateUpperBound(buildRandomSlice());
|
||||
opt.setIterateLowerBound(buildRandomSlice());
|
||||
ReadOptions other = new ReadOptions(opt);
|
||||
assertThat(opt.verifyChecksums()).isEqualTo(other.verifyChecksums());
|
||||
assertThat(opt.fillCache()).isEqualTo(other.fillCache());
|
||||
assertThat(Arrays.equals(opt.iterateUpperBound().data(), other.iterateUpperBound().data())).isTrue();
|
||||
assertThat(Arrays.equals(opt.iterateLowerBound().data(), other.iterateLowerBound().data())).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,6 +255,22 @@ public class ReadOptionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failSetIterateLowerBoundUninitialized() {
|
||||
try (final ReadOptions readOptions =
|
||||
setupUninitializedReadOptions(exception)) {
|
||||
readOptions.setIterateLowerBound(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failIterateLowerBoundUninitialized() {
|
||||
try (final ReadOptions readOptions =
|
||||
setupUninitializedReadOptions(exception)) {
|
||||
readOptions.iterateLowerBound();
|
||||
}
|
||||
}
|
||||
|
||||
private ReadOptions setupUninitializedReadOptions(
|
||||
ExpectedException exception) {
|
||||
final ReadOptions readOptions = new ReadOptions();
|
||||
|
Loading…
Reference in New Issue
Block a user