diff --git a/java/rocksjni/options.cc b/java/rocksjni/options.cc index 12f44b5eb..33d42646f 100644 --- a/java/rocksjni/options.cc +++ b/java/rocksjni/options.cc @@ -1547,6 +1547,27 @@ jboolean Java_org_rocksdb_Options_enablePipelinedWrite( return static_cast(opt->enable_pipelined_write); } +/* + * Class: org_rocksdb_Options + * Method: setUnorderedWrite + * Signature: (JZ)V + */ +void Java_org_rocksdb_Options_setUnorderedWrite( + JNIEnv*, jobject, jlong jhandle, jboolean unordered_write) { + reinterpret_cast(jhandle) + ->unordered_write = static_cast(unordered_write); +} + +/* + * Class: org_rocksdb_Options + * Method: unorderedWrite + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_Options_unorderedWrite( + JNIEnv*, jobject, jlong jhandle) { + return reinterpret_cast(jhandle)->unordered_write; +} + /* * Class: org_rocksdb_Options * Method: setAllowConcurrentMemtableWrite @@ -5717,6 +5738,29 @@ jboolean Java_org_rocksdb_DBOptions_enablePipelinedWrite( return static_cast(opt->enable_pipelined_write); } +/* + * Class: org_rocksdb_DBOptions + * Method: setUnorderedWrite + * Signature: (JZ)V + */ +void Java_org_rocksdb_DBOptions_setUnorderedWrite( + JNIEnv*, jobject, jlong jhandle, jboolean junordered_write) { + auto* opt = reinterpret_cast(jhandle); + opt->unordered_write = junordered_write == JNI_TRUE; +} + +/* + * Class: org_rocksdb_DBOptions + * Method: unorderedWrite + * Signature: (J)Z + */ +jboolean Java_org_rocksdb_DBOptions_unorderedWrite( + JNIEnv*, jobject, jlong jhandle) { +auto* opt = reinterpret_cast(jhandle); +return static_cast(opt->unordered_write); +} + + /* * Class: org_rocksdb_DBOptions * Method: setEnableThreadTracking diff --git a/java/src/main/java/org/rocksdb/DBOptions.java b/java/src/main/java/org/rocksdb/DBOptions.java index e2c4c02b3..fc413c76a 100644 --- a/java/src/main/java/org/rocksdb/DBOptions.java +++ b/java/src/main/java/org/rocksdb/DBOptions.java @@ -872,6 +872,18 @@ public class DBOptions extends RocksObject return enablePipelinedWrite(nativeHandle_); } + @Override + public DBOptions setUnorderedWrite(final boolean unorderedWrite) { + setUnorderedWrite(nativeHandle_, unorderedWrite); + return this; + } + + @Override + public boolean unorderedWrite() { + return unorderedWrite(nativeHandle_); + } + + @Override public DBOptions setAllowConcurrentMemtableWrite( final boolean allowConcurrentMemtableWrite) { @@ -1266,6 +1278,9 @@ public class DBOptions extends RocksObject private native void setEnablePipelinedWrite(final long handle, final boolean enablePipelinedWrite); private native boolean enablePipelinedWrite(final long handle); + private native void setUnorderedWrite(final long handle, + final boolean unorderedWrite); + private native boolean unorderedWrite(final long handle); private native void setAllowConcurrentMemtableWrite(long handle, boolean allowConcurrentMemtableWrite); private native boolean allowConcurrentMemtableWrite(long handle); diff --git a/java/src/main/java/org/rocksdb/DBOptionsInterface.java b/java/src/main/java/org/rocksdb/DBOptionsInterface.java index f4217412f..a26449c5d 100644 --- a/java/src/main/java/org/rocksdb/DBOptionsInterface.java +++ b/java/src/main/java/org/rocksdb/DBOptionsInterface.java @@ -1088,6 +1088,44 @@ public interface DBOptionsInterface> { */ boolean enablePipelinedWrite(); + /** + * Setting {@link #unorderedWrite()} to true trades higher write throughput with + * relaxing the immutability guarantee of snapshots. This violates the + * repeatability one expects from ::Get from a snapshot, as well as + * ::MultiGet and Iterator's consistent-point-in-time view property. + * If the application cannot tolerate the relaxed guarantees, it can implement + * its own mechanisms to work around that and yet benefit from the higher + * throughput. Using TransactionDB with WRITE_PREPARED write policy and + * {@link #twoWriteQueues()} true is one way to achieve immutable snapshots despite + * unordered_write. + * + * By default, i.e., when it is false, rocksdb does not advance the sequence + * number for new snapshots unless all the writes with lower sequence numbers + * are already finished. This provides the immutability that we except from + * snapshots. Moreover, since Iterator and MultiGet internally depend on + * snapshots, the snapshot immutability results into Iterator and MultiGet + * offering consistent-point-in-time view. If set to true, although + * Read-Your-Own-Write property is still provided, the snapshot immutability + * property is relaxed: the writes issued after the snapshot is obtained (with + * larger sequence numbers) will be still not visible to the reads from that + * snapshot, however, there still might be pending writes (with lower sequence + * number) that will change the state visible to the snapshot after they are + * landed to the memtable. + * + * @param unorderedWrite true to enabled unordered write + * + * @return the reference to the current options. + */ + T setUnorderedWrite(final boolean unorderedWrite); + + /** + * Returns true if unordered write are enabled. + * See {@link #setUnorderedWrite(boolean)}. + * + * @return true if unordered write are enabled, false otherwise. + */ + boolean unorderedWrite(); + /** * If true, allow multi-writers to update mem tables in parallel. * Only some memtable factorys support concurrent writes; currently it diff --git a/java/src/main/java/org/rocksdb/Options.java b/java/src/main/java/org/rocksdb/Options.java index bb3c87aef..9fce1eda2 100644 --- a/java/src/main/java/org/rocksdb/Options.java +++ b/java/src/main/java/org/rocksdb/Options.java @@ -919,6 +919,17 @@ public class Options extends RocksObject return enablePipelinedWrite(nativeHandle_); } + @Override + public Options setUnorderedWrite(final boolean unorderedWrite) { + setUnorderedWrite(nativeHandle_, unorderedWrite); + return this; + } + + @Override + public boolean unorderedWrite() { + return unorderedWrite(nativeHandle_); + } + @Override public Options setAllowConcurrentMemtableWrite( final boolean allowConcurrentMemtableWrite) { @@ -1886,6 +1897,9 @@ public class Options extends RocksObject private native void setEnablePipelinedWrite(final long handle, final boolean pipelinedWrite); private native boolean enablePipelinedWrite(final long handle); + private native void setUnorderedWrite(final long handle, + final boolean unorderedWrite); + private native boolean unorderedWrite(final long handle); private native void setAllowConcurrentMemtableWrite(long handle, boolean allowConcurrentMemtableWrite); private native boolean allowConcurrentMemtableWrite(long handle); diff --git a/java/src/test/java/org/rocksdb/DBOptionsTest.java b/java/src/test/java/org/rocksdb/DBOptionsTest.java index e6ebc46cd..1731b6c27 100644 --- a/java/src/test/java/org/rocksdb/DBOptionsTest.java +++ b/java/src/test/java/org/rocksdb/DBOptionsTest.java @@ -543,6 +543,15 @@ public class DBOptionsTest { } } + @Test + public void unordredWrite() { + try(final DBOptions opt = new DBOptions()) { + assertThat(opt.unorderedWrite()).isFalse(); + opt.setUnorderedWrite(true); + assertThat(opt.unorderedWrite()).isTrue(); + } + } + @Test public void allowConcurrentMemtableWrite() { try (final DBOptions opt = new DBOptions()) { diff --git a/java/src/test/java/org/rocksdb/OptionsTest.java b/java/src/test/java/org/rocksdb/OptionsTest.java index e27a33d7d..04d362fb1 100644 --- a/java/src/test/java/org/rocksdb/OptionsTest.java +++ b/java/src/test/java/org/rocksdb/OptionsTest.java @@ -762,6 +762,15 @@ public class OptionsTest { } } + @Test + public void unordredWrite() { + try(final Options opt = new Options()) { + assertThat(opt.unorderedWrite()).isFalse(); + opt.setUnorderedWrite(true); + assertThat(opt.unorderedWrite()).isTrue(); + } + } + @Test public void allowConcurrentMemtableWrite() { try (final Options opt = new Options()) {