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::DB methods from Java side.
8
9 #include <jni.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <algorithm>
13 #include <functional>
14 #include <memory>
15 #include <string>
16 #include <tuple>
17 #include <vector>
18
19 #include "include/org_rocksdb_RocksDB.h"
20 #include "rocksdb/cache.h"
21 #include "rocksdb/convenience.h"
22 #include "rocksdb/db.h"
23 #include "rocksdb/options.h"
24 #include "rocksdb/types.h"
25 #include "rocksjni/portal.h"
26
27 #ifdef min
28 #undef min
29 #endif
30
rocksdb_open_helper(JNIEnv * env,jlong jopt_handle,jstring jdb_path,std::function<ROCKSDB_NAMESPACE::Status (const ROCKSDB_NAMESPACE::Options &,const std::string &,ROCKSDB_NAMESPACE::DB **)> open_fn)31 jlong rocksdb_open_helper(JNIEnv* env, jlong jopt_handle, jstring jdb_path,
32 std::function<ROCKSDB_NAMESPACE::Status(
33 const ROCKSDB_NAMESPACE::Options&,
34 const std::string&, ROCKSDB_NAMESPACE::DB**)>
35 open_fn) {
36 const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
37 if (db_path == nullptr) {
38 // exception thrown: OutOfMemoryError
39 return 0;
40 }
41
42 auto* opt = reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(jopt_handle);
43 ROCKSDB_NAMESPACE::DB* db = nullptr;
44 ROCKSDB_NAMESPACE::Status s = open_fn(*opt, db_path, &db);
45
46 env->ReleaseStringUTFChars(jdb_path, db_path);
47
48 if (s.ok()) {
49 return reinterpret_cast<jlong>(db);
50 } else {
51 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
52 return 0;
53 }
54 }
55
56 /*
57 * Class: org_rocksdb_RocksDB
58 * Method: open
59 * Signature: (JLjava/lang/String;)J
60 */
Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(JNIEnv * env,jclass,jlong jopt_handle,jstring jdb_path)61 jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2(
62 JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) {
63 return rocksdb_open_helper(env, jopt_handle, jdb_path,
64 (ROCKSDB_NAMESPACE::Status(*)(
65 const ROCKSDB_NAMESPACE::Options&,
66 const std::string&, ROCKSDB_NAMESPACE::DB**)) &
67 ROCKSDB_NAMESPACE::DB::Open);
68 }
69
70 /*
71 * Class: org_rocksdb_RocksDB
72 * Method: openROnly
73 * Signature: (JLjava/lang/String;)J
74 */
Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2(JNIEnv * env,jclass,jlong jopt_handle,jstring jdb_path)75 jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2(
76 JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) {
77 return rocksdb_open_helper(
78 env, jopt_handle, jdb_path,
79 [](const ROCKSDB_NAMESPACE::Options& options, const std::string& db_path,
80 ROCKSDB_NAMESPACE::DB** db) {
81 return ROCKSDB_NAMESPACE::DB::OpenForReadOnly(options, db_path, db);
82 });
83 }
84
rocksdb_open_helper(JNIEnv * env,jlong jopt_handle,jstring jdb_path,jobjectArray jcolumn_names,jlongArray jcolumn_options,std::function<ROCKSDB_NAMESPACE::Status (const ROCKSDB_NAMESPACE::DBOptions &,const std::string &,const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> &,std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle * > *,ROCKSDB_NAMESPACE::DB **)> open_fn)85 jlongArray rocksdb_open_helper(
86 JNIEnv* env, jlong jopt_handle, jstring jdb_path,
87 jobjectArray jcolumn_names, jlongArray jcolumn_options,
88 std::function<ROCKSDB_NAMESPACE::Status(
89 const ROCKSDB_NAMESPACE::DBOptions&, const std::string&,
90 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&,
91 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>*,
92 ROCKSDB_NAMESPACE::DB**)>
93 open_fn) {
94 const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
95 if (db_path == nullptr) {
96 // exception thrown: OutOfMemoryError
97 return nullptr;
98 }
99
100 const jsize len_cols = env->GetArrayLength(jcolumn_names);
101 jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr);
102 if (jco == nullptr) {
103 // exception thrown: OutOfMemoryError
104 env->ReleaseStringUTFChars(jdb_path, db_path);
105 return nullptr;
106 }
107
108 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> column_families;
109 jboolean has_exception = JNI_FALSE;
110 ROCKSDB_NAMESPACE::JniUtil::byteStrings<std::string>(
111 env, jcolumn_names,
112 [](const char* str_data, const size_t str_len) {
113 return std::string(str_data, str_len);
114 },
115 [&jco, &column_families](size_t idx, std::string cf_name) {
116 ROCKSDB_NAMESPACE::ColumnFamilyOptions* cf_options =
117 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(jco[idx]);
118 column_families.push_back(
119 ROCKSDB_NAMESPACE::ColumnFamilyDescriptor(cf_name, *cf_options));
120 },
121 &has_exception);
122
123 env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT);
124
125 if (has_exception == JNI_TRUE) {
126 // exception occurred
127 env->ReleaseStringUTFChars(jdb_path, db_path);
128 return nullptr;
129 }
130
131 auto* opt = reinterpret_cast<ROCKSDB_NAMESPACE::DBOptions*>(jopt_handle);
132 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
133 ROCKSDB_NAMESPACE::DB* db = nullptr;
134 ROCKSDB_NAMESPACE::Status s =
135 open_fn(*opt, db_path, column_families, &cf_handles, &db);
136
137 // we have now finished with db_path
138 env->ReleaseStringUTFChars(jdb_path, db_path);
139
140 // check if open operation was successful
141 if (!s.ok()) {
142 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
143 return nullptr;
144 }
145
146 const jsize resultsLen = 1 + len_cols; // db handle + column family handles
147 std::unique_ptr<jlong[]> results =
148 std::unique_ptr<jlong[]>(new jlong[resultsLen]);
149 results[0] = reinterpret_cast<jlong>(db);
150 for (int i = 1; i <= len_cols; i++) {
151 results[i] = reinterpret_cast<jlong>(cf_handles[i - 1]);
152 }
153
154 jlongArray jresults = env->NewLongArray(resultsLen);
155 if (jresults == nullptr) {
156 // exception thrown: OutOfMemoryError
157 return nullptr;
158 }
159
160 env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
161 if (env->ExceptionCheck()) {
162 // exception thrown: ArrayIndexOutOfBoundsException
163 env->DeleteLocalRef(jresults);
164 return nullptr;
165 }
166
167 return jresults;
168 }
169
170 /*
171 * Class: org_rocksdb_RocksDB
172 * Method: openROnly
173 * Signature: (JLjava/lang/String;[[B[J)[J
174 */
Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3J(JNIEnv * env,jclass,jlong jopt_handle,jstring jdb_path,jobjectArray jcolumn_names,jlongArray jcolumn_options)175 jlongArray Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3J(
176 JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
177 jobjectArray jcolumn_names, jlongArray jcolumn_options) {
178 return rocksdb_open_helper(
179 env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
180 [](const ROCKSDB_NAMESPACE::DBOptions& options,
181 const std::string& db_path,
182 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&
183 column_families,
184 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>* handles,
185 ROCKSDB_NAMESPACE::DB** db) {
186 return ROCKSDB_NAMESPACE::DB::OpenForReadOnly(
187 options, db_path, column_families, handles, db);
188 });
189 }
190
191 /*
192 * Class: org_rocksdb_RocksDB
193 * Method: open
194 * Signature: (JLjava/lang/String;[[B[J)[J
195 */
Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J(JNIEnv * env,jclass,jlong jopt_handle,jstring jdb_path,jobjectArray jcolumn_names,jlongArray jcolumn_options)196 jlongArray Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J(
197 JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path,
198 jobjectArray jcolumn_names, jlongArray jcolumn_options) {
199 return rocksdb_open_helper(
200 env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options,
201 (ROCKSDB_NAMESPACE::Status(*)(
202 const ROCKSDB_NAMESPACE::DBOptions&, const std::string&,
203 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor>&,
204 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>*,
205 ROCKSDB_NAMESPACE::DB**)) &
206 ROCKSDB_NAMESPACE::DB::Open);
207 }
208
209 /*
210 * Class: org_rocksdb_RocksDB
211 * Method: disposeInternal
212 * Signature: (J)V
213 */
Java_org_rocksdb_RocksDB_disposeInternal(JNIEnv *,jobject,jlong jhandle)214 void Java_org_rocksdb_RocksDB_disposeInternal(
215 JNIEnv*, jobject, jlong jhandle) {
216 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
217 assert(db != nullptr);
218 delete db;
219 }
220
221 /*
222 * Class: org_rocksdb_RocksDB
223 * Method: closeDatabase
224 * Signature: (J)V
225 */
Java_org_rocksdb_RocksDB_closeDatabase(JNIEnv * env,jclass,jlong jhandle)226 void Java_org_rocksdb_RocksDB_closeDatabase(
227 JNIEnv* env, jclass, jlong jhandle) {
228 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
229 assert(db != nullptr);
230 ROCKSDB_NAMESPACE::Status s = db->Close();
231 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
232 }
233
234 /*
235 * Class: org_rocksdb_RocksDB
236 * Method: listColumnFamilies
237 * Signature: (JLjava/lang/String;)[[B
238 */
Java_org_rocksdb_RocksDB_listColumnFamilies(JNIEnv * env,jclass,jlong jopt_handle,jstring jdb_path)239 jobjectArray Java_org_rocksdb_RocksDB_listColumnFamilies(
240 JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) {
241 std::vector<std::string> column_family_names;
242 const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
243 if (db_path == nullptr) {
244 // exception thrown: OutOfMemoryError
245 return nullptr;
246 }
247
248 auto* opt = reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(jopt_handle);
249 ROCKSDB_NAMESPACE::Status s = ROCKSDB_NAMESPACE::DB::ListColumnFamilies(
250 *opt, db_path, &column_family_names);
251
252 env->ReleaseStringUTFChars(jdb_path, db_path);
253
254 jobjectArray jcolumn_family_names =
255 ROCKSDB_NAMESPACE::JniUtil::stringsBytes(env, column_family_names);
256
257 return jcolumn_family_names;
258 }
259
260 /*
261 * Class: org_rocksdb_RocksDB
262 * Method: createColumnFamily
263 * Signature: (J[BIJ)J
264 */
Java_org_rocksdb_RocksDB_createColumnFamily(JNIEnv * env,jobject,jlong jhandle,jbyteArray jcf_name,jint jcf_name_len,jlong jcf_options_handle)265 jlong Java_org_rocksdb_RocksDB_createColumnFamily(
266 JNIEnv* env, jobject, jlong jhandle, jbyteArray jcf_name,
267 jint jcf_name_len, jlong jcf_options_handle) {
268 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
269 jboolean has_exception = JNI_FALSE;
270 const std::string cf_name =
271 ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
272 env, jcf_name, jcf_name_len,
273 [](const char* str, const size_t len) {
274 return std::string(str, len);
275 },
276 &has_exception);
277 if (has_exception == JNI_TRUE) {
278 // exception occurred
279 return 0;
280 }
281 auto* cf_options = reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(
282 jcf_options_handle);
283 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
284 ROCKSDB_NAMESPACE::Status s =
285 db->CreateColumnFamily(*cf_options, cf_name, &cf_handle);
286 if (!s.ok()) {
287 // error occurred
288 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
289 return 0;
290 }
291 return reinterpret_cast<jlong>(cf_handle);
292 }
293
294 /*
295 * Class: org_rocksdb_RocksDB
296 * Method: createColumnFamilies
297 * Signature: (JJ[[B)[J
298 */
Java_org_rocksdb_RocksDB_createColumnFamilies__JJ_3_3B(JNIEnv * env,jobject,jlong jhandle,jlong jcf_options_handle,jobjectArray jcf_names)299 jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__JJ_3_3B(
300 JNIEnv* env, jobject, jlong jhandle, jlong jcf_options_handle,
301 jobjectArray jcf_names) {
302 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
303 auto* cf_options = reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(
304 jcf_options_handle);
305 jboolean has_exception = JNI_FALSE;
306 std::vector<std::string> cf_names;
307 ROCKSDB_NAMESPACE::JniUtil::byteStrings<std::string>(
308 env, jcf_names,
309 [](const char* str, const size_t len) { return std::string(str, len); },
310 [&cf_names](const size_t, std::string str) { cf_names.push_back(str); },
311 &has_exception);
312 if (has_exception == JNI_TRUE) {
313 // exception occurred
314 return nullptr;
315 }
316
317 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
318 ROCKSDB_NAMESPACE::Status s =
319 db->CreateColumnFamilies(*cf_options, cf_names, &cf_handles);
320 if (!s.ok()) {
321 // error occurred
322 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
323 return nullptr;
324 }
325
326 jlongArray jcf_handles = ROCKSDB_NAMESPACE::JniUtil::toJPointers<
327 ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, cf_handles, &has_exception);
328 if (has_exception == JNI_TRUE) {
329 // exception occurred
330 return nullptr;
331 }
332 return jcf_handles;
333 }
334
335 /*
336 * Class: org_rocksdb_RocksDB
337 * Method: createColumnFamilies
338 * Signature: (J[J[[B)[J
339 */
Java_org_rocksdb_RocksDB_createColumnFamilies__J_3J_3_3B(JNIEnv * env,jobject,jlong jhandle,jlongArray jcf_options_handles,jobjectArray jcf_names)340 jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__J_3J_3_3B(
341 JNIEnv* env, jobject, jlong jhandle, jlongArray jcf_options_handles,
342 jobjectArray jcf_names) {
343 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jhandle);
344 const jsize jlen = env->GetArrayLength(jcf_options_handles);
345 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> cf_descriptors;
346 cf_descriptors.reserve(jlen);
347
348 jboolean jcf_options_handles_is_copy = JNI_FALSE;
349 jlong *jcf_options_handles_elems = env->GetLongArrayElements(jcf_options_handles, &jcf_options_handles_is_copy);
350 if(jcf_options_handles_elems == nullptr) {
351 // exception thrown: OutOfMemoryError
352 return nullptr;
353 }
354
355 // extract the column family descriptors
356 jboolean has_exception = JNI_FALSE;
357 for (jsize i = 0; i < jlen; i++) {
358 auto* cf_options =
359 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(
360 jcf_options_handles_elems[i]);
361 jbyteArray jcf_name = static_cast<jbyteArray>(
362 env->GetObjectArrayElement(jcf_names, i));
363 if (env->ExceptionCheck()) {
364 // exception thrown: ArrayIndexOutOfBoundsException
365 env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT);
366 return nullptr;
367 }
368 const std::string cf_name =
369 ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
370 env, jcf_name,
371 [](const char* str, const size_t len) {
372 return std::string(str, len);
373 },
374 &has_exception);
375 if (has_exception == JNI_TRUE) {
376 // exception occurred
377 env->DeleteLocalRef(jcf_name);
378 env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT);
379 return nullptr;
380 }
381
382 cf_descriptors.push_back(
383 ROCKSDB_NAMESPACE::ColumnFamilyDescriptor(cf_name, *cf_options));
384
385 env->DeleteLocalRef(jcf_name);
386 }
387
388 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
389 ROCKSDB_NAMESPACE::Status s =
390 db->CreateColumnFamilies(cf_descriptors, &cf_handles);
391
392 env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT);
393
394 if (!s.ok()) {
395 // error occurred
396 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
397 return nullptr;
398 }
399
400 jlongArray jcf_handles = ROCKSDB_NAMESPACE::JniUtil::toJPointers<
401 ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, cf_handles, &has_exception);
402 if (has_exception == JNI_TRUE) {
403 // exception occurred
404 return nullptr;
405 }
406 return jcf_handles;
407 }
408
409 /*
410 * Class: org_rocksdb_RocksDB
411 * Method: dropColumnFamily
412 * Signature: (JJ)V;
413 */
Java_org_rocksdb_RocksDB_dropColumnFamily(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle)414 void Java_org_rocksdb_RocksDB_dropColumnFamily(
415 JNIEnv* env, jobject, jlong jdb_handle,
416 jlong jcf_handle) {
417 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
418 auto* cf_handle =
419 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
420 ROCKSDB_NAMESPACE::Status s = db_handle->DropColumnFamily(cf_handle);
421 if (!s.ok()) {
422 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
423 }
424 }
425
426 /*
427 * Class: org_rocksdb_RocksDB
428 * Method: dropColumnFamilies
429 * Signature: (J[J)V
430 */
Java_org_rocksdb_RocksDB_dropColumnFamilies(JNIEnv * env,jobject,jlong jdb_handle,jlongArray jcolumn_family_handles)431 void Java_org_rocksdb_RocksDB_dropColumnFamilies(
432 JNIEnv* env, jobject, jlong jdb_handle,
433 jlongArray jcolumn_family_handles) {
434 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
435
436 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
437 if (jcolumn_family_handles != nullptr) {
438 const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
439
440 jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
441 if (jcfh == nullptr) {
442 // exception thrown: OutOfMemoryError
443 return;
444 }
445
446 for (jsize i = 0; i < len_cols; i++) {
447 auto* cf_handle =
448 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcfh[i]);
449 cf_handles.push_back(cf_handle);
450 }
451 env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
452 }
453
454 ROCKSDB_NAMESPACE::Status s = db_handle->DropColumnFamilies(cf_handles);
455 if (!s.ok()) {
456 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
457 }
458 }
459
460 //////////////////////////////////////////////////////////////////////////////
461 // ROCKSDB_NAMESPACE::DB::Put
462
463 /**
464 * @return true if the put succeeded, false if a Java Exception was thrown
465 */
rocksdb_put_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::WriteOptions & write_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * cf_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)466 bool rocksdb_put_helper(JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
467 const ROCKSDB_NAMESPACE::WriteOptions& write_options,
468 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle,
469 jbyteArray jkey, jint jkey_off, jint jkey_len,
470 jbyteArray jval, jint jval_off, jint jval_len) {
471 jbyte* key = new jbyte[jkey_len];
472 env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
473 if (env->ExceptionCheck()) {
474 // exception thrown: ArrayIndexOutOfBoundsException
475 delete[] key;
476 return false;
477 }
478
479 jbyte* value = new jbyte[jval_len];
480 env->GetByteArrayRegion(jval, jval_off, jval_len, value);
481 if (env->ExceptionCheck()) {
482 // exception thrown: ArrayIndexOutOfBoundsException
483 delete[] value;
484 delete[] key;
485 return false;
486 }
487
488 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
489 ROCKSDB_NAMESPACE::Slice value_slice(reinterpret_cast<char*>(value),
490 jval_len);
491
492 ROCKSDB_NAMESPACE::Status s;
493 if (cf_handle != nullptr) {
494 s = db->Put(write_options, cf_handle, key_slice, value_slice);
495 } else {
496 // backwards compatibility
497 s = db->Put(write_options, key_slice, value_slice);
498 }
499
500 // cleanup
501 delete[] value;
502 delete[] key;
503
504 if (s.ok()) {
505 return true;
506 } else {
507 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
508 return false;
509 }
510 }
511
512 /*
513 * Class: org_rocksdb_RocksDB
514 * Method: put
515 * Signature: (J[BII[BII)V
516 */
Java_org_rocksdb_RocksDB_put__J_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)517 void Java_org_rocksdb_RocksDB_put__J_3BII_3BII(
518 JNIEnv* env, jobject, jlong jdb_handle,
519 jbyteArray jkey, jint jkey_off, jint jkey_len,
520 jbyteArray jval, jint jval_off, jint jval_len) {
521 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
522 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
523 ROCKSDB_NAMESPACE::WriteOptions();
524 rocksdb_put_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
525 jkey_len, jval, jval_off, jval_len);
526 }
527
528 /*
529 * Class: org_rocksdb_RocksDB
530 * Method: put
531 * Signature: (J[BII[BIIJ)V
532 */
Java_org_rocksdb_RocksDB_put__J_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,jlong jcf_handle)533 void Java_org_rocksdb_RocksDB_put__J_3BII_3BIIJ(
534 JNIEnv* env, jobject, jlong jdb_handle,
535 jbyteArray jkey, jint jkey_off, jint jkey_len,
536 jbyteArray jval, jint jval_off, jint jval_len,
537 jlong jcf_handle) {
538 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
539 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
540 ROCKSDB_NAMESPACE::WriteOptions();
541 auto* cf_handle =
542 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
543 if (cf_handle != nullptr) {
544 rocksdb_put_helper(env, db, default_write_options, cf_handle, jkey,
545 jkey_off, jkey_len, jval, jval_off, jval_len);
546 } else {
547 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
548 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
549 "Invalid ColumnFamilyHandle."));
550 }
551 }
552
553 /*
554 * Class: org_rocksdb_RocksDB
555 * Method: put
556 * Signature: (JJ[BII[BII)V
557 */
Java_org_rocksdb_RocksDB_put__JJ_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)558 void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BII(
559 JNIEnv* env, jobject, jlong jdb_handle,
560 jlong jwrite_options_handle,
561 jbyteArray jkey, jint jkey_off, jint jkey_len,
562 jbyteArray jval, jint jval_off, jint jval_len) {
563 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
564 auto* write_options =
565 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
566 rocksdb_put_helper(env, db, *write_options, nullptr, jkey, jkey_off, jkey_len,
567 jval, jval_off, jval_len);
568 }
569
570 /*
571 * Class: org_rocksdb_RocksDB
572 * Method: put
573 * Signature: (JJ[BII[BIIJ)V
574 */
Java_org_rocksdb_RocksDB_put__JJ_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,jlong jcf_handle)575 void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BIIJ(
576 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle,
577 jbyteArray jkey, jint jkey_off, jint jkey_len,
578 jbyteArray jval, jint jval_off, jint jval_len,
579 jlong jcf_handle) {
580 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
581 auto* write_options =
582 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
583 auto* cf_handle =
584 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
585 if (cf_handle != nullptr) {
586 rocksdb_put_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
587 jkey_len, jval, jval_off, jval_len);
588 } else {
589 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
590 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
591 "Invalid ColumnFamilyHandle."));
592 }
593 }
594
595 /*
596 * Class: org_rocksdb_RocksDB
597 * Method: putDirect
598 * Signature: (JJLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IIJ)V
599 */
Java_org_rocksdb_RocksDB_putDirect(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jobject jkey,jint jkey_off,jint jkey_len,jobject jval,jint jval_off,jint jval_len,jlong jcf_handle)600 void Java_org_rocksdb_RocksDB_putDirect(
601 JNIEnv* env, jobject /*jdb*/, jlong jdb_handle, jlong jwrite_options_handle,
602 jobject jkey, jint jkey_off, jint jkey_len, jobject jval, jint jval_off,
603 jint jval_len, jlong jcf_handle) {
604 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
605 auto* write_options =
606 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
607 auto* cf_handle =
608 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
609 auto put = [&env, &db, &cf_handle, &write_options](
610 ROCKSDB_NAMESPACE::Slice& key,
611 ROCKSDB_NAMESPACE::Slice& value) {
612 ROCKSDB_NAMESPACE::Status s;
613 if (cf_handle == nullptr) {
614 s = db->Put(*write_options, key, value);
615 } else {
616 s = db->Put(*write_options, cf_handle, key, value);
617 }
618 if (s.ok()) {
619 return;
620 }
621 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
622 };
623 ROCKSDB_NAMESPACE::JniUtil::kv_op_direct(put, env, jkey, jkey_off, jkey_len,
624 jval, jval_off, jval_len);
625 }
626
627 //////////////////////////////////////////////////////////////////////////////
628 // ROCKSDB_NAMESPACE::DB::Delete()
629
630 /**
631 * @return true if the delete succeeded, false if a Java Exception was thrown
632 */
rocksdb_delete_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::WriteOptions & write_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * cf_handle,jbyteArray jkey,jint jkey_off,jint jkey_len)633 bool rocksdb_delete_helper(JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
634 const ROCKSDB_NAMESPACE::WriteOptions& write_options,
635 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle,
636 jbyteArray jkey, jint jkey_off, jint jkey_len) {
637 jbyte* key = new jbyte[jkey_len];
638 env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
639 if (env->ExceptionCheck()) {
640 // exception thrown: ArrayIndexOutOfBoundsException
641 delete[] key;
642 return false;
643 }
644 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
645
646 ROCKSDB_NAMESPACE::Status s;
647 if (cf_handle != nullptr) {
648 s = db->Delete(write_options, cf_handle, key_slice);
649 } else {
650 // backwards compatibility
651 s = db->Delete(write_options, key_slice);
652 }
653
654 // cleanup
655 delete[] key;
656
657 if (s.ok()) {
658 return true;
659 }
660
661 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
662 return false;
663 }
664
665 /*
666 * Class: org_rocksdb_RocksDB
667 * Method: delete
668 * Signature: (J[BII)V
669 */
Java_org_rocksdb_RocksDB_delete__J_3BII(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len)670 void Java_org_rocksdb_RocksDB_delete__J_3BII(
671 JNIEnv* env, jobject, jlong jdb_handle,
672 jbyteArray jkey, jint jkey_off, jint jkey_len) {
673 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
674 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
675 ROCKSDB_NAMESPACE::WriteOptions();
676 rocksdb_delete_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
677 jkey_len);
678 }
679
680 /*
681 * Class: org_rocksdb_RocksDB
682 * Method: delete
683 * Signature: (J[BIIJ)V
684 */
Java_org_rocksdb_RocksDB_delete__J_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jlong jcf_handle)685 void Java_org_rocksdb_RocksDB_delete__J_3BIIJ(
686 JNIEnv* env, jobject, jlong jdb_handle,
687 jbyteArray jkey, jint jkey_off, jint jkey_len,
688 jlong jcf_handle) {
689 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
690 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
691 ROCKSDB_NAMESPACE::WriteOptions();
692 auto* cf_handle =
693 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
694 if (cf_handle != nullptr) {
695 rocksdb_delete_helper(env, db, default_write_options, cf_handle, jkey,
696 jkey_off, jkey_len);
697 } else {
698 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
699 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
700 "Invalid ColumnFamilyHandle."));
701 }
702 }
703
704 /*
705 * Class: org_rocksdb_RocksDB
706 * Method: delete
707 * Signature: (JJ[BII)V
708 */
Java_org_rocksdb_RocksDB_delete__JJ_3BII(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jbyteArray jkey,jint jkey_off,jint jkey_len)709 void Java_org_rocksdb_RocksDB_delete__JJ_3BII(
710 JNIEnv* env, jobject,
711 jlong jdb_handle,
712 jlong jwrite_options,
713 jbyteArray jkey, jint jkey_off, jint jkey_len) {
714 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
715 auto* write_options =
716 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
717 rocksdb_delete_helper(env, db, *write_options, nullptr, jkey, jkey_off,
718 jkey_len);
719 }
720
721 /*
722 * Class: org_rocksdb_RocksDB
723 * Method: delete
724 * Signature: (JJ[BIIJ)V
725 */
Java_org_rocksdb_RocksDB_delete__JJ_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jbyteArray jkey,jint jkey_off,jint jkey_len,jlong jcf_handle)726 void Java_org_rocksdb_RocksDB_delete__JJ_3BIIJ(
727 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
728 jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
729 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
730 auto* write_options =
731 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
732 auto* cf_handle =
733 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
734 if (cf_handle != nullptr) {
735 rocksdb_delete_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
736 jkey_len);
737 } else {
738 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
739 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
740 "Invalid ColumnFamilyHandle."));
741 }
742 }
743
744 //////////////////////////////////////////////////////////////////////////////
745 // ROCKSDB_NAMESPACE::DB::SingleDelete()
746 /**
747 * @return true if the single delete succeeded, false if a Java Exception
748 * was thrown
749 */
rocksdb_single_delete_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::WriteOptions & write_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * cf_handle,jbyteArray jkey,jint jkey_len)750 bool rocksdb_single_delete_helper(
751 JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
752 const ROCKSDB_NAMESPACE::WriteOptions& write_options,
753 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle, jbyteArray jkey,
754 jint jkey_len) {
755 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
756 if (key == nullptr) {
757 // exception thrown: OutOfMemoryError
758 return false;
759 }
760 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
761
762 ROCKSDB_NAMESPACE::Status s;
763 if (cf_handle != nullptr) {
764 s = db->SingleDelete(write_options, cf_handle, key_slice);
765 } else {
766 // backwards compatibility
767 s = db->SingleDelete(write_options, key_slice);
768 }
769
770 // trigger java unref on key and value.
771 // by passing JNI_ABORT, it will simply release the reference without
772 // copying the result back to the java byte array.
773 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
774
775 if (s.ok()) {
776 return true;
777 }
778
779 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
780 return false;
781 }
782
783 /*
784 * Class: org_rocksdb_RocksDB
785 * Method: singleDelete
786 * Signature: (J[BI)V
787 */
Java_org_rocksdb_RocksDB_singleDelete__J_3BI(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_len)788 void Java_org_rocksdb_RocksDB_singleDelete__J_3BI(
789 JNIEnv* env, jobject,
790 jlong jdb_handle,
791 jbyteArray jkey,
792 jint jkey_len) {
793 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
794 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
795 ROCKSDB_NAMESPACE::WriteOptions();
796 rocksdb_single_delete_helper(env, db, default_write_options, nullptr,
797 jkey, jkey_len);
798 }
799
800 /*
801 * Class: org_rocksdb_RocksDB
802 * Method: singleDelete
803 * Signature: (J[BIJ)V
804 */
Java_org_rocksdb_RocksDB_singleDelete__J_3BIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_len,jlong jcf_handle)805 void Java_org_rocksdb_RocksDB_singleDelete__J_3BIJ(
806 JNIEnv* env, jobject, jlong jdb_handle,
807 jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
808 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
809 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
810 ROCKSDB_NAMESPACE::WriteOptions();
811 auto* cf_handle =
812 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
813 if (cf_handle != nullptr) {
814 rocksdb_single_delete_helper(env, db, default_write_options, cf_handle,
815 jkey, jkey_len);
816 } else {
817 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
818 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
819 "Invalid ColumnFamilyHandle."));
820 }
821 }
822
823 /*
824 * Class: org_rocksdb_RocksDB
825 * Method: singleDelete
826 * Signature: (JJ[BIJ)V
827 */
Java_org_rocksdb_RocksDB_singleDelete__JJ_3BI(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jbyteArray jkey,jint jkey_len)828 void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BI(
829 JNIEnv* env, jobject, jlong jdb_handle,
830 jlong jwrite_options,
831 jbyteArray jkey,
832 jint jkey_len) {
833 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
834 auto* write_options =
835 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
836 rocksdb_single_delete_helper(env, db, *write_options, nullptr, jkey,
837 jkey_len);
838 }
839
840 /*
841 * Class: org_rocksdb_RocksDB
842 * Method: singleDelete
843 * Signature: (JJ[BIJ)V
844 */
Java_org_rocksdb_RocksDB_singleDelete__JJ_3BIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jbyteArray jkey,jint jkey_len,jlong jcf_handle)845 void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BIJ(
846 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
847 jbyteArray jkey, jint jkey_len, jlong jcf_handle) {
848 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
849 auto* write_options =
850 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
851 auto* cf_handle =
852 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
853 if (cf_handle != nullptr) {
854 rocksdb_single_delete_helper(env, db, *write_options, cf_handle, jkey,
855 jkey_len);
856 } else {
857 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
858 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
859 "Invalid ColumnFamilyHandle."));
860 }
861 }
862
863 //////////////////////////////////////////////////////////////////////////////
864 // ROCKSDB_NAMESPACE::DB::DeleteRange()
865 /**
866 * @return true if the delete range succeeded, false if a Java Exception
867 * was thrown
868 */
rocksdb_delete_range_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::WriteOptions & write_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * cf_handle,jbyteArray jbegin_key,jint jbegin_key_off,jint jbegin_key_len,jbyteArray jend_key,jint jend_key_off,jint jend_key_len)869 bool rocksdb_delete_range_helper(
870 JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
871 const ROCKSDB_NAMESPACE::WriteOptions& write_options,
872 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle, jbyteArray jbegin_key,
873 jint jbegin_key_off, jint jbegin_key_len, jbyteArray jend_key,
874 jint jend_key_off, jint jend_key_len) {
875 jbyte* begin_key = new jbyte[jbegin_key_len];
876 env->GetByteArrayRegion(jbegin_key, jbegin_key_off, jbegin_key_len,
877 begin_key);
878 if (env->ExceptionCheck()) {
879 // exception thrown: ArrayIndexOutOfBoundsException
880 delete[] begin_key;
881 return false;
882 }
883 ROCKSDB_NAMESPACE::Slice begin_key_slice(reinterpret_cast<char*>(begin_key),
884 jbegin_key_len);
885
886 jbyte* end_key = new jbyte[jend_key_len];
887 env->GetByteArrayRegion(jend_key, jend_key_off, jend_key_len, end_key);
888 if (env->ExceptionCheck()) {
889 // exception thrown: ArrayIndexOutOfBoundsException
890 delete[] begin_key;
891 delete[] end_key;
892 return false;
893 }
894 ROCKSDB_NAMESPACE::Slice end_key_slice(reinterpret_cast<char*>(end_key),
895 jend_key_len);
896
897 ROCKSDB_NAMESPACE::Status s =
898 db->DeleteRange(write_options, cf_handle, begin_key_slice, end_key_slice);
899
900 // cleanup
901 delete[] begin_key;
902 delete[] end_key;
903
904 if (s.ok()) {
905 return true;
906 }
907
908 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
909 return false;
910 }
911
912 /*
913 * Class: org_rocksdb_RocksDB
914 * Method: deleteRange
915 * Signature: (J[BII[BII)V
916 */
Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jbegin_key,jint jbegin_key_off,jint jbegin_key_len,jbyteArray jend_key,jint jend_key_off,jint jend_key_len)917 void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BII(
918 JNIEnv* env, jobject, jlong jdb_handle,
919 jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
920 jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
921 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
922 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
923 ROCKSDB_NAMESPACE::WriteOptions();
924 rocksdb_delete_range_helper(env, db, default_write_options, nullptr,
925 jbegin_key, jbegin_key_off, jbegin_key_len,
926 jend_key, jend_key_off, jend_key_len);
927 }
928
rocksdb_get_helper_direct(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::ReadOptions & read_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * column_family_handle,jobject jkey,jint jkey_off,jint jkey_len,jobject jval,jint jval_off,jint jval_len,bool * has_exception)929 jint rocksdb_get_helper_direct(
930 JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
931 const ROCKSDB_NAMESPACE::ReadOptions& read_options,
932 ROCKSDB_NAMESPACE::ColumnFamilyHandle* column_family_handle, jobject jkey,
933 jint jkey_off, jint jkey_len, jobject jval, jint jval_off, jint jval_len,
934 bool* has_exception) {
935 static const int kNotFound = -1;
936 static const int kStatusError = -2;
937 static const int kArgumentError = -3;
938
939 char* key = reinterpret_cast<char*>(env->GetDirectBufferAddress(jkey));
940 if (key == nullptr) {
941 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
942 env,
943 "Invalid key argument (argument is not a valid direct ByteBuffer)");
944 *has_exception = true;
945 return kArgumentError;
946 }
947 if (env->GetDirectBufferCapacity(jkey) < (jkey_off + jkey_len)) {
948 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
949 env,
950 "Invalid key argument. Capacity is less than requested region (offset "
951 "+ length).");
952 *has_exception = true;
953 return kArgumentError;
954 }
955
956 char* value = reinterpret_cast<char*>(env->GetDirectBufferAddress(jval));
957 if (value == nullptr) {
958 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
959 env,
960 "Invalid value argument (argument is not a valid direct ByteBuffer)");
961 *has_exception = true;
962 return kArgumentError;
963 }
964
965 if (env->GetDirectBufferCapacity(jval) < (jval_off + jval_len)) {
966 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
967 env,
968 "Invalid value argument. Capacity is less than requested region "
969 "(offset + length).");
970 *has_exception = true;
971 return kArgumentError;
972 }
973
974 key += jkey_off;
975 value += jval_off;
976
977 ROCKSDB_NAMESPACE::Slice key_slice(key, jkey_len);
978
979 // TODO(yhchiang): we might save one memory allocation here by adding
980 // a DB::Get() function which takes preallocated jbyte* as input.
981 std::string cvalue;
982 ROCKSDB_NAMESPACE::Status s;
983 if (column_family_handle != nullptr) {
984 s = db->Get(read_options, column_family_handle, key_slice, &cvalue);
985 } else {
986 // backwards compatibility
987 s = db->Get(read_options, key_slice, &cvalue);
988 }
989
990 if (s.IsNotFound()) {
991 *has_exception = false;
992 return kNotFound;
993 } else if (!s.ok()) {
994 *has_exception = true;
995 // Here since we are throwing a Java exception from c++ side.
996 // As a result, c++ does not know calling this function will in fact
997 // throwing an exception. As a result, the execution flow will
998 // not stop here, and codes after this throw will still be
999 // executed.
1000 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1001
1002 // Return a dummy const value to avoid compilation error, although
1003 // java side might not have a chance to get the return value :)
1004 return kStatusError;
1005 }
1006
1007 const jint cvalue_len = static_cast<jint>(cvalue.size());
1008 const jint length = std::min(jval_len, cvalue_len);
1009
1010 memcpy(value, cvalue.c_str(), length);
1011
1012 *has_exception = false;
1013 return cvalue_len;
1014 }
1015
1016 /*
1017 * Class: org_rocksdb_RocksDB
1018 * Method: deleteRange
1019 * Signature: (J[BII[BIIJ)V
1020 */
Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jbegin_key,jint jbegin_key_off,jint jbegin_key_len,jbyteArray jend_key,jint jend_key_off,jint jend_key_len,jlong jcf_handle)1021 void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BIIJ(
1022 JNIEnv* env, jobject, jlong jdb_handle,
1023 jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
1024 jbyteArray jend_key, jint jend_key_off, jint jend_key_len,
1025 jlong jcf_handle) {
1026 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1027 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
1028 ROCKSDB_NAMESPACE::WriteOptions();
1029 auto* cf_handle =
1030 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1031 if (cf_handle != nullptr) {
1032 rocksdb_delete_range_helper(env, db, default_write_options, cf_handle,
1033 jbegin_key, jbegin_key_off, jbegin_key_len,
1034 jend_key, jend_key_off, jend_key_len);
1035 } else {
1036 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1037 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1038 "Invalid ColumnFamilyHandle."));
1039 }
1040 }
1041
1042 /*
1043 * Class: org_rocksdb_RocksDB
1044 * Method: deleteRange
1045 * Signature: (JJ[BII[BII)V
1046 */
Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jbyteArray jbegin_key,jint jbegin_key_off,jint jbegin_key_len,jbyteArray jend_key,jint jend_key_off,jint jend_key_len)1047 void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BII(
1048 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
1049 jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
1050 jbyteArray jend_key, jint jend_key_off, jint jend_key_len) {
1051 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1052 auto* write_options =
1053 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
1054 rocksdb_delete_range_helper(env, db, *write_options, nullptr, jbegin_key,
1055 jbegin_key_off, jbegin_key_len, jend_key,
1056 jend_key_off, jend_key_len);
1057 }
1058
1059 /*
1060 * Class: org_rocksdb_RocksDB
1061 * Method: deleteRange
1062 * Signature: (JJ[BII[BIIJ)V
1063 */
Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jbyteArray jbegin_key,jint jbegin_key_off,jint jbegin_key_len,jbyteArray jend_key,jint jend_key_off,jint jend_key_len,jlong jcf_handle)1064 void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BIIJ(
1065 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options,
1066 jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len,
1067 jbyteArray jend_key, jint jend_key_off, jint jend_key_len,
1068 jlong jcf_handle) {
1069 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1070 auto* write_options =
1071 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
1072 auto* cf_handle =
1073 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1074 if (cf_handle != nullptr) {
1075 rocksdb_delete_range_helper(env, db, *write_options, cf_handle,
1076 jbegin_key, jbegin_key_off, jbegin_key_len,
1077 jend_key, jend_key_off, jend_key_len);
1078 } else {
1079 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1080 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1081 "Invalid ColumnFamilyHandle."));
1082 }
1083 }
1084
1085 /*
1086 * Class: org_rocksdb_RocksDB
1087 * Method: getDirect
1088 * Signature: (JJLjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IIJ)I
1089 */
Java_org_rocksdb_RocksDB_getDirect(JNIEnv * env,jobject,jlong jdb_handle,jlong jropt_handle,jobject jkey,jint jkey_off,jint jkey_len,jobject jval,jint jval_off,jint jval_len,jlong jcf_handle)1090 jint Java_org_rocksdb_RocksDB_getDirect(JNIEnv* env, jobject /*jdb*/,
1091 jlong jdb_handle, jlong jropt_handle,
1092 jobject jkey, jint jkey_off,
1093 jint jkey_len, jobject jval,
1094 jint jval_off, jint jval_len,
1095 jlong jcf_handle) {
1096 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1097 auto* ro_opt =
1098 reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle);
1099 auto* cf_handle =
1100 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1101 bool has_exception = false;
1102 return rocksdb_get_helper_direct(
1103 env, db_handle,
1104 ro_opt == nullptr ? ROCKSDB_NAMESPACE::ReadOptions() : *ro_opt, cf_handle,
1105 jkey, jkey_off, jkey_len, jval, jval_off, jval_len, &has_exception);
1106 }
1107
1108 //////////////////////////////////////////////////////////////////////////////
1109 // ROCKSDB_NAMESPACE::DB::Merge
1110
1111 /**
1112 * @return true if the merge succeeded, false if a Java Exception was thrown
1113 */
rocksdb_merge_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::WriteOptions & write_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * cf_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)1114 bool rocksdb_merge_helper(JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
1115 const ROCKSDB_NAMESPACE::WriteOptions& write_options,
1116 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle,
1117 jbyteArray jkey, jint jkey_off, jint jkey_len,
1118 jbyteArray jval, jint jval_off, jint jval_len) {
1119 jbyte* key = new jbyte[jkey_len];
1120 env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
1121 if (env->ExceptionCheck()) {
1122 // exception thrown: ArrayIndexOutOfBoundsException
1123 delete[] key;
1124 return false;
1125 }
1126 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
1127
1128 jbyte* value = new jbyte[jval_len];
1129 env->GetByteArrayRegion(jval, jval_off, jval_len, value);
1130 if (env->ExceptionCheck()) {
1131 // exception thrown: ArrayIndexOutOfBoundsException
1132 delete[] value;
1133 delete[] key;
1134 return false;
1135 }
1136 ROCKSDB_NAMESPACE::Slice value_slice(reinterpret_cast<char*>(value),
1137 jval_len);
1138
1139 ROCKSDB_NAMESPACE::Status s;
1140 if (cf_handle != nullptr) {
1141 s = db->Merge(write_options, cf_handle, key_slice, value_slice);
1142 } else {
1143 s = db->Merge(write_options, key_slice, value_slice);
1144 }
1145
1146 // cleanup
1147 delete[] value;
1148 delete[] key;
1149
1150 if (s.ok()) {
1151 return true;
1152 }
1153
1154 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1155 return false;
1156 }
1157
1158 /*
1159 * Class: org_rocksdb_RocksDB
1160 * Method: merge
1161 * Signature: (J[BII[BII)V
1162 */
Java_org_rocksdb_RocksDB_merge__J_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)1163 void Java_org_rocksdb_RocksDB_merge__J_3BII_3BII(
1164 JNIEnv* env, jobject, jlong jdb_handle,
1165 jbyteArray jkey, jint jkey_off, jint jkey_len,
1166 jbyteArray jval, jint jval_off, jint jval_len) {
1167 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1168 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
1169 ROCKSDB_NAMESPACE::WriteOptions();
1170 rocksdb_merge_helper(env, db, default_write_options, nullptr, jkey, jkey_off,
1171 jkey_len, jval, jval_off, jval_len);
1172 }
1173
1174 /*
1175 * Class: org_rocksdb_RocksDB
1176 * Method: merge
1177 * Signature: (J[BII[BIIJ)V
1178 */
Java_org_rocksdb_RocksDB_merge__J_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,jlong jcf_handle)1179 void Java_org_rocksdb_RocksDB_merge__J_3BII_3BIIJ(
1180 JNIEnv* env, jobject, jlong jdb_handle,
1181 jbyteArray jkey, jint jkey_off, jint jkey_len,
1182 jbyteArray jval, jint jval_off, jint jval_len,
1183 jlong jcf_handle) {
1184 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1185 static const ROCKSDB_NAMESPACE::WriteOptions default_write_options =
1186 ROCKSDB_NAMESPACE::WriteOptions();
1187 auto* cf_handle =
1188 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1189 if (cf_handle != nullptr) {
1190 rocksdb_merge_helper(env, db, default_write_options, cf_handle, jkey,
1191 jkey_off, jkey_len, jval, jval_off, jval_len);
1192 } else {
1193 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1194 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1195 "Invalid ColumnFamilyHandle."));
1196 }
1197 }
1198
1199 /*
1200 * Class: org_rocksdb_RocksDB
1201 * Method: merge
1202 * Signature: (JJ[BII[BII)V
1203 */
Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)1204 void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BII(
1205 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle,
1206 jbyteArray jkey, jint jkey_off, jint jkey_len,
1207 jbyteArray jval, jint jval_off, jint jval_len) {
1208 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1209 auto* write_options =
1210 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
1211 rocksdb_merge_helper(env, db, *write_options, nullptr, jkey, jkey_off,
1212 jkey_len, jval, jval_off, jval_len);
1213 }
1214
1215 /*
1216 * Class: org_rocksdb_RocksDB
1217 * Method: merge
1218 * Signature: (JJ[BII[BIIJ)V
1219 */
Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,jlong jcf_handle)1220 void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BIIJ(
1221 JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle,
1222 jbyteArray jkey, jint jkey_off, jint jkey_len,
1223 jbyteArray jval, jint jval_off, jint jval_len, jlong jcf_handle) {
1224 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1225 auto* write_options =
1226 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
1227 auto* cf_handle =
1228 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1229 if (cf_handle != nullptr) {
1230 rocksdb_merge_helper(env, db, *write_options, cf_handle, jkey, jkey_off,
1231 jkey_len, jval, jval_off, jval_len);
1232 } else {
1233 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1234 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1235 "Invalid ColumnFamilyHandle."));
1236 }
1237 }
1238
rocksdb_iterator_helper(ROCKSDB_NAMESPACE::DB * db,ROCKSDB_NAMESPACE::ReadOptions read_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * cf_handle)1239 jlong rocksdb_iterator_helper(
1240 ROCKSDB_NAMESPACE::DB* db, ROCKSDB_NAMESPACE::ReadOptions read_options,
1241 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle) {
1242 ROCKSDB_NAMESPACE::Iterator* iterator = nullptr;
1243 if (cf_handle != nullptr) {
1244 iterator = db->NewIterator(read_options, cf_handle);
1245 } else {
1246 iterator = db->NewIterator(read_options);
1247 }
1248 return reinterpret_cast<jlong>(iterator);
1249 }
1250
1251 /*
1252 * Class: org_rocksdb_RocksDB
1253 * Method: deleteDirect
1254 * Signature: (JJLjava/nio/ByteBuffer;IIJ)V
1255 */
Java_org_rocksdb_RocksDB_deleteDirect(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options,jobject jkey,jint jkey_offset,jint jkey_len,jlong jcf_handle)1256 void Java_org_rocksdb_RocksDB_deleteDirect(JNIEnv* env, jobject /*jdb*/,
1257 jlong jdb_handle,
1258 jlong jwrite_options, jobject jkey,
1259 jint jkey_offset, jint jkey_len,
1260 jlong jcf_handle) {
1261 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1262 auto* write_options =
1263 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options);
1264 auto* cf_handle =
1265 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1266 auto remove = [&env, &db, &write_options,
1267 &cf_handle](ROCKSDB_NAMESPACE::Slice& key) {
1268 ROCKSDB_NAMESPACE::Status s;
1269 if (cf_handle == nullptr) {
1270 s = db->Delete(*write_options, key);
1271 } else {
1272 s = db->Delete(*write_options, cf_handle, key);
1273 }
1274 if (s.ok()) {
1275 return;
1276 }
1277 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1278 };
1279 ROCKSDB_NAMESPACE::JniUtil::k_op_direct(remove, env, jkey, jkey_offset,
1280 jkey_len);
1281 }
1282
1283 //////////////////////////////////////////////////////////////////////////////
1284 // ROCKSDB_NAMESPACE::DB::Write
1285 /*
1286 * Class: org_rocksdb_RocksDB
1287 * Method: write0
1288 * Signature: (JJJ)V
1289 */
Java_org_rocksdb_RocksDB_write0(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jlong jwb_handle)1290 void Java_org_rocksdb_RocksDB_write0(
1291 JNIEnv* env, jobject, jlong jdb_handle,
1292 jlong jwrite_options_handle, jlong jwb_handle) {
1293 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1294 auto* write_options =
1295 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
1296 auto* wb = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle);
1297
1298 ROCKSDB_NAMESPACE::Status s = db->Write(*write_options, wb);
1299
1300 if (!s.ok()) {
1301 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1302 }
1303 }
1304
1305 /*
1306 * Class: org_rocksdb_RocksDB
1307 * Method: write1
1308 * Signature: (JJJ)V
1309 */
Java_org_rocksdb_RocksDB_write1(JNIEnv * env,jobject,jlong jdb_handle,jlong jwrite_options_handle,jlong jwbwi_handle)1310 void Java_org_rocksdb_RocksDB_write1(
1311 JNIEnv* env, jobject, jlong jdb_handle,
1312 jlong jwrite_options_handle, jlong jwbwi_handle) {
1313 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1314 auto* write_options =
1315 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
1316 auto* wbwi =
1317 reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatchWithIndex*>(jwbwi_handle);
1318 auto* wb = wbwi->GetWriteBatch();
1319
1320 ROCKSDB_NAMESPACE::Status s = db->Write(*write_options, wb);
1321
1322 if (!s.ok()) {
1323 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1324 }
1325 }
1326
1327 //////////////////////////////////////////////////////////////////////////////
1328 // ROCKSDB_NAMESPACE::DB::Get
1329
rocksdb_get_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::ReadOptions & read_opt,ROCKSDB_NAMESPACE::ColumnFamilyHandle * column_family_handle,jbyteArray jkey,jint jkey_off,jint jkey_len)1330 jbyteArray rocksdb_get_helper(
1331 JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
1332 const ROCKSDB_NAMESPACE::ReadOptions& read_opt,
1333 ROCKSDB_NAMESPACE::ColumnFamilyHandle* column_family_handle,
1334 jbyteArray jkey, jint jkey_off, jint jkey_len) {
1335 jbyte* key = new jbyte[jkey_len];
1336 env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
1337 if (env->ExceptionCheck()) {
1338 // exception thrown: ArrayIndexOutOfBoundsException
1339 delete[] key;
1340 return nullptr;
1341 }
1342
1343 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
1344
1345 std::string value;
1346 ROCKSDB_NAMESPACE::Status s;
1347 if (column_family_handle != nullptr) {
1348 s = db->Get(read_opt, column_family_handle, key_slice, &value);
1349 } else {
1350 // backwards compatibility
1351 s = db->Get(read_opt, key_slice, &value);
1352 }
1353
1354 // cleanup
1355 delete[] key;
1356
1357 if (s.IsNotFound()) {
1358 return nullptr;
1359 }
1360
1361 if (s.ok()) {
1362 jbyteArray jret_value = ROCKSDB_NAMESPACE::JniUtil::copyBytes(env, value);
1363 if (jret_value == nullptr) {
1364 // exception occurred
1365 return nullptr;
1366 }
1367 return jret_value;
1368 }
1369
1370 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1371 return nullptr;
1372 }
1373
1374 /*
1375 * Class: org_rocksdb_RocksDB
1376 * Method: get
1377 * Signature: (J[BII)[B
1378 */
Java_org_rocksdb_RocksDB_get__J_3BII(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len)1379 jbyteArray Java_org_rocksdb_RocksDB_get__J_3BII(
1380 JNIEnv* env, jobject, jlong jdb_handle,
1381 jbyteArray jkey, jint jkey_off, jint jkey_len) {
1382 return rocksdb_get_helper(
1383 env, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1384 ROCKSDB_NAMESPACE::ReadOptions(), nullptr, jkey, jkey_off, jkey_len);
1385 }
1386
1387 /*
1388 * Class: org_rocksdb_RocksDB
1389 * Method: get
1390 * Signature: (J[BIIJ)[B
1391 */
Java_org_rocksdb_RocksDB_get__J_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jlong jcf_handle)1392 jbyteArray Java_org_rocksdb_RocksDB_get__J_3BIIJ(
1393 JNIEnv* env, jobject, jlong jdb_handle,
1394 jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
1395 auto db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1396 auto cf_handle =
1397 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1398 if (cf_handle != nullptr) {
1399 return rocksdb_get_helper(env, db_handle, ROCKSDB_NAMESPACE::ReadOptions(),
1400 cf_handle, jkey, jkey_off, jkey_len);
1401 } else {
1402 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1403 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1404 "Invalid ColumnFamilyHandle."));
1405 return nullptr;
1406 }
1407 }
1408
1409 /*
1410 * Class: org_rocksdb_RocksDB
1411 * Method: get
1412 * Signature: (JJ[BII)[B
1413 */
Java_org_rocksdb_RocksDB_get__JJ_3BII(JNIEnv * env,jobject,jlong jdb_handle,jlong jropt_handle,jbyteArray jkey,jint jkey_off,jint jkey_len)1414 jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BII(
1415 JNIEnv* env, jobject,
1416 jlong jdb_handle, jlong jropt_handle,
1417 jbyteArray jkey, jint jkey_off, jint jkey_len) {
1418 return rocksdb_get_helper(
1419 env, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1420 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle), nullptr,
1421 jkey, jkey_off, jkey_len);
1422 }
1423
1424 /*
1425 * Class: org_rocksdb_RocksDB
1426 * Method: get
1427 * Signature: (JJ[BIIJ)[B
1428 */
Java_org_rocksdb_RocksDB_get__JJ_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jropt_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jlong jcf_handle)1429 jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BIIJ(
1430 JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle,
1431 jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) {
1432 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1433 auto& ro_opt =
1434 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle);
1435 auto* cf_handle =
1436 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1437 if (cf_handle != nullptr) {
1438 return rocksdb_get_helper(
1439 env, db_handle, ro_opt, cf_handle, jkey, jkey_off, jkey_len);
1440 } else {
1441 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1442 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1443 "Invalid ColumnFamilyHandle."));
1444 return nullptr;
1445 }
1446 }
1447
rocksdb_get_helper(JNIEnv * env,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::ReadOptions & read_options,ROCKSDB_NAMESPACE::ColumnFamilyHandle * column_family_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,bool * has_exception)1448 jint rocksdb_get_helper(
1449 JNIEnv* env, ROCKSDB_NAMESPACE::DB* db,
1450 const ROCKSDB_NAMESPACE::ReadOptions& read_options,
1451 ROCKSDB_NAMESPACE::ColumnFamilyHandle* column_family_handle,
1452 jbyteArray jkey, jint jkey_off, jint jkey_len, jbyteArray jval,
1453 jint jval_off, jint jval_len, bool* has_exception) {
1454 static const int kNotFound = -1;
1455 static const int kStatusError = -2;
1456
1457 jbyte* key = new jbyte[jkey_len];
1458 env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key);
1459 if (env->ExceptionCheck()) {
1460 // exception thrown: OutOfMemoryError
1461 delete[] key;
1462 *has_exception = true;
1463 return kStatusError;
1464 }
1465 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
1466
1467 // TODO(yhchiang): we might save one memory allocation here by adding
1468 // a DB::Get() function which takes preallocated jbyte* as input.
1469 std::string cvalue;
1470 ROCKSDB_NAMESPACE::Status s;
1471 if (column_family_handle != nullptr) {
1472 s = db->Get(read_options, column_family_handle, key_slice, &cvalue);
1473 } else {
1474 // backwards compatibility
1475 s = db->Get(read_options, key_slice, &cvalue);
1476 }
1477
1478 // cleanup
1479 delete[] key;
1480
1481 if (s.IsNotFound()) {
1482 *has_exception = false;
1483 return kNotFound;
1484 } else if (!s.ok()) {
1485 *has_exception = true;
1486 // Here since we are throwing a Java exception from c++ side.
1487 // As a result, c++ does not know calling this function will in fact
1488 // throwing an exception. As a result, the execution flow will
1489 // not stop here, and codes after this throw will still be
1490 // executed.
1491 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
1492
1493 // Return a dummy const value to avoid compilation error, although
1494 // java side might not have a chance to get the return value :)
1495 return kStatusError;
1496 }
1497
1498 const jint cvalue_len = static_cast<jint>(cvalue.size());
1499 const jint length = std::min(jval_len, cvalue_len);
1500
1501 env->SetByteArrayRegion(
1502 jval, jval_off, length,
1503 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(cvalue.c_str())));
1504 if (env->ExceptionCheck()) {
1505 // exception thrown: OutOfMemoryError
1506 *has_exception = true;
1507 return kStatusError;
1508 }
1509
1510 *has_exception = false;
1511 return cvalue_len;
1512 }
1513
1514 /*
1515 * Class: org_rocksdb_RocksDB
1516 * Method: get
1517 * Signature: (J[BII[BII)I
1518 */
Java_org_rocksdb_RocksDB_get__J_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)1519 jint Java_org_rocksdb_RocksDB_get__J_3BII_3BII(
1520 JNIEnv* env, jobject, jlong jdb_handle,
1521 jbyteArray jkey, jint jkey_off, jint jkey_len,
1522 jbyteArray jval, jint jval_off, jint jval_len) {
1523 bool has_exception = false;
1524 return rocksdb_get_helper(
1525 env, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1526 ROCKSDB_NAMESPACE::ReadOptions(), nullptr, jkey, jkey_off, jkey_len, jval,
1527 jval_off, jval_len, &has_exception);
1528 }
1529
1530 /*
1531 * Class: org_rocksdb_RocksDB
1532 * Method: get
1533 * Signature: (J[BII[BIIJ)I
1534 */
Java_org_rocksdb_RocksDB_get__J_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,jlong jcf_handle)1535 jint Java_org_rocksdb_RocksDB_get__J_3BII_3BIIJ(
1536 JNIEnv* env, jobject, jlong jdb_handle,
1537 jbyteArray jkey, jint jkey_off, jint jkey_len,
1538 jbyteArray jval, jint jval_off, jint jval_len,
1539 jlong jcf_handle) {
1540 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1541 auto* cf_handle =
1542 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1543 if (cf_handle != nullptr) {
1544 bool has_exception = false;
1545 return rocksdb_get_helper(env, db_handle, ROCKSDB_NAMESPACE::ReadOptions(),
1546 cf_handle, jkey, jkey_off, jkey_len, jval,
1547 jval_off, jval_len, &has_exception);
1548 } else {
1549 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1550 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1551 "Invalid ColumnFamilyHandle."));
1552 // will never be evaluated
1553 return 0;
1554 }
1555 }
1556
1557 /*
1558 * Class: org_rocksdb_RocksDB
1559 * Method: get
1560 * Signature: (JJ[BII[BII)I
1561 */
Java_org_rocksdb_RocksDB_get__JJ_3BII_3BII(JNIEnv * env,jobject,jlong jdb_handle,jlong jropt_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len)1562 jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BII(
1563 JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle,
1564 jbyteArray jkey, jint jkey_off, jint jkey_len,
1565 jbyteArray jval, jint jval_off, jint jval_len) {
1566 bool has_exception = false;
1567 return rocksdb_get_helper(
1568 env, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1569 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle), nullptr,
1570 jkey, jkey_off, jkey_len, jval, jval_off, jval_len, &has_exception);
1571 }
1572
1573 /*
1574 * Class: org_rocksdb_RocksDB
1575 * Method: get
1576 * Signature: (JJ[BII[BIIJ)I
1577 */
Java_org_rocksdb_RocksDB_get__JJ_3BII_3BIIJ(JNIEnv * env,jobject,jlong jdb_handle,jlong jropt_handle,jbyteArray jkey,jint jkey_off,jint jkey_len,jbyteArray jval,jint jval_off,jint jval_len,jlong jcf_handle)1578 jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BIIJ(
1579 JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle,
1580 jbyteArray jkey, jint jkey_off, jint jkey_len,
1581 jbyteArray jval, jint jval_off, jint jval_len,
1582 jlong jcf_handle) {
1583 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1584 auto& ro_opt =
1585 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle);
1586 auto* cf_handle =
1587 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1588 if (cf_handle != nullptr) {
1589 bool has_exception = false;
1590 return rocksdb_get_helper(env, db_handle, ro_opt, cf_handle,
1591 jkey, jkey_off, jkey_len,
1592 jval, jval_off, jval_len,
1593 &has_exception);
1594 } else {
1595 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
1596 env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
1597 "Invalid ColumnFamilyHandle."));
1598 // will never be evaluated
1599 return 0;
1600 }
1601 }
1602
multi_get_helper_release_keys(JNIEnv * env,std::vector<std::pair<jbyte *,jobject>> & keys_to_free)1603 inline void multi_get_helper_release_keys(
1604 JNIEnv* env, std::vector<std::pair<jbyte*, jobject>>& keys_to_free) {
1605 auto end = keys_to_free.end();
1606 for (auto it = keys_to_free.begin(); it != end; ++it) {
1607 delete[] it->first;
1608 env->DeleteLocalRef(it->second);
1609 }
1610 keys_to_free.clear();
1611 }
1612
1613 /**
1614 * cf multi get
1615 *
1616 * @return byte[][] of values or nullptr if an exception occurs
1617 */
multi_get_helper(JNIEnv * env,jobject,ROCKSDB_NAMESPACE::DB * db,const ROCKSDB_NAMESPACE::ReadOptions & rOpt,jobjectArray jkeys,jintArray jkey_offs,jintArray jkey_lens,jlongArray jcolumn_family_handles)1618 jobjectArray multi_get_helper(JNIEnv* env, jobject, ROCKSDB_NAMESPACE::DB* db,
1619 const ROCKSDB_NAMESPACE::ReadOptions& rOpt,
1620 jobjectArray jkeys, jintArray jkey_offs,
1621 jintArray jkey_lens,
1622 jlongArray jcolumn_family_handles) {
1623 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
1624 if (jcolumn_family_handles != nullptr) {
1625 const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
1626
1627 jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
1628 if (jcfh == nullptr) {
1629 // exception thrown: OutOfMemoryError
1630 return nullptr;
1631 }
1632
1633 for (jsize i = 0; i < len_cols; i++) {
1634 auto* cf_handle =
1635 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcfh[i]);
1636 cf_handles.push_back(cf_handle);
1637 }
1638 env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
1639 }
1640
1641 const jsize len_keys = env->GetArrayLength(jkeys);
1642 if (env->EnsureLocalCapacity(len_keys) != 0) {
1643 // exception thrown: OutOfMemoryError
1644 return nullptr;
1645 }
1646
1647 jint* jkey_off = env->GetIntArrayElements(jkey_offs, nullptr);
1648 if (jkey_off == nullptr) {
1649 // exception thrown: OutOfMemoryError
1650 return nullptr;
1651 }
1652
1653 jint* jkey_len = env->GetIntArrayElements(jkey_lens, nullptr);
1654 if (jkey_len == nullptr) {
1655 // exception thrown: OutOfMemoryError
1656 env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
1657 return nullptr;
1658 }
1659
1660 std::vector<ROCKSDB_NAMESPACE::Slice> keys;
1661 std::vector<std::pair<jbyte*, jobject>> keys_to_free;
1662 for (jsize i = 0; i < len_keys; i++) {
1663 jobject jkey = env->GetObjectArrayElement(jkeys, i);
1664 if (env->ExceptionCheck()) {
1665 // exception thrown: ArrayIndexOutOfBoundsException
1666 env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
1667 env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
1668 multi_get_helper_release_keys(env, keys_to_free);
1669 return nullptr;
1670 }
1671
1672 jbyteArray jkey_ba = reinterpret_cast<jbyteArray>(jkey);
1673
1674 const jint len_key = jkey_len[i];
1675 jbyte* key = new jbyte[len_key];
1676 env->GetByteArrayRegion(jkey_ba, jkey_off[i], len_key, key);
1677 if (env->ExceptionCheck()) {
1678 // exception thrown: ArrayIndexOutOfBoundsException
1679 delete[] key;
1680 env->DeleteLocalRef(jkey);
1681 env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
1682 env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
1683 multi_get_helper_release_keys(env, keys_to_free);
1684 return nullptr;
1685 }
1686
1687 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), len_key);
1688 keys.push_back(key_slice);
1689
1690 keys_to_free.push_back(std::pair<jbyte*, jobject>(key, jkey));
1691 }
1692
1693 // cleanup jkey_off and jken_len
1694 env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT);
1695 env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT);
1696
1697 std::vector<std::string> values;
1698 std::vector<ROCKSDB_NAMESPACE::Status> s;
1699 if (cf_handles.size() == 0) {
1700 s = db->MultiGet(rOpt, keys, &values);
1701 } else {
1702 s = db->MultiGet(rOpt, cf_handles, keys, &values);
1703 }
1704
1705 // free up allocated byte arrays
1706 multi_get_helper_release_keys(env, keys_to_free);
1707
1708 // prepare the results
1709 jobjectArray jresults = ROCKSDB_NAMESPACE::ByteJni::new2dByteArray(
1710 env, static_cast<jsize>(s.size()));
1711 if (jresults == nullptr) {
1712 // exception occurred
1713 return nullptr;
1714 }
1715
1716 // TODO(AR) it is not clear to me why EnsureLocalCapacity is needed for the
1717 // loop as we cleanup references with env->DeleteLocalRef(jentry_value);
1718 if (env->EnsureLocalCapacity(static_cast<jint>(s.size())) != 0) {
1719 // exception thrown: OutOfMemoryError
1720 return nullptr;
1721 }
1722 // add to the jresults
1723 for (std::vector<ROCKSDB_NAMESPACE::Status>::size_type i = 0; i != s.size();
1724 i++) {
1725 if (s[i].ok()) {
1726 std::string* value = &values[i];
1727 const jsize jvalue_len = static_cast<jsize>(value->size());
1728 jbyteArray jentry_value = env->NewByteArray(jvalue_len);
1729 if (jentry_value == nullptr) {
1730 // exception thrown: OutOfMemoryError
1731 return nullptr;
1732 }
1733
1734 env->SetByteArrayRegion(
1735 jentry_value, 0, static_cast<jsize>(jvalue_len),
1736 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value->c_str())));
1737 if (env->ExceptionCheck()) {
1738 // exception thrown: ArrayIndexOutOfBoundsException
1739 env->DeleteLocalRef(jentry_value);
1740 return nullptr;
1741 }
1742
1743 env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jentry_value);
1744 if (env->ExceptionCheck()) {
1745 // exception thrown: ArrayIndexOutOfBoundsException
1746 env->DeleteLocalRef(jentry_value);
1747 return nullptr;
1748 }
1749
1750 env->DeleteLocalRef(jentry_value);
1751 }
1752 }
1753
1754 return jresults;
1755 }
1756
1757 /*
1758 * Class: org_rocksdb_RocksDB
1759 * Method: multiGet
1760 * Signature: (J[[B[I[I)[[B
1761 */
Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I(JNIEnv * env,jobject jdb,jlong jdb_handle,jobjectArray jkeys,jintArray jkey_offs,jintArray jkey_lens)1762 jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I(
1763 JNIEnv* env, jobject jdb, jlong jdb_handle,
1764 jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) {
1765 return multi_get_helper(
1766 env, jdb, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1767 ROCKSDB_NAMESPACE::ReadOptions(), jkeys, jkey_offs, jkey_lens, nullptr);
1768 }
1769
1770 /*
1771 * Class: org_rocksdb_RocksDB
1772 * Method: multiGet
1773 * Signature: (J[[B[I[I[J)[[B
1774 */
Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I_3J(JNIEnv * env,jobject jdb,jlong jdb_handle,jobjectArray jkeys,jintArray jkey_offs,jintArray jkey_lens,jlongArray jcolumn_family_handles)1775 jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I_3J(
1776 JNIEnv* env, jobject jdb, jlong jdb_handle,
1777 jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens,
1778 jlongArray jcolumn_family_handles) {
1779 return multi_get_helper(env, jdb,
1780 reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1781 ROCKSDB_NAMESPACE::ReadOptions(), jkeys, jkey_offs,
1782 jkey_lens, jcolumn_family_handles);
1783 }
1784
1785 /*
1786 * Class: org_rocksdb_RocksDB
1787 * Method: multiGet
1788 * Signature: (JJ[[B[I[I)[[B
1789 */
Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I(JNIEnv * env,jobject jdb,jlong jdb_handle,jlong jropt_handle,jobjectArray jkeys,jintArray jkey_offs,jintArray jkey_lens)1790 jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I(
1791 JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
1792 jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) {
1793 return multi_get_helper(
1794 env, jdb, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1795 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle), jkeys,
1796 jkey_offs, jkey_lens, nullptr);
1797 }
1798
1799 /*
1800 * Class: org_rocksdb_RocksDB
1801 * Method: multiGet
1802 * Signature: (JJ[[B[I[I[J)[[B
1803 */
Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I_3J(JNIEnv * env,jobject jdb,jlong jdb_handle,jlong jropt_handle,jobjectArray jkeys,jintArray jkey_offs,jintArray jkey_lens,jlongArray jcolumn_family_handles)1804 jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I_3J(
1805 JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
1806 jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens,
1807 jlongArray jcolumn_family_handles) {
1808 return multi_get_helper(
1809 env, jdb, reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle),
1810 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jropt_handle), jkeys,
1811 jkey_offs, jkey_lens, jcolumn_family_handles);
1812 }
1813
1814 //////////////////////////////////////////////////////////////////////////////
1815 // ROCKSDB_NAMESPACE::DB::KeyMayExist
key_may_exist_helper(JNIEnv * env,jlong jdb_handle,jlong jcf_handle,jlong jread_opts_handle,jbyteArray jkey,jint jkey_offset,jint jkey_len,bool * has_exception,std::string * value,bool * value_found)1816 bool key_may_exist_helper(JNIEnv* env, jlong jdb_handle, jlong jcf_handle,
1817 jlong jread_opts_handle,
1818 jbyteArray jkey, jint jkey_offset, jint jkey_len,
1819 bool* has_exception, std::string* value, bool* value_found) {
1820 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
1821 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
1822 if (jcf_handle == 0) {
1823 cf_handle = db->DefaultColumnFamily();
1824 } else {
1825 cf_handle =
1826 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
1827 }
1828 ROCKSDB_NAMESPACE::ReadOptions read_opts =
1829 jread_opts_handle == 0
1830 ? ROCKSDB_NAMESPACE::ReadOptions()
1831 : *(reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(
1832 jread_opts_handle));
1833
1834 jbyte* key = new jbyte[jkey_len];
1835 env->GetByteArrayRegion(jkey, jkey_offset, jkey_len, key);
1836 if (env->ExceptionCheck()) {
1837 // exception thrown: ArrayIndexOutOfBoundsException
1838 delete[] key;
1839 *has_exception = true;
1840 return false;
1841 }
1842 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
1843
1844 const bool exists = db->KeyMayExist(
1845 read_opts, cf_handle, key_slice, value, value_found);
1846
1847 // cleanup
1848 delete[] key;
1849
1850 return exists;
1851 }
1852
1853
1854 /*
1855 * Class: org_rocksdb_RocksDB
1856 * Method: keyMayExist
1857 * Signature: (JJJ[BII)Z
1858 */
Java_org_rocksdb_RocksDB_keyMayExist(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jlong jread_opts_handle,jbyteArray jkey,jint jkey_offset,jint jkey_len)1859 jboolean Java_org_rocksdb_RocksDB_keyMayExist(
1860 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
1861 jlong jread_opts_handle,
1862 jbyteArray jkey, jint jkey_offset, jint jkey_len) {
1863
1864 bool has_exception = false;
1865 std::string value;
1866 bool value_found = false;
1867
1868 const bool exists = key_may_exist_helper(
1869 env, jdb_handle, jcf_handle, jread_opts_handle,
1870 jkey, jkey_offset, jkey_len,
1871 &has_exception, &value, &value_found);
1872
1873 if (has_exception) {
1874 // java exception already raised
1875 return false;
1876 }
1877
1878 return static_cast<jboolean>(exists);
1879 }
1880
1881 /*
1882 * Class: org_rocksdb_RocksDB
1883 * Method: keyMayExistFoundValue
1884 * Signature: (JJJ[BII)[[B
1885 */
Java_org_rocksdb_RocksDB_keyMayExistFoundValue(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jlong jread_opts_handle,jbyteArray jkey,jint jkey_offset,jint jkey_len)1886 jobjectArray Java_org_rocksdb_RocksDB_keyMayExistFoundValue(
1887 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
1888 jlong jread_opts_handle,
1889 jbyteArray jkey, jint jkey_offset, jint jkey_len) {
1890
1891 bool has_exception = false;
1892 std::string value;
1893 bool value_found = false;
1894
1895 const bool exists = key_may_exist_helper(
1896 env, jdb_handle, jcf_handle, jread_opts_handle,
1897 jkey, jkey_offset, jkey_len,
1898 &has_exception, &value, &value_found);
1899
1900 if (has_exception) {
1901 // java exception already raised
1902 return nullptr;
1903 }
1904
1905 jbyte result_flags[1];
1906 if (!exists) {
1907 result_flags[0] = 0;
1908 } else if (!value_found) {
1909 result_flags[0] = 1;
1910 } else {
1911 // found
1912 result_flags[0] = 2;
1913 }
1914
1915 jobjectArray jresults = ROCKSDB_NAMESPACE::ByteJni::new2dByteArray(env, 2);
1916 if (jresults == nullptr) {
1917 // exception occurred
1918 return nullptr;
1919 }
1920
1921 // prepare the result flag
1922 jbyteArray jresult_flags = env->NewByteArray(1);
1923 if (jresult_flags == nullptr) {
1924 // exception thrown: OutOfMemoryError
1925 return nullptr;
1926 }
1927 env->SetByteArrayRegion(jresult_flags, 0, 1, result_flags);
1928 if (env->ExceptionCheck()) {
1929 // exception thrown: ArrayIndexOutOfBoundsException
1930 env->DeleteLocalRef(jresult_flags);
1931 return nullptr;
1932 }
1933
1934 env->SetObjectArrayElement(jresults, 0, jresult_flags);
1935 if (env->ExceptionCheck()) {
1936 // exception thrown: ArrayIndexOutOfBoundsException
1937 env->DeleteLocalRef(jresult_flags);
1938 return nullptr;
1939 }
1940
1941 env->DeleteLocalRef(jresult_flags);
1942
1943 if (result_flags[0] == 2) {
1944 // set the value
1945 const jsize jvalue_len = static_cast<jsize>(value.size());
1946 jbyteArray jresult_value = env->NewByteArray(jvalue_len);
1947 if (jresult_value == nullptr) {
1948 // exception thrown: OutOfMemoryError
1949 return nullptr;
1950 }
1951 env->SetByteArrayRegion(jresult_value, 0, jvalue_len,
1952 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.data())));
1953 if (env->ExceptionCheck()) {
1954 // exception thrown: ArrayIndexOutOfBoundsException
1955 env->DeleteLocalRef(jresult_value);
1956 return nullptr;
1957 }
1958 env->SetObjectArrayElement(jresults, 1, jresult_value);
1959 if (env->ExceptionCheck()) {
1960 // exception thrown: ArrayIndexOutOfBoundsException
1961 env->DeleteLocalRef(jresult_value);
1962 return nullptr;
1963 }
1964
1965 env->DeleteLocalRef(jresult_value);
1966 }
1967
1968 return jresults;
1969 }
1970
1971 /*
1972 * Class: org_rocksdb_RocksDB
1973 * Method: iterator
1974 * Signature: (J)J
1975 */
Java_org_rocksdb_RocksDB_iterator__J(JNIEnv *,jobject,jlong db_handle)1976 jlong Java_org_rocksdb_RocksDB_iterator__J(
1977 JNIEnv*, jobject, jlong db_handle) {
1978 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
1979 return rocksdb_iterator_helper(db, ROCKSDB_NAMESPACE::ReadOptions(), nullptr);
1980 }
1981
1982 /*
1983 * Class: org_rocksdb_RocksDB
1984 * Method: iterator
1985 * Signature: (JJ)J
1986 */
Java_org_rocksdb_RocksDB_iterator__JJ(JNIEnv *,jobject,jlong db_handle,jlong jread_options_handle)1987 jlong Java_org_rocksdb_RocksDB_iterator__JJ(
1988 JNIEnv*, jobject, jlong db_handle, jlong jread_options_handle) {
1989 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
1990 auto& read_options =
1991 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
1992 return rocksdb_iterator_helper(db, read_options, nullptr);
1993 }
1994
1995 /*
1996 * Class: org_rocksdb_RocksDB
1997 * Method: iteratorCF
1998 * Signature: (JJ)J
1999 */
Java_org_rocksdb_RocksDB_iteratorCF__JJ(JNIEnv *,jobject,jlong db_handle,jlong jcf_handle)2000 jlong Java_org_rocksdb_RocksDB_iteratorCF__JJ(
2001 JNIEnv*, jobject, jlong db_handle, jlong jcf_handle) {
2002 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
2003 auto* cf_handle =
2004 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2005 return rocksdb_iterator_helper(db, ROCKSDB_NAMESPACE::ReadOptions(),
2006 cf_handle);
2007 }
2008
2009 /*
2010 * Class: org_rocksdb_RocksDB
2011 * Method: iteratorCF
2012 * Signature: (JJJ)J
2013 */
Java_org_rocksdb_RocksDB_iteratorCF__JJJ(JNIEnv *,jobject,jlong db_handle,jlong jcf_handle,jlong jread_options_handle)2014 jlong Java_org_rocksdb_RocksDB_iteratorCF__JJJ(
2015 JNIEnv*, jobject,
2016 jlong db_handle, jlong jcf_handle, jlong jread_options_handle) {
2017 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
2018 auto* cf_handle =
2019 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2020 auto& read_options =
2021 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
2022 return rocksdb_iterator_helper(db, read_options, cf_handle);
2023 }
2024
2025 /*
2026 * Class: org_rocksdb_RocksDB
2027 * Method: iterators
2028 * Signature: (J[JJ)[J
2029 */
Java_org_rocksdb_RocksDB_iterators(JNIEnv * env,jobject,jlong db_handle,jlongArray jcolumn_family_handles,jlong jread_options_handle)2030 jlongArray Java_org_rocksdb_RocksDB_iterators(
2031 JNIEnv* env, jobject, jlong db_handle,
2032 jlongArray jcolumn_family_handles,
2033 jlong jread_options_handle) {
2034 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
2035 auto& read_options =
2036 *reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
2037
2038 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
2039 if (jcolumn_family_handles != nullptr) {
2040 const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
2041 jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
2042 if (jcfh == nullptr) {
2043 // exception thrown: OutOfMemoryError
2044 return nullptr;
2045 }
2046
2047 for (jsize i = 0; i < len_cols; i++) {
2048 auto* cf_handle =
2049 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcfh[i]);
2050 cf_handles.push_back(cf_handle);
2051 }
2052
2053 env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
2054 }
2055
2056 std::vector<ROCKSDB_NAMESPACE::Iterator*> iterators;
2057 ROCKSDB_NAMESPACE::Status s =
2058 db->NewIterators(read_options, cf_handles, &iterators);
2059 if (s.ok()) {
2060 jlongArray jLongArray =
2061 env->NewLongArray(static_cast<jsize>(iterators.size()));
2062 if (jLongArray == nullptr) {
2063 // exception thrown: OutOfMemoryError
2064 return nullptr;
2065 }
2066
2067 for (std::vector<ROCKSDB_NAMESPACE::Iterator*>::size_type i = 0;
2068 i < iterators.size(); i++) {
2069 env->SetLongArrayRegion(
2070 jLongArray, static_cast<jsize>(i), 1,
2071 const_cast<jlong*>(reinterpret_cast<const jlong*>(&iterators[i])));
2072 if (env->ExceptionCheck()) {
2073 // exception thrown: ArrayIndexOutOfBoundsException
2074 env->DeleteLocalRef(jLongArray);
2075 return nullptr;
2076 }
2077 }
2078
2079 return jLongArray;
2080 } else {
2081 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2082 return nullptr;
2083 }
2084 }
2085
2086 /*
2087 * Method: getSnapshot
2088 * Signature: (J)J
2089 */
Java_org_rocksdb_RocksDB_getSnapshot(JNIEnv *,jobject,jlong db_handle)2090 jlong Java_org_rocksdb_RocksDB_getSnapshot(
2091 JNIEnv*, jobject, jlong db_handle) {
2092 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
2093 const ROCKSDB_NAMESPACE::Snapshot* snapshot = db->GetSnapshot();
2094 return reinterpret_cast<jlong>(snapshot);
2095 }
2096
2097 /*
2098 * Method: releaseSnapshot
2099 * Signature: (JJ)V
2100 */
Java_org_rocksdb_RocksDB_releaseSnapshot(JNIEnv *,jobject,jlong db_handle,jlong snapshot_handle)2101 void Java_org_rocksdb_RocksDB_releaseSnapshot(
2102 JNIEnv*, jobject, jlong db_handle,
2103 jlong snapshot_handle) {
2104 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
2105 auto* snapshot =
2106 reinterpret_cast<ROCKSDB_NAMESPACE::Snapshot*>(snapshot_handle);
2107 db->ReleaseSnapshot(snapshot);
2108 }
2109
2110 /*
2111 * Class: org_rocksdb_RocksDB
2112 * Method: getProperty
2113 * Signature: (JJLjava/lang/String;I)Ljava/lang/String;
2114 */
Java_org_rocksdb_RocksDB_getProperty(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jstring jproperty,jint jproperty_len)2115 jstring Java_org_rocksdb_RocksDB_getProperty(
2116 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
2117 jstring jproperty, jint jproperty_len) {
2118 const char* property = env->GetStringUTFChars(jproperty, nullptr);
2119 if (property == nullptr) {
2120 // exception thrown: OutOfMemoryError
2121 return nullptr;
2122 }
2123 ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
2124
2125 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2126 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2127 if (jcf_handle == 0) {
2128 cf_handle = db->DefaultColumnFamily();
2129 } else {
2130 cf_handle =
2131 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2132 }
2133
2134 std::string property_value;
2135 bool retCode = db->GetProperty(cf_handle, property_name, &property_value);
2136 env->ReleaseStringUTFChars(jproperty, property);
2137
2138 if (retCode) {
2139 return env->NewStringUTF(property_value.c_str());
2140 }
2141
2142 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2143 env, ROCKSDB_NAMESPACE::Status::NotFound());
2144 return nullptr;
2145 }
2146
2147 /*
2148 * Class: org_rocksdb_RocksDB
2149 * Method: getMapProperty
2150 * Signature: (JJLjava/lang/String;I)Ljava/util/Map;
2151 */
Java_org_rocksdb_RocksDB_getMapProperty(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jstring jproperty,jint jproperty_len)2152 jobject Java_org_rocksdb_RocksDB_getMapProperty(
2153 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
2154 jstring jproperty, jint jproperty_len) {
2155 const char* property = env->GetStringUTFChars(jproperty, nullptr);
2156 if (property == nullptr) {
2157 // exception thrown: OutOfMemoryError
2158 return nullptr;
2159 }
2160 ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
2161
2162 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2163 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2164 if (jcf_handle == 0) {
2165 cf_handle = db->DefaultColumnFamily();
2166 } else {
2167 cf_handle =
2168 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2169 }
2170
2171 std::map<std::string, std::string> property_value;
2172 bool retCode = db->GetMapProperty(cf_handle, property_name, &property_value);
2173 env->ReleaseStringUTFChars(jproperty, property);
2174
2175 if (retCode) {
2176 return ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(env, &property_value);
2177 }
2178
2179 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2180 env, ROCKSDB_NAMESPACE::Status::NotFound());
2181 return nullptr;
2182 }
2183
2184 /*
2185 * Class: org_rocksdb_RocksDB
2186 * Method: getLongProperty
2187 * Signature: (JJLjava/lang/String;I)J
2188 */
Java_org_rocksdb_RocksDB_getLongProperty(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jstring jproperty,jint jproperty_len)2189 jlong Java_org_rocksdb_RocksDB_getLongProperty(
2190 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
2191 jstring jproperty, jint jproperty_len) {
2192 const char* property = env->GetStringUTFChars(jproperty, nullptr);
2193 if (property == nullptr) {
2194 // exception thrown: OutOfMemoryError
2195 return 0;
2196 }
2197 ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
2198
2199 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2200 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2201 if (jcf_handle == 0) {
2202 cf_handle = db->DefaultColumnFamily();
2203 } else {
2204 cf_handle =
2205 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2206 }
2207
2208 uint64_t property_value;
2209 bool retCode = db->GetIntProperty(cf_handle, property_name, &property_value);
2210 env->ReleaseStringUTFChars(jproperty, property);
2211
2212 if (retCode) {
2213 return property_value;
2214 }
2215
2216 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2217 env, ROCKSDB_NAMESPACE::Status::NotFound());
2218 return 0;
2219 }
2220
2221 /*
2222 * Class: org_rocksdb_RocksDB
2223 * Method: resetStats
2224 * Signature: (J)V
2225 */
Java_org_rocksdb_RocksDB_resetStats(JNIEnv *,jobject,jlong jdb_handle)2226 void Java_org_rocksdb_RocksDB_resetStats(
2227 JNIEnv *, jobject, jlong jdb_handle) {
2228 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2229 db->ResetStats();
2230 }
2231
2232 /*
2233 * Class: org_rocksdb_RocksDB
2234 * Method: getAggregatedLongProperty
2235 * Signature: (JLjava/lang/String;I)J
2236 */
Java_org_rocksdb_RocksDB_getAggregatedLongProperty(JNIEnv * env,jobject,jlong db_handle,jstring jproperty,jint jproperty_len)2237 jlong Java_org_rocksdb_RocksDB_getAggregatedLongProperty(
2238 JNIEnv* env, jobject, jlong db_handle,
2239 jstring jproperty, jint jproperty_len) {
2240 const char* property = env->GetStringUTFChars(jproperty, nullptr);
2241 if (property == nullptr) {
2242 return 0;
2243 }
2244 ROCKSDB_NAMESPACE::Slice property_name(property, jproperty_len);
2245 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(db_handle);
2246 uint64_t property_value = 0;
2247 bool retCode = db->GetAggregatedIntProperty(property_name, &property_value);
2248 env->ReleaseStringUTFChars(jproperty, property);
2249
2250 if (retCode) {
2251 return property_value;
2252 }
2253
2254 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2255 env, ROCKSDB_NAMESPACE::Status::NotFound());
2256 return 0;
2257 }
2258
2259 /*
2260 * Class: org_rocksdb_RocksDB
2261 * Method: getApproximateSizes
2262 * Signature: (JJ[JB)[J
2263 */
Java_org_rocksdb_RocksDB_getApproximateSizes(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jlongArray jrange_slice_handles,jbyte jinclude_flags)2264 jlongArray Java_org_rocksdb_RocksDB_getApproximateSizes(
2265 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
2266 jlongArray jrange_slice_handles, jbyte jinclude_flags) {
2267 const jsize jlen = env->GetArrayLength(jrange_slice_handles);
2268 const size_t range_count = jlen / 2;
2269
2270 jboolean jranges_is_copy = JNI_FALSE;
2271 jlong* jranges = env->GetLongArrayElements(jrange_slice_handles,
2272 &jranges_is_copy);
2273 if (jranges == nullptr) {
2274 // exception thrown: OutOfMemoryError
2275 return nullptr;
2276 }
2277
2278 auto ranges = std::unique_ptr<ROCKSDB_NAMESPACE::Range[]>(
2279 new ROCKSDB_NAMESPACE::Range[range_count]);
2280 for (jsize i = 0; i < jlen; ++i) {
2281 auto* start = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jranges[i]);
2282 auto* limit = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jranges[++i]);
2283 ranges.get()[i] = ROCKSDB_NAMESPACE::Range(*start, *limit);
2284 }
2285
2286 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2287 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2288 if (jcf_handle == 0) {
2289 cf_handle = db->DefaultColumnFamily();
2290 } else {
2291 cf_handle =
2292 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2293 }
2294
2295 auto sizes = std::unique_ptr<uint64_t[]>(new uint64_t[range_count]);
2296 db->GetApproximateSizes(cf_handle, ranges.get(),
2297 static_cast<int>(range_count), sizes.get(),
2298 static_cast<uint8_t>(jinclude_flags));
2299
2300 // release LongArrayElements
2301 env->ReleaseLongArrayElements(jrange_slice_handles, jranges, JNI_ABORT);
2302
2303 // prepare results
2304 auto results = std::unique_ptr<jlong[]>(new jlong[range_count]);
2305 for (size_t i = 0; i < range_count; ++i) {
2306 results.get()[i] = static_cast<jlong>(sizes.get()[i]);
2307 }
2308
2309 const jsize jrange_count = jlen / 2;
2310 jlongArray jresults = env->NewLongArray(jrange_count);
2311 if (jresults == nullptr) {
2312 // exception thrown: OutOfMemoryError
2313 return nullptr;
2314 }
2315
2316 env->SetLongArrayRegion(jresults, 0, jrange_count, results.get());
2317 if (env->ExceptionCheck()) {
2318 // exception thrown: ArrayIndexOutOfBoundsException
2319 env->DeleteLocalRef(jresults);
2320 return nullptr;
2321 }
2322
2323 return jresults;
2324 }
2325
2326 /*
2327 * Class: org_rocksdb_RocksDB
2328 * Method: getApproximateMemTableStats
2329 * Signature: (JJJJ)[J
2330 */
Java_org_rocksdb_RocksDB_getApproximateMemTableStats(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jlong jstartHandle,jlong jlimitHandle)2331 jlongArray Java_org_rocksdb_RocksDB_getApproximateMemTableStats(
2332 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
2333 jlong jstartHandle, jlong jlimitHandle) {
2334 auto* start = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jstartHandle);
2335 auto* limit = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jlimitHandle);
2336 const ROCKSDB_NAMESPACE::Range range(*start, *limit);
2337
2338 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2339 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2340 if (jcf_handle == 0) {
2341 cf_handle = db->DefaultColumnFamily();
2342 } else {
2343 cf_handle =
2344 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2345 }
2346
2347 uint64_t count = 0;
2348 uint64_t sizes = 0;
2349 db->GetApproximateMemTableStats(cf_handle, range, &count, &sizes);
2350
2351 // prepare results
2352 jlong results[2] = {
2353 static_cast<jlong>(count),
2354 static_cast<jlong>(sizes)};
2355
2356 const jsize jcount = static_cast<jsize>(count);
2357 jlongArray jsizes = env->NewLongArray(jcount);
2358 if (jsizes == nullptr) {
2359 // exception thrown: OutOfMemoryError
2360 return nullptr;
2361 }
2362
2363 env->SetLongArrayRegion(jsizes, 0, jcount, results);
2364 if (env->ExceptionCheck()) {
2365 // exception thrown: ArrayIndexOutOfBoundsException
2366 env->DeleteLocalRef(jsizes);
2367 return nullptr;
2368 }
2369
2370 return jsizes;
2371 }
2372
2373 /*
2374 * Class: org_rocksdb_RocksDB
2375 * Method: compactRange
2376 * Signature: (J[BI[BIJJ)V
2377 */
Java_org_rocksdb_RocksDB_compactRange(JNIEnv * env,jobject,jlong jdb_handle,jbyteArray jbegin,jint jbegin_len,jbyteArray jend,jint jend_len,jlong jcompact_range_opts_handle,jlong jcf_handle)2378 void Java_org_rocksdb_RocksDB_compactRange(
2379 JNIEnv* env, jobject, jlong jdb_handle,
2380 jbyteArray jbegin, jint jbegin_len,
2381 jbyteArray jend, jint jend_len,
2382 jlong jcompact_range_opts_handle,
2383 jlong jcf_handle) {
2384 jboolean has_exception = JNI_FALSE;
2385
2386 std::string str_begin;
2387 if (jbegin_len > 0) {
2388 str_begin = ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
2389 env, jbegin, jbegin_len,
2390 [](const char* str, const size_t len) { return std::string(str, len); },
2391 &has_exception);
2392 if (has_exception == JNI_TRUE) {
2393 // exception occurred
2394 return;
2395 }
2396 }
2397
2398 std::string str_end;
2399 if (jend_len > 0) {
2400 str_end = ROCKSDB_NAMESPACE::JniUtil::byteString<std::string>(
2401 env, jend, jend_len,
2402 [](const char* str, const size_t len) { return std::string(str, len); },
2403 &has_exception);
2404 if (has_exception == JNI_TRUE) {
2405 // exception occurred
2406 return;
2407 }
2408 }
2409
2410 ROCKSDB_NAMESPACE::CompactRangeOptions* compact_range_opts = nullptr;
2411 if (jcompact_range_opts_handle == 0) {
2412 // NOTE: we DO own the pointer!
2413 compact_range_opts = new ROCKSDB_NAMESPACE::CompactRangeOptions();
2414 } else {
2415 // NOTE: we do NOT own the pointer!
2416 compact_range_opts =
2417 reinterpret_cast<ROCKSDB_NAMESPACE::CompactRangeOptions*>(
2418 jcompact_range_opts_handle);
2419 }
2420
2421 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2422
2423 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2424 if (jcf_handle == 0) {
2425 cf_handle = db->DefaultColumnFamily();
2426 } else {
2427 cf_handle =
2428 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2429 }
2430
2431 ROCKSDB_NAMESPACE::Status s;
2432 if (jbegin_len > 0 || jend_len > 0) {
2433 const ROCKSDB_NAMESPACE::Slice begin(str_begin);
2434 const ROCKSDB_NAMESPACE::Slice end(str_end);
2435 s = db->CompactRange(*compact_range_opts, cf_handle, &begin, &end);
2436 } else {
2437 s = db->CompactRange(*compact_range_opts, cf_handle, nullptr, nullptr);
2438 }
2439
2440 if (jcompact_range_opts_handle == 0) {
2441 delete compact_range_opts;
2442 }
2443 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2444 }
2445
2446 /*
2447 * Class: org_rocksdb_RocksDB
2448 * Method: setOptions
2449 * Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)V
2450 */
Java_org_rocksdb_RocksDB_setOptions(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jobjectArray jkeys,jobjectArray jvalues)2451 void Java_org_rocksdb_RocksDB_setOptions(
2452 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
2453 jobjectArray jkeys, jobjectArray jvalues) {
2454 const jsize len = env->GetArrayLength(jkeys);
2455 assert(len == env->GetArrayLength(jvalues));
2456
2457 std::unordered_map<std::string, std::string> options_map;
2458 for (jsize i = 0; i < len; i++) {
2459 jobject jobj_key = env->GetObjectArrayElement(jkeys, i);
2460 if (env->ExceptionCheck()) {
2461 // exception thrown: ArrayIndexOutOfBoundsException
2462 return;
2463 }
2464
2465 jobject jobj_value = env->GetObjectArrayElement(jvalues, i);
2466 if (env->ExceptionCheck()) {
2467 // exception thrown: ArrayIndexOutOfBoundsException
2468 env->DeleteLocalRef(jobj_key);
2469 return;
2470 }
2471
2472 jboolean has_exception = JNI_FALSE;
2473 std::string s_key = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
2474 env, reinterpret_cast<jstring>(jobj_key), &has_exception);
2475 if (has_exception == JNI_TRUE) {
2476 // exception occurred
2477 env->DeleteLocalRef(jobj_value);
2478 env->DeleteLocalRef(jobj_key);
2479 return;
2480 }
2481
2482 std::string s_value = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
2483 env, reinterpret_cast<jstring>(jobj_value), &has_exception);
2484 if (has_exception == JNI_TRUE) {
2485 // exception occurred
2486 env->DeleteLocalRef(jobj_value);
2487 env->DeleteLocalRef(jobj_key);
2488 return;
2489 }
2490
2491 options_map[s_key] = s_value;
2492
2493 env->DeleteLocalRef(jobj_key);
2494 env->DeleteLocalRef(jobj_value);
2495 }
2496
2497 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2498 auto* cf_handle =
2499 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2500 auto s = db->SetOptions(cf_handle, options_map);
2501 if (!s.ok()) {
2502 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2503 }
2504 }
2505
2506 /*
2507 * Class: org_rocksdb_RocksDB
2508 * Method: setDBOptions
2509 * Signature: (J[Ljava/lang/String;[Ljava/lang/String;)V
2510 */
Java_org_rocksdb_RocksDB_setDBOptions(JNIEnv * env,jobject,jlong jdb_handle,jobjectArray jkeys,jobjectArray jvalues)2511 void Java_org_rocksdb_RocksDB_setDBOptions(
2512 JNIEnv* env, jobject, jlong jdb_handle,
2513 jobjectArray jkeys, jobjectArray jvalues) {
2514 const jsize len = env->GetArrayLength(jkeys);
2515 assert(len == env->GetArrayLength(jvalues));
2516
2517 std::unordered_map<std::string, std::string> options_map;
2518 for (jsize i = 0; i < len; i++) {
2519 jobject jobj_key = env->GetObjectArrayElement(jkeys, i);
2520 if (env->ExceptionCheck()) {
2521 // exception thrown: ArrayIndexOutOfBoundsException
2522 return;
2523 }
2524
2525 jobject jobj_value = env->GetObjectArrayElement(jvalues, i);
2526 if (env->ExceptionCheck()) {
2527 // exception thrown: ArrayIndexOutOfBoundsException
2528 env->DeleteLocalRef(jobj_key);
2529 return;
2530 }
2531
2532 jboolean has_exception = JNI_FALSE;
2533 std::string s_key = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
2534 env, reinterpret_cast<jstring>(jobj_key), &has_exception);
2535 if (has_exception == JNI_TRUE) {
2536 // exception occurred
2537 env->DeleteLocalRef(jobj_value);
2538 env->DeleteLocalRef(jobj_key);
2539 return;
2540 }
2541
2542 std::string s_value = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
2543 env, reinterpret_cast<jstring>(jobj_value), &has_exception);
2544 if (has_exception == JNI_TRUE) {
2545 // exception occurred
2546 env->DeleteLocalRef(jobj_value);
2547 env->DeleteLocalRef(jobj_key);
2548 return;
2549 }
2550
2551 options_map[s_key] = s_value;
2552
2553 env->DeleteLocalRef(jobj_key);
2554 env->DeleteLocalRef(jobj_value);
2555 }
2556
2557 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2558 auto s = db->SetDBOptions(options_map);
2559 if (!s.ok()) {
2560 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2561 }
2562 }
2563
2564 /*
2565 * Class: org_rocksdb_RocksDB
2566 * Method: compactFiles
2567 * Signature: (JJJ[Ljava/lang/String;IIJ)[Ljava/lang/String;
2568 */
Java_org_rocksdb_RocksDB_compactFiles(JNIEnv * env,jobject,jlong jdb_handle,jlong jcompaction_opts_handle,jlong jcf_handle,jobjectArray jinput_file_names,jint joutput_level,jint joutput_path_id,jlong jcompaction_job_info_handle)2569 jobjectArray Java_org_rocksdb_RocksDB_compactFiles(
2570 JNIEnv* env, jobject, jlong jdb_handle, jlong jcompaction_opts_handle,
2571 jlong jcf_handle, jobjectArray jinput_file_names, jint joutput_level,
2572 jint joutput_path_id, jlong jcompaction_job_info_handle) {
2573 jboolean has_exception = JNI_FALSE;
2574 const std::vector<std::string> input_file_names =
2575 ROCKSDB_NAMESPACE::JniUtil::copyStrings(env, jinput_file_names,
2576 &has_exception);
2577 if (has_exception == JNI_TRUE) {
2578 // exception occurred
2579 return nullptr;
2580 }
2581
2582 auto* compaction_opts =
2583 reinterpret_cast<ROCKSDB_NAMESPACE::CompactionOptions*>(
2584 jcompaction_opts_handle);
2585 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2586 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2587 if (jcf_handle == 0) {
2588 cf_handle = db->DefaultColumnFamily();
2589 } else {
2590 cf_handle =
2591 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2592 }
2593
2594 ROCKSDB_NAMESPACE::CompactionJobInfo* compaction_job_info = nullptr;
2595 if (jcompaction_job_info_handle != 0) {
2596 compaction_job_info =
2597 reinterpret_cast<ROCKSDB_NAMESPACE::CompactionJobInfo*>(
2598 jcompaction_job_info_handle);
2599 }
2600
2601 std::vector<std::string> output_file_names;
2602 auto s = db->CompactFiles(*compaction_opts, cf_handle, input_file_names,
2603 static_cast<int>(joutput_level), static_cast<int>(joutput_path_id),
2604 &output_file_names, compaction_job_info);
2605 if (!s.ok()) {
2606 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2607 return nullptr;
2608 }
2609
2610 return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &output_file_names);
2611 }
2612
2613 /*
2614 * Class: org_rocksdb_RocksDB
2615 * Method: pauseBackgroundWork
2616 * Signature: (J)V
2617 */
Java_org_rocksdb_RocksDB_pauseBackgroundWork(JNIEnv * env,jobject,jlong jdb_handle)2618 void Java_org_rocksdb_RocksDB_pauseBackgroundWork(
2619 JNIEnv* env, jobject, jlong jdb_handle) {
2620 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2621 auto s = db->PauseBackgroundWork();
2622 if (!s.ok()) {
2623 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2624 }
2625 }
2626
2627 /*
2628 * Class: org_rocksdb_RocksDB
2629 * Method: continueBackgroundWork
2630 * Signature: (J)V
2631 */
Java_org_rocksdb_RocksDB_continueBackgroundWork(JNIEnv * env,jobject,jlong jdb_handle)2632 void Java_org_rocksdb_RocksDB_continueBackgroundWork(
2633 JNIEnv* env, jobject, jlong jdb_handle) {
2634 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2635 auto s = db->ContinueBackgroundWork();
2636 if (!s.ok()) {
2637 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2638 }
2639 }
2640
2641 /*
2642 * Class: org_rocksdb_RocksDB
2643 * Method: enableAutoCompaction
2644 * Signature: (J[J)V
2645 */
Java_org_rocksdb_RocksDB_enableAutoCompaction(JNIEnv * env,jobject,jlong jdb_handle,jlongArray jcf_handles)2646 void Java_org_rocksdb_RocksDB_enableAutoCompaction(
2647 JNIEnv* env, jobject, jlong jdb_handle, jlongArray jcf_handles) {
2648 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2649 jboolean has_exception = JNI_FALSE;
2650 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles =
2651 ROCKSDB_NAMESPACE::JniUtil::fromJPointers<
2652 ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, jcf_handles,
2653 &has_exception);
2654 if (has_exception == JNI_TRUE) {
2655 // exception occurred
2656 return;
2657 }
2658 db->EnableAutoCompaction(cf_handles);
2659 }
2660
2661 /*
2662 * Class: org_rocksdb_RocksDB
2663 * Method: numberLevels
2664 * Signature: (JJ)I
2665 */
Java_org_rocksdb_RocksDB_numberLevels(JNIEnv *,jobject,jlong jdb_handle,jlong jcf_handle)2666 jint Java_org_rocksdb_RocksDB_numberLevels(
2667 JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) {
2668 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2669 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2670 if (jcf_handle == 0) {
2671 cf_handle = db->DefaultColumnFamily();
2672 } else {
2673 cf_handle =
2674 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2675 }
2676 return static_cast<jint>(db->NumberLevels(cf_handle));
2677 }
2678
2679 /*
2680 * Class: org_rocksdb_RocksDB
2681 * Method: maxMemCompactionLevel
2682 * Signature: (JJ)I
2683 */
Java_org_rocksdb_RocksDB_maxMemCompactionLevel(JNIEnv *,jobject,jlong jdb_handle,jlong jcf_handle)2684 jint Java_org_rocksdb_RocksDB_maxMemCompactionLevel(
2685 JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) {
2686 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2687 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2688 if (jcf_handle == 0) {
2689 cf_handle = db->DefaultColumnFamily();
2690 } else {
2691 cf_handle =
2692 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2693 }
2694 return static_cast<jint>(db->MaxMemCompactionLevel(cf_handle));
2695 }
2696
2697 /*
2698 * Class: org_rocksdb_RocksDB
2699 * Method: level0StopWriteTrigger
2700 * Signature: (JJ)I
2701 */
Java_org_rocksdb_RocksDB_level0StopWriteTrigger(JNIEnv *,jobject,jlong jdb_handle,jlong jcf_handle)2702 jint Java_org_rocksdb_RocksDB_level0StopWriteTrigger(
2703 JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) {
2704 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2705 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
2706 if (jcf_handle == 0) {
2707 cf_handle = db->DefaultColumnFamily();
2708 } else {
2709 cf_handle =
2710 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
2711 }
2712 return static_cast<jint>(db->Level0StopWriteTrigger(cf_handle));
2713 }
2714
2715 /*
2716 * Class: org_rocksdb_RocksDB
2717 * Method: getName
2718 * Signature: (J)Ljava/lang/String;
2719 */
Java_org_rocksdb_RocksDB_getName(JNIEnv * env,jobject,jlong jdb_handle)2720 jstring Java_org_rocksdb_RocksDB_getName(
2721 JNIEnv* env, jobject, jlong jdb_handle) {
2722 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2723 std::string name = db->GetName();
2724 return ROCKSDB_NAMESPACE::JniUtil::toJavaString(env, &name, false);
2725 }
2726
2727 /*
2728 * Class: org_rocksdb_RocksDB
2729 * Method: getEnv
2730 * Signature: (J)J
2731 */
Java_org_rocksdb_RocksDB_getEnv(JNIEnv *,jobject,jlong jdb_handle)2732 jlong Java_org_rocksdb_RocksDB_getEnv(
2733 JNIEnv*, jobject, jlong jdb_handle) {
2734 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2735 return reinterpret_cast<jlong>(db->GetEnv());
2736 }
2737
2738 /*
2739 * Class: org_rocksdb_RocksDB
2740 * Method: flush
2741 * Signature: (JJ[J)V
2742 */
Java_org_rocksdb_RocksDB_flush(JNIEnv * env,jobject,jlong jdb_handle,jlong jflush_opts_handle,jlongArray jcf_handles)2743 void Java_org_rocksdb_RocksDB_flush(
2744 JNIEnv* env, jobject, jlong jdb_handle, jlong jflush_opts_handle,
2745 jlongArray jcf_handles) {
2746 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2747 auto* flush_opts =
2748 reinterpret_cast<ROCKSDB_NAMESPACE::FlushOptions*>(jflush_opts_handle);
2749 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
2750 if (jcf_handles == nullptr) {
2751 cf_handles.push_back(db->DefaultColumnFamily());
2752 } else {
2753 jboolean has_exception = JNI_FALSE;
2754 cf_handles = ROCKSDB_NAMESPACE::JniUtil::fromJPointers<
2755 ROCKSDB_NAMESPACE::ColumnFamilyHandle>(env, jcf_handles,
2756 &has_exception);
2757 if (has_exception) {
2758 // exception occurred
2759 return;
2760 }
2761 }
2762 auto s = db->Flush(*flush_opts, cf_handles);
2763 if (!s.ok()) {
2764 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2765 }
2766 }
2767
2768 /*
2769 * Class: org_rocksdb_RocksDB
2770 * Method: flushWal
2771 * Signature: (JZ)V
2772 */
Java_org_rocksdb_RocksDB_flushWal(JNIEnv * env,jobject,jlong jdb_handle,jboolean jsync)2773 void Java_org_rocksdb_RocksDB_flushWal(
2774 JNIEnv* env, jobject, jlong jdb_handle, jboolean jsync) {
2775 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2776 auto s = db->FlushWAL(jsync == JNI_TRUE);
2777 if (!s.ok()) {
2778 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2779 }
2780 }
2781
2782 /*
2783 * Class: org_rocksdb_RocksDB
2784 * Method: syncWal
2785 * Signature: (J)V
2786 */
Java_org_rocksdb_RocksDB_syncWal(JNIEnv * env,jobject,jlong jdb_handle)2787 void Java_org_rocksdb_RocksDB_syncWal(
2788 JNIEnv* env, jobject, jlong jdb_handle) {
2789 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2790 auto s = db->SyncWAL();
2791 if (!s.ok()) {
2792 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2793 }
2794 }
2795
2796 /*
2797 * Class: org_rocksdb_RocksDB
2798 * Method: getLatestSequenceNumber
2799 * Signature: (J)V
2800 */
Java_org_rocksdb_RocksDB_getLatestSequenceNumber(JNIEnv *,jobject,jlong jdb_handle)2801 jlong Java_org_rocksdb_RocksDB_getLatestSequenceNumber(
2802 JNIEnv*, jobject, jlong jdb_handle) {
2803 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2804 return db->GetLatestSequenceNumber();
2805 }
2806
2807 /*
2808 * Class: org_rocksdb_RocksDB
2809 * Method: setPreserveDeletesSequenceNumber
2810 * Signature: (JJ)Z
2811 */
Java_org_rocksdb_RocksDB_setPreserveDeletesSequenceNumber(JNIEnv *,jobject,jlong jdb_handle,jlong jseq_number)2812 jboolean JNICALL Java_org_rocksdb_RocksDB_setPreserveDeletesSequenceNumber(
2813 JNIEnv*, jobject, jlong jdb_handle, jlong jseq_number) {
2814 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2815 if (db->SetPreserveDeletesSequenceNumber(
2816 static_cast<uint64_t>(jseq_number))) {
2817 return JNI_TRUE;
2818 } else {
2819 return JNI_FALSE;
2820 }
2821 }
2822
2823 /*
2824 * Class: org_rocksdb_RocksDB
2825 * Method: disableFileDeletions
2826 * Signature: (J)V
2827 */
Java_org_rocksdb_RocksDB_disableFileDeletions(JNIEnv * env,jobject,jlong jdb_handle)2828 void Java_org_rocksdb_RocksDB_disableFileDeletions(
2829 JNIEnv* env, jobject, jlong jdb_handle) {
2830 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2831 ROCKSDB_NAMESPACE::Status s = db->DisableFileDeletions();
2832 if (!s.ok()) {
2833 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2834 }
2835 }
2836
2837 /*
2838 * Class: org_rocksdb_RocksDB
2839 * Method: enableFileDeletions
2840 * Signature: (JZ)V
2841 */
Java_org_rocksdb_RocksDB_enableFileDeletions(JNIEnv * env,jobject,jlong jdb_handle,jboolean jforce)2842 void Java_org_rocksdb_RocksDB_enableFileDeletions(
2843 JNIEnv* env, jobject, jlong jdb_handle, jboolean jforce) {
2844 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2845 ROCKSDB_NAMESPACE::Status s = db->EnableFileDeletions(jforce);
2846 if (!s.ok()) {
2847 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2848 }
2849 }
2850
2851 /*
2852 * Class: org_rocksdb_RocksDB
2853 * Method: getLiveFiles
2854 * Signature: (JZ)[Ljava/lang/String;
2855 */
Java_org_rocksdb_RocksDB_getLiveFiles(JNIEnv * env,jobject,jlong jdb_handle,jboolean jflush_memtable)2856 jobjectArray Java_org_rocksdb_RocksDB_getLiveFiles(
2857 JNIEnv* env, jobject, jlong jdb_handle, jboolean jflush_memtable) {
2858 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2859 std::vector<std::string> live_files;
2860 uint64_t manifest_file_size = 0;
2861 auto s = db->GetLiveFiles(
2862 live_files, &manifest_file_size, jflush_memtable == JNI_TRUE);
2863 if (!s.ok()) {
2864 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2865 return nullptr;
2866 }
2867
2868 // append the manifest_file_size to the vector
2869 // for passing back to java
2870 live_files.push_back(std::to_string(manifest_file_size));
2871
2872 return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &live_files);
2873 }
2874
2875 /*
2876 * Class: org_rocksdb_RocksDB
2877 * Method: getSortedWalFiles
2878 * Signature: (J)[Lorg/rocksdb/LogFile;
2879 */
Java_org_rocksdb_RocksDB_getSortedWalFiles(JNIEnv * env,jobject,jlong jdb_handle)2880 jobjectArray Java_org_rocksdb_RocksDB_getSortedWalFiles(
2881 JNIEnv* env, jobject, jlong jdb_handle) {
2882 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2883 std::vector<std::unique_ptr<ROCKSDB_NAMESPACE::LogFile>> sorted_wal_files;
2884 auto s = db->GetSortedWalFiles(sorted_wal_files);
2885 if (!s.ok()) {
2886 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2887 return nullptr;
2888 }
2889
2890 // convert to Java type
2891 const jsize jlen = static_cast<jsize>(sorted_wal_files.size());
2892 jobjectArray jsorted_wal_files = env->NewObjectArray(
2893 jlen, ROCKSDB_NAMESPACE::LogFileJni::getJClass(env), nullptr);
2894 if(jsorted_wal_files == nullptr) {
2895 // exception thrown: OutOfMemoryError
2896 return nullptr;
2897 }
2898
2899 jsize i = 0;
2900 for (auto it = sorted_wal_files.begin(); it != sorted_wal_files.end(); ++it) {
2901 jobject jlog_file =
2902 ROCKSDB_NAMESPACE::LogFileJni::fromCppLogFile(env, it->get());
2903 if (jlog_file == nullptr) {
2904 // exception occurred
2905 env->DeleteLocalRef(jsorted_wal_files);
2906 return nullptr;
2907 }
2908
2909 env->SetObjectArrayElement(jsorted_wal_files, i++, jlog_file);
2910 if (env->ExceptionCheck()) {
2911 // exception occurred
2912 env->DeleteLocalRef(jlog_file);
2913 env->DeleteLocalRef(jsorted_wal_files);
2914 return nullptr;
2915 }
2916
2917 env->DeleteLocalRef(jlog_file);
2918 }
2919
2920 return jsorted_wal_files;
2921 }
2922
2923 /*
2924 * Class: org_rocksdb_RocksDB
2925 * Method: getUpdatesSince
2926 * Signature: (JJ)J
2927 */
Java_org_rocksdb_RocksDB_getUpdatesSince(JNIEnv * env,jobject,jlong jdb_handle,jlong jsequence_number)2928 jlong Java_org_rocksdb_RocksDB_getUpdatesSince(
2929 JNIEnv* env, jobject, jlong jdb_handle, jlong jsequence_number) {
2930 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2931 ROCKSDB_NAMESPACE::SequenceNumber sequence_number =
2932 static_cast<ROCKSDB_NAMESPACE::SequenceNumber>(jsequence_number);
2933 std::unique_ptr<ROCKSDB_NAMESPACE::TransactionLogIterator> iter;
2934 ROCKSDB_NAMESPACE::Status s = db->GetUpdatesSince(sequence_number, &iter);
2935 if (s.ok()) {
2936 return reinterpret_cast<jlong>(iter.release());
2937 }
2938
2939 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2940 return 0;
2941 }
2942
2943 /*
2944 * Class: org_rocksdb_RocksDB
2945 * Method: deleteFile
2946 * Signature: (JLjava/lang/String;)V
2947 */
Java_org_rocksdb_RocksDB_deleteFile(JNIEnv * env,jobject,jlong jdb_handle,jstring jname)2948 void Java_org_rocksdb_RocksDB_deleteFile(
2949 JNIEnv* env, jobject, jlong jdb_handle, jstring jname) {
2950 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2951 jboolean has_exception = JNI_FALSE;
2952 std::string name =
2953 ROCKSDB_NAMESPACE::JniUtil::copyStdString(env, jname, &has_exception);
2954 if (has_exception == JNI_TRUE) {
2955 // exception occurred
2956 return;
2957 }
2958 db->DeleteFile(name);
2959 }
2960
2961 /*
2962 * Class: org_rocksdb_RocksDB
2963 * Method: getLiveFilesMetaData
2964 * Signature: (J)[Lorg/rocksdb/LiveFileMetaData;
2965 */
Java_org_rocksdb_RocksDB_getLiveFilesMetaData(JNIEnv * env,jobject,jlong jdb_handle)2966 jobjectArray Java_org_rocksdb_RocksDB_getLiveFilesMetaData(
2967 JNIEnv* env, jobject, jlong jdb_handle) {
2968 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
2969 std::vector<ROCKSDB_NAMESPACE::LiveFileMetaData> live_files_meta_data;
2970 db->GetLiveFilesMetaData(&live_files_meta_data);
2971
2972 // convert to Java type
2973 const jsize jlen = static_cast<jsize>(live_files_meta_data.size());
2974 jobjectArray jlive_files_meta_data = env->NewObjectArray(
2975 jlen, ROCKSDB_NAMESPACE::LiveFileMetaDataJni::getJClass(env), nullptr);
2976 if(jlive_files_meta_data == nullptr) {
2977 // exception thrown: OutOfMemoryError
2978 return nullptr;
2979 }
2980
2981 jsize i = 0;
2982 for (auto it = live_files_meta_data.begin(); it != live_files_meta_data.end(); ++it) {
2983 jobject jlive_file_meta_data =
2984 ROCKSDB_NAMESPACE::LiveFileMetaDataJni::fromCppLiveFileMetaData(env,
2985 &(*it));
2986 if (jlive_file_meta_data == nullptr) {
2987 // exception occurred
2988 env->DeleteLocalRef(jlive_files_meta_data);
2989 return nullptr;
2990 }
2991
2992 env->SetObjectArrayElement(jlive_files_meta_data, i++, jlive_file_meta_data);
2993 if (env->ExceptionCheck()) {
2994 // exception occurred
2995 env->DeleteLocalRef(jlive_file_meta_data);
2996 env->DeleteLocalRef(jlive_files_meta_data);
2997 return nullptr;
2998 }
2999
3000 env->DeleteLocalRef(jlive_file_meta_data);
3001 }
3002
3003 return jlive_files_meta_data;
3004 }
3005
3006 /*
3007 * Class: org_rocksdb_RocksDB
3008 * Method: getColumnFamilyMetaData
3009 * Signature: (JJ)Lorg/rocksdb/ColumnFamilyMetaData;
3010 */
Java_org_rocksdb_RocksDB_getColumnFamilyMetaData(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle)3011 jobject Java_org_rocksdb_RocksDB_getColumnFamilyMetaData(
3012 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) {
3013 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3014 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
3015 if (jcf_handle == 0) {
3016 cf_handle = db->DefaultColumnFamily();
3017 } else {
3018 cf_handle =
3019 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3020 }
3021 ROCKSDB_NAMESPACE::ColumnFamilyMetaData cf_metadata;
3022 db->GetColumnFamilyMetaData(cf_handle, &cf_metadata);
3023 return ROCKSDB_NAMESPACE::ColumnFamilyMetaDataJni::
3024 fromCppColumnFamilyMetaData(env, &cf_metadata);
3025 }
3026
3027 /*
3028 * Class: org_rocksdb_RocksDB
3029 * Method: ingestExternalFile
3030 * Signature: (JJ[Ljava/lang/String;IJ)V
3031 */
Java_org_rocksdb_RocksDB_ingestExternalFile(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jobjectArray jfile_path_list,jint jfile_path_list_len,jlong jingest_external_file_options_handle)3032 void Java_org_rocksdb_RocksDB_ingestExternalFile(
3033 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
3034 jobjectArray jfile_path_list, jint jfile_path_list_len,
3035 jlong jingest_external_file_options_handle) {
3036 jboolean has_exception = JNI_FALSE;
3037 std::vector<std::string> file_path_list =
3038 ROCKSDB_NAMESPACE::JniUtil::copyStrings(
3039 env, jfile_path_list, jfile_path_list_len, &has_exception);
3040 if (has_exception == JNI_TRUE) {
3041 // exception occurred
3042 return;
3043 }
3044
3045 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3046 auto* column_family =
3047 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3048 auto* ifo = reinterpret_cast<ROCKSDB_NAMESPACE::IngestExternalFileOptions*>(
3049 jingest_external_file_options_handle);
3050 ROCKSDB_NAMESPACE::Status s =
3051 db->IngestExternalFile(column_family, file_path_list, *ifo);
3052 if (!s.ok()) {
3053 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3054 }
3055 }
3056
3057 /*
3058 * Class: org_rocksdb_RocksDB
3059 * Method: verifyChecksum
3060 * Signature: (J)V
3061 */
Java_org_rocksdb_RocksDB_verifyChecksum(JNIEnv * env,jobject,jlong jdb_handle)3062 void Java_org_rocksdb_RocksDB_verifyChecksum(
3063 JNIEnv* env, jobject, jlong jdb_handle) {
3064 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3065 auto s = db->VerifyChecksum();
3066 if (!s.ok()) {
3067 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3068 }
3069 }
3070
3071 /*
3072 * Class: org_rocksdb_RocksDB
3073 * Method: getDefaultColumnFamily
3074 * Signature: (J)J
3075 */
Java_org_rocksdb_RocksDB_getDefaultColumnFamily(JNIEnv *,jobject,jlong jdb_handle)3076 jlong Java_org_rocksdb_RocksDB_getDefaultColumnFamily(
3077 JNIEnv*, jobject, jlong jdb_handle) {
3078 auto* db_handle = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3079 auto* cf_handle = db_handle->DefaultColumnFamily();
3080 return reinterpret_cast<jlong>(cf_handle);
3081 }
3082
3083 /*
3084 * Class: org_rocksdb_RocksDB
3085 * Method: getPropertiesOfAllTables
3086 * Signature: (JJ)Ljava/util/Map;
3087 */
Java_org_rocksdb_RocksDB_getPropertiesOfAllTables(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle)3088 jobject Java_org_rocksdb_RocksDB_getPropertiesOfAllTables(
3089 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) {
3090 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3091 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
3092 if (jcf_handle == 0) {
3093 cf_handle = db->DefaultColumnFamily();
3094 } else {
3095 cf_handle =
3096 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3097 }
3098 ROCKSDB_NAMESPACE::TablePropertiesCollection table_properties_collection;
3099 auto s = db->GetPropertiesOfAllTables(cf_handle,
3100 &table_properties_collection);
3101 if (!s.ok()) {
3102 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3103 }
3104
3105 // convert to Java type
3106 jobject jhash_map = ROCKSDB_NAMESPACE::HashMapJni::construct(
3107 env, static_cast<uint32_t>(table_properties_collection.size()));
3108 if (jhash_map == nullptr) {
3109 // exception occurred
3110 return nullptr;
3111 }
3112
3113 const ROCKSDB_NAMESPACE::HashMapJni::FnMapKV<
3114 const std::string,
3115 const std::shared_ptr<const ROCKSDB_NAMESPACE::TableProperties>, jobject,
3116 jobject>
3117 fn_map_kv =
3118 [env](const std::pair<const std::string,
3119 const std::shared_ptr<
3120 const ROCKSDB_NAMESPACE::TableProperties>>&
3121 kv) {
3122 jstring jkey = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
3123 env, &(kv.first), false);
3124 if (env->ExceptionCheck()) {
3125 // an error occurred
3126 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
3127 }
3128
3129 jobject jtable_properties =
3130 ROCKSDB_NAMESPACE::TablePropertiesJni::fromCppTableProperties(
3131 env, *(kv.second.get()));
3132 if (jtable_properties == nullptr) {
3133 // an error occurred
3134 env->DeleteLocalRef(jkey);
3135 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
3136 }
3137
3138 return std::unique_ptr<std::pair<jobject, jobject>>(
3139 new std::pair<jobject, jobject>(
3140 static_cast<jobject>(jkey),
3141 static_cast<jobject>(jtable_properties)));
3142 };
3143
3144 if (!ROCKSDB_NAMESPACE::HashMapJni::putAll(
3145 env, jhash_map, table_properties_collection.begin(),
3146 table_properties_collection.end(), fn_map_kv)) {
3147 // exception occurred
3148 return nullptr;
3149 }
3150
3151 return jhash_map;
3152 }
3153
3154 /*
3155 * Class: org_rocksdb_RocksDB
3156 * Method: getPropertiesOfTablesInRange
3157 * Signature: (JJ[J)Ljava/util/Map;
3158 */
Java_org_rocksdb_RocksDB_getPropertiesOfTablesInRange(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jlongArray jrange_slice_handles)3159 jobject Java_org_rocksdb_RocksDB_getPropertiesOfTablesInRange(
3160 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle,
3161 jlongArray jrange_slice_handles) {
3162 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3163 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
3164 if (jcf_handle == 0) {
3165 cf_handle = db->DefaultColumnFamily();
3166 } else {
3167 cf_handle =
3168 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3169 }
3170 const jsize jlen = env->GetArrayLength(jrange_slice_handles);
3171 jboolean jrange_slice_handles_is_copy = JNI_FALSE;
3172 jlong *jrange_slice_handle = env->GetLongArrayElements(
3173 jrange_slice_handles, &jrange_slice_handles_is_copy);
3174 if (jrange_slice_handle == nullptr) {
3175 // exception occurred
3176 return nullptr;
3177 }
3178
3179 const size_t ranges_len = static_cast<size_t>(jlen / 2);
3180 auto ranges = std::unique_ptr<ROCKSDB_NAMESPACE::Range[]>(
3181 new ROCKSDB_NAMESPACE::Range[ranges_len]);
3182 for (jsize i = 0, j = 0; i < jlen; ++i) {
3183 auto* start =
3184 reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jrange_slice_handle[i]);
3185 auto* limit =
3186 reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(jrange_slice_handle[++i]);
3187 ranges[j++] = ROCKSDB_NAMESPACE::Range(*start, *limit);
3188 }
3189
3190 ROCKSDB_NAMESPACE::TablePropertiesCollection table_properties_collection;
3191 auto s = db->GetPropertiesOfTablesInRange(
3192 cf_handle, ranges.get(), ranges_len, &table_properties_collection);
3193 if (!s.ok()) {
3194 // error occurred
3195 env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle, JNI_ABORT);
3196 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3197 return nullptr;
3198 }
3199
3200 // cleanup
3201 env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle, JNI_ABORT);
3202
3203 return jrange_slice_handles;
3204 }
3205
3206 /*
3207 * Class: org_rocksdb_RocksDB
3208 * Method: suggestCompactRange
3209 * Signature: (JJ)[J
3210 */
Java_org_rocksdb_RocksDB_suggestCompactRange(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle)3211 jlongArray Java_org_rocksdb_RocksDB_suggestCompactRange(
3212 JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) {
3213 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3214 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
3215 if (jcf_handle == 0) {
3216 cf_handle = db->DefaultColumnFamily();
3217 } else {
3218 cf_handle =
3219 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3220 }
3221 auto* begin = new ROCKSDB_NAMESPACE::Slice();
3222 auto* end = new ROCKSDB_NAMESPACE::Slice();
3223 auto s = db->SuggestCompactRange(cf_handle, begin, end);
3224 if (!s.ok()) {
3225 // error occurred
3226 delete begin;
3227 delete end;
3228 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3229 return nullptr;
3230 }
3231
3232 jlongArray jslice_handles = env->NewLongArray(2);
3233 if (jslice_handles == nullptr) {
3234 // exception thrown: OutOfMemoryError
3235 delete begin;
3236 delete end;
3237 return nullptr;
3238 }
3239
3240 jlong slice_handles[2];
3241 slice_handles[0] = reinterpret_cast<jlong>(begin);
3242 slice_handles[1] = reinterpret_cast<jlong>(end);
3243 env->SetLongArrayRegion(jslice_handles, 0, 2, slice_handles);
3244 if (env->ExceptionCheck()) {
3245 // exception thrown: ArrayIndexOutOfBoundsException
3246 delete begin;
3247 delete end;
3248 env->DeleteLocalRef(jslice_handles);
3249 return nullptr;
3250 }
3251
3252 return jslice_handles;
3253 }
3254
3255 /*
3256 * Class: org_rocksdb_RocksDB
3257 * Method: promoteL0
3258 * Signature: (JJI)V
3259 */
Java_org_rocksdb_RocksDB_promoteL0(JNIEnv *,jobject,jlong jdb_handle,jlong jcf_handle,jint jtarget_level)3260 void Java_org_rocksdb_RocksDB_promoteL0(
3261 JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle, jint jtarget_level) {
3262 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3263 ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf_handle;
3264 if (jcf_handle == 0) {
3265 cf_handle = db->DefaultColumnFamily();
3266 } else {
3267 cf_handle =
3268 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3269 }
3270 db->PromoteL0(cf_handle, static_cast<int>(jtarget_level));
3271 }
3272
3273 /*
3274 * Class: org_rocksdb_RocksDB
3275 * Method: startTrace
3276 * Signature: (JJJ)V
3277 */
Java_org_rocksdb_RocksDB_startTrace(JNIEnv * env,jobject,jlong jdb_handle,jlong jmax_trace_file_size,jlong jtrace_writer_jnicallback_handle)3278 void Java_org_rocksdb_RocksDB_startTrace(
3279 JNIEnv* env, jobject, jlong jdb_handle, jlong jmax_trace_file_size,
3280 jlong jtrace_writer_jnicallback_handle) {
3281 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3282 ROCKSDB_NAMESPACE::TraceOptions trace_options;
3283 trace_options.max_trace_file_size =
3284 static_cast<uint64_t>(jmax_trace_file_size);
3285 // transfer ownership of trace writer from Java to C++
3286 auto trace_writer =
3287 std::unique_ptr<ROCKSDB_NAMESPACE::TraceWriterJniCallback>(
3288 reinterpret_cast<ROCKSDB_NAMESPACE::TraceWriterJniCallback*>(
3289 jtrace_writer_jnicallback_handle));
3290 auto s = db->StartTrace(trace_options, std::move(trace_writer));
3291 if (!s.ok()) {
3292 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3293 }
3294 }
3295
3296 /*
3297 * Class: org_rocksdb_RocksDB
3298 * Method: endTrace
3299 * Signature: (J)V
3300 */
Java_org_rocksdb_RocksDB_endTrace(JNIEnv * env,jobject,jlong jdb_handle)3301 JNIEXPORT void JNICALL Java_org_rocksdb_RocksDB_endTrace(
3302 JNIEnv* env, jobject, jlong jdb_handle) {
3303 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3304 auto s = db->EndTrace();
3305 if (!s.ok()) {
3306 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3307 }
3308 }
3309
3310 /*
3311 * Class: org_rocksdb_RocksDB
3312 * Method: destroyDB
3313 * Signature: (Ljava/lang/String;J)V
3314 */
Java_org_rocksdb_RocksDB_destroyDB(JNIEnv * env,jclass,jstring jdb_path,jlong joptions_handle)3315 void Java_org_rocksdb_RocksDB_destroyDB(
3316 JNIEnv* env, jclass, jstring jdb_path, jlong joptions_handle) {
3317 const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
3318 if (db_path == nullptr) {
3319 // exception thrown: OutOfMemoryError
3320 return;
3321 }
3322
3323 auto* options =
3324 reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(joptions_handle);
3325 if (options == nullptr) {
3326 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
3327 env, ROCKSDB_NAMESPACE::Status::InvalidArgument("Invalid Options."));
3328 }
3329
3330 ROCKSDB_NAMESPACE::Status s = ROCKSDB_NAMESPACE::DestroyDB(db_path, *options);
3331 env->ReleaseStringUTFChars(jdb_path, db_path);
3332
3333 if (!s.ok()) {
3334 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3335 }
3336 }
3337
get_slice_helper(JNIEnv * env,jobjectArray ranges,jsize index,std::unique_ptr<ROCKSDB_NAMESPACE::Slice> & slice,std::vector<std::unique_ptr<jbyte[]>> & ranges_to_free)3338 bool get_slice_helper(JNIEnv* env, jobjectArray ranges, jsize index,
3339 std::unique_ptr<ROCKSDB_NAMESPACE::Slice>& slice,
3340 std::vector<std::unique_ptr<jbyte[]>>& ranges_to_free) {
3341 jobject jArray = env->GetObjectArrayElement(ranges, index);
3342 if (env->ExceptionCheck()) {
3343 // exception thrown: ArrayIndexOutOfBoundsException
3344 return false;
3345 }
3346
3347 if (jArray == nullptr) {
3348 return true;
3349 }
3350
3351 jbyteArray jba = reinterpret_cast<jbyteArray>(jArray);
3352 jsize len_ba = env->GetArrayLength(jba);
3353 ranges_to_free.push_back(std::unique_ptr<jbyte[]>(new jbyte[len_ba]));
3354 env->GetByteArrayRegion(jba, 0, len_ba, ranges_to_free.back().get());
3355 if (env->ExceptionCheck()) {
3356 // exception thrown: ArrayIndexOutOfBoundsException
3357 env->DeleteLocalRef(jArray);
3358 return false;
3359 }
3360 env->DeleteLocalRef(jArray);
3361 slice.reset(new ROCKSDB_NAMESPACE::Slice(
3362 reinterpret_cast<char*>(ranges_to_free.back().get()), len_ba));
3363 return true;
3364 }
3365 /*
3366 * Class: org_rocksdb_RocksDB
3367 * Method: deleteFilesInRanges
3368 * Signature: (JJLjava/util/List;Z)V
3369 */
Java_org_rocksdb_RocksDB_deleteFilesInRanges(JNIEnv * env,jobject,jlong jdb_handle,jlong jcf_handle,jobjectArray ranges,jboolean include_end)3370 JNIEXPORT void JNICALL Java_org_rocksdb_RocksDB_deleteFilesInRanges(
3371 JNIEnv* env, jobject /*jdb*/, jlong jdb_handle, jlong jcf_handle,
3372 jobjectArray ranges, jboolean include_end) {
3373 jsize length = env->GetArrayLength(ranges);
3374
3375 std::vector<ROCKSDB_NAMESPACE::RangePtr> rangesVector;
3376 std::vector<std::unique_ptr<ROCKSDB_NAMESPACE::Slice>> slices;
3377 std::vector<std::unique_ptr<jbyte[]>> ranges_to_free;
3378 for (jsize i = 0; (i + 1) < length; i += 2) {
3379 slices.push_back(std::unique_ptr<ROCKSDB_NAMESPACE::Slice>());
3380 if (!get_slice_helper(env, ranges, i, slices.back(), ranges_to_free)) {
3381 // exception thrown
3382 return;
3383 }
3384
3385 slices.push_back(std::unique_ptr<ROCKSDB_NAMESPACE::Slice>());
3386 if (!get_slice_helper(env, ranges, i + 1, slices.back(), ranges_to_free)) {
3387 // exception thrown
3388 return;
3389 }
3390
3391 rangesVector.push_back(ROCKSDB_NAMESPACE::RangePtr(
3392 slices[slices.size() - 2].get(), slices[slices.size() - 1].get()));
3393 }
3394
3395 auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
3396 auto* column_family =
3397 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcf_handle);
3398
3399 ROCKSDB_NAMESPACE::Status s = ROCKSDB_NAMESPACE::DeleteFilesInRanges(
3400 db, column_family == nullptr ? db->DefaultColumnFamily() : column_family,
3401 rangesVector.data(), rangesVector.size(), include_end);
3402
3403 if (!s.ok()) {
3404 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
3405 }
3406 }
3407