diff --git a/java/rocksjni/rocksjni.cc b/java/rocksjni/rocksjni.cc index 84175913a..5ccda2670 100644 --- a/java/rocksjni/rocksjni.cc +++ b/java/rocksjni/rocksjni.cc @@ -2610,6 +2610,17 @@ jobjectArray Java_org_rocksdb_RocksDB_compactFiles( return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &output_file_names); } +/* + * Class: org_rocksdb_RocksDB + * Method: cancelAllBackgroundWork + * Signature: (JZ)V + */ +void Java_org_rocksdb_RocksDB_cancelAllBackgroundWork( + JNIEnv*, jobject, jlong jdb_handle, jboolean jwait) { + auto* db = reinterpret_cast(jdb_handle); + rocksdb::CancelAllBackgroundWork(db, jwait); +} + /* * Class: org_rocksdb_RocksDB * Method: pauseBackgroundWork diff --git a/java/src/main/java/org/rocksdb/RocksDB.java b/java/src/main/java/org/rocksdb/RocksDB.java index 338324b13..05d9ca201 100644 --- a/java/src/main/java/org/rocksdb/RocksDB.java +++ b/java/src/main/java/org/rocksdb/RocksDB.java @@ -3479,6 +3479,17 @@ public class RocksDB extends RocksObject { compactionJobInfo == null ? 0 : compactionJobInfo.nativeHandle_)); } + /** + * This function will cancel all currently running background processes. + * + * @param wait if true, wait for all background work to be cancelled before + * returning. + * + */ + public void cancelAllBackgroundWork(boolean wait) { + cancelAllBackgroundWork(nativeHandle_, wait); + } + /** * This function will wait until all currently running background processes * finish. After it returns, no background process will be run until @@ -4457,6 +4468,8 @@ public class RocksDB extends RocksObject { final int outputLevel, final int outputPathId, final long compactionJobInfoHandle) throws RocksDBException; + private native void cancelAllBackgroundWork(final long handle, + final boolean wait); private native void pauseBackgroundWork(final long handle) throws RocksDBException; private native void continueBackgroundWork(final long handle) diff --git a/java/src/test/java/org/rocksdb/RocksDBTest.java b/java/src/test/java/org/rocksdb/RocksDBTest.java index b4d96ed43..f6acfaa64 100644 --- a/java/src/test/java/org/rocksdb/RocksDBTest.java +++ b/java/src/test/java/org/rocksdb/RocksDBTest.java @@ -1084,6 +1084,57 @@ public class RocksDBTest { } } + @Test + public void continueBackgroundWorkAfterCancelAllBackgroundWork() throws RocksDBException { + final int KEY_SIZE = 20; + final int VALUE_SIZE = 300; + try (final DBOptions opt = new DBOptions(). + setCreateIfMissing(true). + setCreateMissingColumnFamilies(true); + final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions() + ) { + final List columnFamilyDescriptors = + Arrays.asList( + new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY), + new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts) + ); + + final List columnFamilyHandles = new ArrayList<>(); + // open the database + try (final RocksDB db = RocksDB.open(opt, + dbFolder.getRoot().getAbsolutePath(), + columnFamilyDescriptors, + columnFamilyHandles)) { + try { + db.cancelAllBackgroundWork(true); + try { + db.put(new byte[KEY_SIZE], new byte[VALUE_SIZE]); + db.flush(new FlushOptions().setWaitForFlush(true)); + fail("Expected RocksDBException to be thrown if we attempt to trigger a flush after" + + " all background work is cancelled."); + } catch (RocksDBException ignored) { } + } finally { + for (final ColumnFamilyHandle handle : columnFamilyHandles) { + handle.close(); + } + } + } + } + } + + @Test + public void cancelAllBackgroundWorkTwice() throws RocksDBException { + try (final Options options = new Options().setCreateIfMissing(true); + final RocksDB db = RocksDB.open(options, + dbFolder.getRoot().getAbsolutePath()) + ) { + // Cancel all background work synchronously + db.cancelAllBackgroundWork(true); + // Cancel all background work asynchronously + db.cancelAllBackgroundWork(false); + } + } + @Test public void pauseContinueBackgroundWork() throws RocksDBException { try (final Options options = new Options().setCreateIfMissing(true);