diff --git a/java/org/rocksdb/BackupableDB.java b/java/org/rocksdb/BackupableDB.java index 2644fec8f..e73df52e0 100644 --- a/java/org/rocksdb/BackupableDB.java +++ b/java/org/rocksdb/BackupableDB.java @@ -92,6 +92,29 @@ public class BackupableDB extends RocksDB { return getBackupInfo(nativeHandle_); } + /** + *

Returns a list of corrupted backup ids. If there + * is no corrupted backup the method will return an + * empty list.

+ * + * @return list of backup ids as Integer. + */ + public List getCorruptedBackups() { + return getCorruptedBackups(nativeHandle_); + } + + /** + *

Will delete all the files we don't need anymore. It will + * do the full scan of the files/ directory and delete all the + * files that are not referenced.

+ * + * @throws RocksDBException thrown if error happens in underlying + * native library. + */ + public void garbageCollect() throws RocksDBException { + garbageCollect(nativeHandle_); + } + /** * Close the BackupableDB instance and release resource. * @@ -126,4 +149,7 @@ public class BackupableDB extends RocksDB { private native void deleteBackup0(long nativeHandle, int backupId) throws RocksDBException; protected native List getBackupInfo(long handle); + private native List getCorruptedBackups(long handle); + private native void garbageCollect(long handle) + throws RocksDBException; } diff --git a/java/org/rocksdb/RestoreBackupableDB.java b/java/org/rocksdb/RestoreBackupableDB.java index ffbc2e011..9c41f4345 100644 --- a/java/org/rocksdb/RestoreBackupableDB.java +++ b/java/org/rocksdb/RestoreBackupableDB.java @@ -101,6 +101,29 @@ public class RestoreBackupableDB extends RocksObject { return getBackupInfo(nativeHandle_); } + /** + *

Returns a list of corrupted backup ids. If there + * is no corrupted backup the method will return an + * empty list.

+ * + * @return list of backup ids as Integer. + */ + public List getCorruptedBackups() { + return getCorruptedBackups(nativeHandle_); + } + + /** + *

Will delete all the files we don't need anymore. It will + * do the full scan of the files/ directory and delete all the + * files that are not referenced.

+ * + * @throws RocksDBException thrown if error happens in underlying + * native library. + */ + public void garbageCollect() throws RocksDBException { + garbageCollect(nativeHandle_); + } + /** * Release the memory allocated for the current instance * in the c++ side. @@ -121,6 +144,9 @@ public class RestoreBackupableDB extends RocksObject { throws RocksDBException; private native void deleteBackup0(long nativeHandle, int backupId) throws RocksDBException; - protected native List getBackupInfo(long handle); + private native List getBackupInfo(long handle); + private native List getCorruptedBackups(long handle); + private native void garbageCollect(long handle) + throws RocksDBException; private native void dispose(long nativeHandle); } diff --git a/java/org/rocksdb/test/BackupableDBTest.java b/java/org/rocksdb/test/BackupableDBTest.java index f24163bd5..0a0b12849 100644 --- a/java/org/rocksdb/test/BackupableDBTest.java +++ b/java/org/rocksdb/test/BackupableDBTest.java @@ -56,6 +56,9 @@ public class BackupableDBTest { isEqualTo(0); bdb.createNewBackup(true); + assertThat(bdb.getCorruptedBackups().size()). + isEqualTo(0); + bdb.garbageCollect(); backupInfos = bdb.getBackupInfos(); assertThat(backupInfos.size()). isEqualTo(1); @@ -102,6 +105,9 @@ public class BackupableDBTest { ropt); // do nothing because there is only one backup rdb.purgeOldBackups(1); + rdb.garbageCollect(); + assertThat(rdb.getCorruptedBackups().size()). + isEqualTo(0); restoreInfos = rdb.getBackupInfos(); assertThat(restoreInfos.size()). isEqualTo(1); diff --git a/java/rocksjni/backupablejni.cc b/java/rocksjni/backupablejni.cc index 4db9f5682..639c73eba 100644 --- a/java/rocksjni/backupablejni.cc +++ b/java/rocksjni/backupablejni.cc @@ -92,6 +92,52 @@ jobject Java_org_rocksdb_BackupableDB_getBackupInfo( backup_infos); } +/* + * Class: org_rocksdb_BackupableDB + * Method: getCorruptedBackups + * Signature: (J)Ljava/util/List; + */ +jobject Java_org_rocksdb_BackupableDB_getCorruptedBackups( + JNIEnv* env, jobject jbdb, jlong jhandle) { + std::vector backup_ids; + reinterpret_cast(jhandle)-> + GetCorruptedBackups(&backup_ids); + + jclass jclazz = env->FindClass("java/util/ArrayList"); + jmethodID mid = rocksdb::ListJni::getArrayListConstructorMethodId( + env, jclazz); + jobject jbackup_id_handle_list = env->NewObject(jclazz, mid, + backup_ids.size()); + // insert in java list + for (std::vector::size_type i = 0; + i != backup_ids.size(); i++) { + // convert BackupID to Integer + jclass jIntClazz = env->FindClass("java/lang/Integer"); + jmethodID midLong = env->GetMethodID(jIntClazz, "", "(I)V"); + jobject obj = env->NewObject(jIntClazz, midLong, + (backup_ids[i])); + // add Integer to List + env->CallBooleanMethod(jbackup_id_handle_list, + rocksdb::ListJni::getListAddMethodId(env), obj); + } + return jbackup_id_handle_list; +} + +/* + * Class: org_rocksdb_BackupableDB + * Method: garbageCollect + * Signature: (J)V + */ +void Java_org_rocksdb_BackupableDB_garbageCollect(JNIEnv* env, + jobject jobj, jlong jhandle) { + auto db = reinterpret_cast(jhandle); + rocksdb::Status s = db->GarbageCollect(); + + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} + /////////////////////////////////////////////////////////////////////////// // BackupDBOptions diff --git a/java/rocksjni/restorejni.cc b/java/rocksjni/restorejni.cc index 4fe813d09..99ffc4256 100644 --- a/java/rocksjni/restorejni.cc +++ b/java/rocksjni/restorejni.cc @@ -145,6 +145,53 @@ jobject Java_org_rocksdb_RestoreBackupableDB_getBackupInfo( backup_infos); } +/* + * Class: org_rocksdb_RestoreBackupableDB + * Method: getCorruptedBackups + * Signature: (J)Ljava/util/List; + */ +jobject Java_org_rocksdb_RestoreBackupableDB_getCorruptedBackups( + JNIEnv* env, jobject jbdb, jlong jhandle) { + std::vector backup_ids; + reinterpret_cast(jhandle)-> + GetCorruptedBackups(&backup_ids); + + jclass jclazz = env->FindClass("java/util/ArrayList"); + jmethodID mid = rocksdb::ListJni::getArrayListConstructorMethodId( + env, jclazz); + jobject jbackup_id_handle_list = env->NewObject(jclazz, mid, + backup_ids.size()); + // insert in java list + for (std::vector::size_type i = 0; + i != backup_ids.size(); i++) { + // convert BackupID to Integer + jclass jIntClazz = env->FindClass("java/lang/Integer"); + jmethodID midLong = env->GetMethodID(jIntClazz, "", "(I)V"); + jobject obj = env->NewObject(jIntClazz, midLong, + (backup_ids[i])); + // add Integer to List + env->CallBooleanMethod(jbackup_id_handle_list, + rocksdb::ListJni::getListAddMethodId(env), obj); + } + return jbackup_id_handle_list; +} + +/* + * Class: org_rocksdb_RestoreBackupableDB + * Method: garbageCollect + * Signature: (J)V + */ +void Java_org_rocksdb_RestoreBackupableDB_garbageCollect( + JNIEnv* env, jobject jobj, jlong jhandle) { + auto db = reinterpret_cast( + jhandle); + rocksdb::Status s = db->GarbageCollect(); + + if (!s.ok()) { + rocksdb::RocksDBExceptionJni::ThrowNew(env, s); + } +} + /* * Class: org_rocksdb_RestoreBackupableDB * Method: dispose