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