backupenginejni.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // This file implements the "bridge" between Java and C++ and enables
  7. // calling C++ ROCKSDB_NAMESPACE::BackupEngine methods from the Java side.
  8. #include <jni.h>
  9. #include <vector>
  10. #include "include/org_rocksdb_BackupEngine.h"
  11. #include "rocksdb/utilities/backupable_db.h"
  12. #include "rocksjni/portal.h"
  13. /*
  14. * Class: org_rocksdb_BackupEngine
  15. * Method: open
  16. * Signature: (JJ)J
  17. */
  18. jlong Java_org_rocksdb_BackupEngine_open(JNIEnv* env, jclass /*jcls*/,
  19. jlong env_handle,
  20. jlong backupable_db_options_handle) {
  21. auto* rocks_env = reinterpret_cast<ROCKSDB_NAMESPACE::Env*>(env_handle);
  22. auto* backupable_db_options =
  23. reinterpret_cast<ROCKSDB_NAMESPACE::BackupableDBOptions*>(
  24. backupable_db_options_handle);
  25. ROCKSDB_NAMESPACE::BackupEngine* backup_engine;
  26. auto status = ROCKSDB_NAMESPACE::BackupEngine::Open(
  27. rocks_env, *backupable_db_options, &backup_engine);
  28. if (status.ok()) {
  29. return reinterpret_cast<jlong>(backup_engine);
  30. } else {
  31. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  32. return 0;
  33. }
  34. }
  35. /*
  36. * Class: org_rocksdb_BackupEngine
  37. * Method: createNewBackup
  38. * Signature: (JJZ)V
  39. */
  40. void Java_org_rocksdb_BackupEngine_createNewBackup(
  41. JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jlong db_handle,
  42. jboolean jflush_before_backup) {
  43. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  44. auto* backup_engine =
  45. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  46. auto status = backup_engine->CreateNewBackup(
  47. db, static_cast<bool>(jflush_before_backup));
  48. if (status.ok()) {
  49. return;
  50. }
  51. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  52. }
  53. /*
  54. * Class: org_rocksdb_BackupEngine
  55. * Method: createNewBackupWithMetadata
  56. * Signature: (JJLjava/lang/String;Z)V
  57. */
  58. void Java_org_rocksdb_BackupEngine_createNewBackupWithMetadata(
  59. JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jlong db_handle,
  60. jstring japp_metadata, jboolean jflush_before_backup) {
  61. auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
  62. auto* backup_engine =
  63. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  64. jboolean has_exception = JNI_FALSE;
  65. std::string app_metadata = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
  66. env, japp_metadata, &has_exception);
  67. if (has_exception == JNI_TRUE) {
  68. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
  69. env, "Could not copy jstring to std::string");
  70. return;
  71. }
  72. auto status = backup_engine->CreateNewBackupWithMetadata(
  73. db, app_metadata, static_cast<bool>(jflush_before_backup));
  74. if (status.ok()) {
  75. return;
  76. }
  77. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  78. }
  79. /*
  80. * Class: org_rocksdb_BackupEngine
  81. * Method: getBackupInfo
  82. * Signature: (J)Ljava/util/List;
  83. */
  84. jobject Java_org_rocksdb_BackupEngine_getBackupInfo(JNIEnv* env,
  85. jobject /*jbe*/,
  86. jlong jbe_handle) {
  87. auto* backup_engine =
  88. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  89. std::vector<ROCKSDB_NAMESPACE::BackupInfo> backup_infos;
  90. backup_engine->GetBackupInfo(&backup_infos);
  91. return ROCKSDB_NAMESPACE::BackupInfoListJni::getBackupInfo(env, backup_infos);
  92. }
  93. /*
  94. * Class: org_rocksdb_BackupEngine
  95. * Method: getCorruptedBackups
  96. * Signature: (J)[I
  97. */
  98. jintArray Java_org_rocksdb_BackupEngine_getCorruptedBackups(JNIEnv* env,
  99. jobject /*jbe*/,
  100. jlong jbe_handle) {
  101. auto* backup_engine =
  102. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  103. std::vector<ROCKSDB_NAMESPACE::BackupID> backup_ids;
  104. backup_engine->GetCorruptedBackups(&backup_ids);
  105. // store backupids in int array
  106. std::vector<jint> int_backup_ids(backup_ids.begin(), backup_ids.end());
  107. // Store ints in java array
  108. // Its ok to loose precision here (64->32)
  109. jsize ret_backup_ids_size = static_cast<jsize>(backup_ids.size());
  110. jintArray ret_backup_ids = env->NewIntArray(ret_backup_ids_size);
  111. if (ret_backup_ids == nullptr) {
  112. // exception thrown: OutOfMemoryError
  113. return nullptr;
  114. }
  115. env->SetIntArrayRegion(ret_backup_ids, 0, ret_backup_ids_size,
  116. int_backup_ids.data());
  117. return ret_backup_ids;
  118. }
  119. /*
  120. * Class: org_rocksdb_BackupEngine
  121. * Method: garbageCollect
  122. * Signature: (J)V
  123. */
  124. void Java_org_rocksdb_BackupEngine_garbageCollect(JNIEnv* env, jobject /*jbe*/,
  125. jlong jbe_handle) {
  126. auto* backup_engine =
  127. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  128. auto status = backup_engine->GarbageCollect();
  129. if (status.ok()) {
  130. return;
  131. }
  132. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  133. }
  134. /*
  135. * Class: org_rocksdb_BackupEngine
  136. * Method: purgeOldBackups
  137. * Signature: (JI)V
  138. */
  139. void Java_org_rocksdb_BackupEngine_purgeOldBackups(JNIEnv* env, jobject /*jbe*/,
  140. jlong jbe_handle,
  141. jint jnum_backups_to_keep) {
  142. auto* backup_engine =
  143. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  144. auto status = backup_engine->PurgeOldBackups(
  145. static_cast<uint32_t>(jnum_backups_to_keep));
  146. if (status.ok()) {
  147. return;
  148. }
  149. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  150. }
  151. /*
  152. * Class: org_rocksdb_BackupEngine
  153. * Method: deleteBackup
  154. * Signature: (JI)V
  155. */
  156. void Java_org_rocksdb_BackupEngine_deleteBackup(JNIEnv* env, jobject /*jbe*/,
  157. jlong jbe_handle,
  158. jint jbackup_id) {
  159. auto* backup_engine =
  160. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  161. auto status = backup_engine->DeleteBackup(
  162. static_cast<ROCKSDB_NAMESPACE::BackupID>(jbackup_id));
  163. if (status.ok()) {
  164. return;
  165. }
  166. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  167. }
  168. /*
  169. * Class: org_rocksdb_BackupEngine
  170. * Method: restoreDbFromBackup
  171. * Signature: (JILjava/lang/String;Ljava/lang/String;J)V
  172. */
  173. void Java_org_rocksdb_BackupEngine_restoreDbFromBackup(
  174. JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jint jbackup_id,
  175. jstring jdb_dir, jstring jwal_dir, jlong jrestore_options_handle) {
  176. auto* backup_engine =
  177. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  178. const char* db_dir = env->GetStringUTFChars(jdb_dir, nullptr);
  179. if (db_dir == nullptr) {
  180. // exception thrown: OutOfMemoryError
  181. return;
  182. }
  183. const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
  184. if (wal_dir == nullptr) {
  185. // exception thrown: OutOfMemoryError
  186. env->ReleaseStringUTFChars(jdb_dir, db_dir);
  187. return;
  188. }
  189. auto* restore_options = reinterpret_cast<ROCKSDB_NAMESPACE::RestoreOptions*>(
  190. jrestore_options_handle);
  191. auto status = backup_engine->RestoreDBFromBackup(
  192. static_cast<ROCKSDB_NAMESPACE::BackupID>(jbackup_id), db_dir, wal_dir,
  193. *restore_options);
  194. env->ReleaseStringUTFChars(jwal_dir, wal_dir);
  195. env->ReleaseStringUTFChars(jdb_dir, db_dir);
  196. if (status.ok()) {
  197. return;
  198. }
  199. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  200. }
  201. /*
  202. * Class: org_rocksdb_BackupEngine
  203. * Method: restoreDbFromLatestBackup
  204. * Signature: (JLjava/lang/String;Ljava/lang/String;J)V
  205. */
  206. void Java_org_rocksdb_BackupEngine_restoreDbFromLatestBackup(
  207. JNIEnv* env, jobject /*jbe*/, jlong jbe_handle, jstring jdb_dir,
  208. jstring jwal_dir, jlong jrestore_options_handle) {
  209. auto* backup_engine =
  210. reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  211. const char* db_dir = env->GetStringUTFChars(jdb_dir, nullptr);
  212. if (db_dir == nullptr) {
  213. // exception thrown: OutOfMemoryError
  214. return;
  215. }
  216. const char* wal_dir = env->GetStringUTFChars(jwal_dir, nullptr);
  217. if (wal_dir == nullptr) {
  218. // exception thrown: OutOfMemoryError
  219. env->ReleaseStringUTFChars(jdb_dir, db_dir);
  220. return;
  221. }
  222. auto* restore_options = reinterpret_cast<ROCKSDB_NAMESPACE::RestoreOptions*>(
  223. jrestore_options_handle);
  224. auto status = backup_engine->RestoreDBFromLatestBackup(db_dir, wal_dir,
  225. *restore_options);
  226. env->ReleaseStringUTFChars(jwal_dir, wal_dir);
  227. env->ReleaseStringUTFChars(jdb_dir, db_dir);
  228. if (status.ok()) {
  229. return;
  230. }
  231. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, status);
  232. }
  233. /*
  234. * Class: org_rocksdb_BackupEngine
  235. * Method: disposeInternal
  236. * Signature: (J)V
  237. */
  238. void Java_org_rocksdb_BackupEngine_disposeInternal(JNIEnv* /*env*/,
  239. jobject /*jbe*/,
  240. jlong jbe_handle) {
  241. auto* be = reinterpret_cast<ROCKSDB_NAMESPACE::BackupEngine*>(jbe_handle);
  242. assert(be != nullptr);
  243. delete be;
  244. }