backupenginejni.cc 9.2 KB

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