]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/java/rocksjni/portal.h
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / rocksdb / java / rocksjni / portal.h
CommitLineData
7c673cae
FG
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under the BSD-style license found in the
3// LICENSE file in the root directory of this source tree. An additional grant
4// of patent rights can be found in the PATENTS file in the same directory.
5
6// This file is designed for caching those frequently used IDs and provide
7// efficient portal (i.e, a set of static functions) to access java code
8// from c++.
9
10#ifndef JAVA_ROCKSJNI_PORTAL_H_
11#define JAVA_ROCKSJNI_PORTAL_H_
12
13#include <jni.h>
14#include <functional>
15#include <iostream>
16#include <limits>
17#include <string>
18#include <vector>
19
20#include "rocksdb/db.h"
21#include "rocksdb/filter_policy.h"
22#include "rocksdb/status.h"
23#include "rocksdb/utilities/backupable_db.h"
24#include "rocksdb/utilities/write_batch_with_index.h"
25#include "rocksjni/comparatorjnicallback.h"
26#include "rocksjni/loggerjnicallback.h"
27#include "rocksjni/writebatchhandlerjnicallback.h"
28
29// Remove macro on windows
30#ifdef DELETE
31#undef DELETE
32#endif
33
34namespace rocksdb {
35
36// Detect if jlong overflows size_t
37inline Status check_if_jlong_fits_size_t(const jlong& jvalue) {
38 Status s = Status::OK();
39 if (static_cast<uint64_t>(jvalue) > std::numeric_limits<size_t>::max()) {
40 s = Status::InvalidArgument(Slice("jlong overflows 32 bit value."));
41 }
42 return s;
43}
44
45class JavaClass {
46 public:
47 /**
48 * Gets and initializes a Java Class
49 *
50 * @param env A pointer to the Java environment
51 * @param jclazz_name The fully qualified JNI name of the Java Class
52 * e.g. "java/lang/String"
53 *
54 * @return The Java Class or nullptr if one of the
55 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
56 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
57 */
58 static jclass getJClass(JNIEnv* env, const char* jclazz_name) {
59 jclass jclazz = env->FindClass(jclazz_name);
60 assert(jclazz != nullptr);
61 return jclazz;
62 }
63};
64
65// Native class template
66template<class PTR, class DERIVED> class RocksDBNativeClass : public JavaClass {
67};
68
69// Native class template for sub-classes of RocksMutableObject
70template<class PTR, class DERIVED> class NativeRocksMutableObject
71 : public RocksDBNativeClass<PTR, DERIVED> {
72 public:
73
74 /**
75 * Gets the Java Method ID for the
76 * RocksMutableObject#setNativeHandle(long, boolean) method
77 *
78 * @param env A pointer to the Java environment
79 * @return The Java Method ID or nullptr the RocksMutableObject class cannot
80 * be accessed, or if one of the NoSuchMethodError,
81 * ExceptionInInitializerError or OutOfMemoryError exceptions is thrown
82 */
83 static jmethodID getSetNativeHandleMethod(JNIEnv* env) {
84 static jclass jclazz = DERIVED::getJClass(env);
85 if(jclazz == nullptr) {
86 return nullptr;
87 }
88
89 static jmethodID mid = env->GetMethodID(
90 jclazz, "setNativeHandle", "(JZ)V");
91 assert(mid != nullptr);
92 return mid;
93 }
94
95 /**
96 * Sets the C++ object pointer handle in the Java object
97 *
98 * @param env A pointer to the Java environment
99 * @param jobj The Java object on which to set the pointer handle
100 * @param ptr The C++ object pointer
101 * @param java_owns_handle JNI_TRUE if ownership of the C++ object is
102 * managed by the Java object
103 *
104 * @return true if a Java exception is pending, false otherwise
105 */
106 static bool setHandle(JNIEnv* env, jobject jobj, PTR ptr,
107 jboolean java_owns_handle) {
108 assert(jobj != nullptr);
109 static jmethodID mid = getSetNativeHandleMethod(env);
110 if(mid == nullptr) {
111 return true; // signal exception
112 }
113
114 env->CallVoidMethod(jobj, mid, reinterpret_cast<jlong>(ptr), java_owns_handle);
115 if(env->ExceptionCheck()) {
116 return true; // signal exception
117 }
118
119 return false;
120 }
121};
122
123// Java Exception template
124template<class DERIVED> class JavaException : public JavaClass {
125 public:
126 /**
127 * Create and throw a java exception with the provided message
128 *
129 * @param env A pointer to the Java environment
130 * @param msg The message for the exception
131 *
132 * @return true if an exception was thrown, false otherwise
133 */
134 static bool ThrowNew(JNIEnv* env, const std::string& msg) {
135 jclass jclazz = DERIVED::getJClass(env);
136 if(jclazz == nullptr) {
137 // exception occurred accessing class
138 std::cerr << "JavaException::ThrowNew - Error: unexpected exception!" << std::endl;
139 return env->ExceptionCheck();
140 }
141
142 const jint rs = env->ThrowNew(jclazz, msg.c_str());
143 if(rs != JNI_OK) {
144 // exception could not be thrown
145 std::cerr << "JavaException::ThrowNew - Fatal: could not throw exception!" << std::endl;
146 return env->ExceptionCheck();
147 }
148
149 return true;
150 }
151};
152
153// The portal class for org.rocksdb.RocksDB
154class RocksDBJni : public RocksDBNativeClass<rocksdb::DB*, RocksDBJni> {
155 public:
156 /**
157 * Get the Java Class org.rocksdb.RocksDB
158 *
159 * @param env A pointer to the Java environment
160 *
161 * @return The Java Class or nullptr if one of the
162 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
163 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
164 */
165 static jclass getJClass(JNIEnv* env) {
166 return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksDB");
167 }
168};
169
170// The portal class for org.rocksdb.Status
171class StatusJni : public RocksDBNativeClass<rocksdb::Status*, StatusJni> {
172 public:
173 /**
174 * Get the Java Class org.rocksdb.Status
175 *
176 * @param env A pointer to the Java environment
177 *
178 * @return The Java Class or nullptr if one of the
179 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
180 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
181 */
182 static jclass getJClass(JNIEnv* env) {
183 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Status");
184 }
185
186 /**
187 * Create a new Java org.rocksdb.Status object with the same properties as
188 * the provided C++ rocksdb::Status object
189 *
190 * @param env A pointer to the Java environment
191 * @param status The rocksdb::Status object
192 *
193 * @return A reference to a Java org.rocksdb.Status object, or nullptr
194 * if an an exception occurs
195 */
196 static jobject construct(JNIEnv* env, const Status& status) {
197 jclass jclazz = getJClass(env);
198 if(jclazz == nullptr) {
199 // exception occurred accessing class
200 return nullptr;
201 }
202
203 jmethodID mid =
204 env->GetMethodID(jclazz, "<init>", "(BBLjava/lang/String;)V");
205 if(mid == nullptr) {
206 // exception thrown: NoSuchMethodException or OutOfMemoryError
207 return nullptr;
208 }
209
210 // convert the Status state for Java
211 jstring jstate = nullptr;
212 if (status.getState() != nullptr) {
213 const char* const state = status.getState();
214 jstate = env->NewStringUTF(state);
215 if(env->ExceptionCheck()) {
216 if(jstate != nullptr) {
217 env->DeleteLocalRef(jstate);
218 }
219 return nullptr;
220 }
221 }
222
223 jobject jstatus =
224 env->NewObject(jclazz, mid, toJavaStatusCode(status.code()),
225 toJavaStatusSubCode(status.subcode()), jstate);
226 if(env->ExceptionCheck()) {
227 // exception occurred
228 if(jstate != nullptr) {
229 env->DeleteLocalRef(jstate);
230 }
231 return nullptr;
232 }
233
234 if(jstate != nullptr) {
235 env->DeleteLocalRef(jstate);
236 }
237
238 return jstatus;
239 }
240
241 // Returns the equivalent org.rocksdb.Status.Code for the provided
242 // C++ rocksdb::Status::Code enum
243 static jbyte toJavaStatusCode(const rocksdb::Status::Code& code) {
244 switch (code) {
245 case rocksdb::Status::Code::kOk:
246 return 0x0;
247 case rocksdb::Status::Code::kNotFound:
248 return 0x1;
249 case rocksdb::Status::Code::kCorruption:
250 return 0x2;
251 case rocksdb::Status::Code::kNotSupported:
252 return 0x3;
253 case rocksdb::Status::Code::kInvalidArgument:
254 return 0x4;
255 case rocksdb::Status::Code::kIOError:
256 return 0x5;
257 case rocksdb::Status::Code::kMergeInProgress:
258 return 0x6;
259 case rocksdb::Status::Code::kIncomplete:
260 return 0x7;
261 case rocksdb::Status::Code::kShutdownInProgress:
262 return 0x8;
263 case rocksdb::Status::Code::kTimedOut:
264 return 0x9;
265 case rocksdb::Status::Code::kAborted:
266 return 0xA;
267 case rocksdb::Status::Code::kBusy:
268 return 0xB;
269 case rocksdb::Status::Code::kExpired:
270 return 0xC;
271 case rocksdb::Status::Code::kTryAgain:
272 return 0xD;
273 default:
274 return 0x7F; // undefined
275 }
276 }
277
278 // Returns the equivalent org.rocksdb.Status.SubCode for the provided
279 // C++ rocksdb::Status::SubCode enum
280 static jbyte toJavaStatusSubCode(const rocksdb::Status::SubCode& subCode) {
281 switch (subCode) {
282 case rocksdb::Status::SubCode::kNone:
283 return 0x0;
284 case rocksdb::Status::SubCode::kMutexTimeout:
285 return 0x1;
286 case rocksdb::Status::SubCode::kLockTimeout:
287 return 0x2;
288 case rocksdb::Status::SubCode::kLockLimit:
289 return 0x3;
290 case rocksdb::Status::SubCode::kMaxSubCode:
291 return 0x7E;
292 default:
293 return 0x7F; // undefined
294 }
295 }
296};
297
298// The portal class for org.rocksdb.RocksDBException
299class RocksDBExceptionJni :
300 public JavaException<RocksDBExceptionJni> {
301 public:
302 /**
303 * Get the Java Class org.rocksdb.RocksDBException
304 *
305 * @param env A pointer to the Java environment
306 *
307 * @return The Java Class or nullptr if one of the
308 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
309 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
310 */
311 static jclass getJClass(JNIEnv* env) {
312 return JavaException::getJClass(env, "org/rocksdb/RocksDBException");
313 }
314
315 /**
316 * Create and throw a Java RocksDBException with the provided message
317 *
318 * @param env A pointer to the Java environment
319 * @param msg The message for the exception
320 *
321 * @return true if an exception was thrown, false otherwise
322 */
323 static bool ThrowNew(JNIEnv* env, const std::string& msg) {
324 return JavaException::ThrowNew(env, msg);
325 }
326
327 /**
328 * Create and throw a Java RocksDBException with the provided status
329 *
330 * If s.ok() == true, then this function will not throw any exception.
331 *
332 * @param env A pointer to the Java environment
333 * @param s The status for the exception
334 *
335 * @return true if an exception was thrown, false otherwise
336 */
337 static bool ThrowNew(JNIEnv* env, const Status& s) {
338 assert(!s.ok());
339 if (s.ok()) {
340 return false;
341 }
342
343 // get the RocksDBException class
344 jclass jclazz = getJClass(env);
345 if(jclazz == nullptr) {
346 // exception occurred accessing class
347 std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
348 return env->ExceptionCheck();
349 }
350
351 // get the constructor of org.rocksdb.RocksDBException
352 jmethodID mid =
353 env->GetMethodID(jclazz, "<init>", "(Lorg/rocksdb/Status;)V");
354 if(mid == nullptr) {
355 // exception thrown: NoSuchMethodException or OutOfMemoryError
356 std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
357 return env->ExceptionCheck();
358 }
359
360 // get the Java status object
361 jobject jstatus = StatusJni::construct(env, s);
362 if(jstatus == nullptr) {
363 // exception occcurred
364 std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
365 return env->ExceptionCheck();
366 }
367
368 // construct the RocksDBException
369 jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jstatus));
370 if(env->ExceptionCheck()) {
371 if(jstatus != nullptr) {
372 env->DeleteLocalRef(jstatus);
373 }
374 if(rocksdb_exception != nullptr) {
375 env->DeleteLocalRef(rocksdb_exception);
376 }
377 std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
378 return true;
379 }
380
381 // throw the RocksDBException
382 const jint rs = env->Throw(rocksdb_exception);
383 if(rs != JNI_OK) {
384 // exception could not be thrown
385 std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
386 if(jstatus != nullptr) {
387 env->DeleteLocalRef(jstatus);
388 }
389 if(rocksdb_exception != nullptr) {
390 env->DeleteLocalRef(rocksdb_exception);
391 }
392 return env->ExceptionCheck();
393 }
394
395 if(jstatus != nullptr) {
396 env->DeleteLocalRef(jstatus);
397 }
398 if(rocksdb_exception != nullptr) {
399 env->DeleteLocalRef(rocksdb_exception);
400 }
401
402 return true;
403 }
404
405 /**
406 * Create and throw a Java RocksDBException with the provided message
407 * and status
408 *
409 * If s.ok() == true, then this function will not throw any exception.
410 *
411 * @param env A pointer to the Java environment
412 * @param msg The message for the exception
413 * @param s The status for the exception
414 *
415 * @return true if an exception was thrown, false otherwise
416 */
417 static bool ThrowNew(JNIEnv* env, const std::string& msg, const Status& s) {
418 assert(!s.ok());
419 if (s.ok()) {
420 return false;
421 }
422
423 // get the RocksDBException class
424 jclass jclazz = getJClass(env);
425 if(jclazz == nullptr) {
426 // exception occurred accessing class
427 std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
428 return env->ExceptionCheck();
429 }
430
431 // get the constructor of org.rocksdb.RocksDBException
432 jmethodID mid =
433 env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;Lorg/rocksdb/Status;)V");
434 if(mid == nullptr) {
435 // exception thrown: NoSuchMethodException or OutOfMemoryError
436 std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
437 return env->ExceptionCheck();
438 }
439
440 jstring jmsg = env->NewStringUTF(msg.c_str());
441 if(jmsg == nullptr) {
442 // exception thrown: OutOfMemoryError
443 std::cerr << "RocksDBExceptionJni::ThrowNew/msg - Error: unexpected exception!" << std::endl;
444 return env->ExceptionCheck();
445 }
446
447 // get the Java status object
448 jobject jstatus = StatusJni::construct(env, s);
449 if(jstatus == nullptr) {
450 // exception occcurred
451 std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
452 if(jmsg != nullptr) {
453 env->DeleteLocalRef(jmsg);
454 }
455 return env->ExceptionCheck();
456 }
457
458 // construct the RocksDBException
459 jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jmsg, jstatus));
460 if(env->ExceptionCheck()) {
461 if(jstatus != nullptr) {
462 env->DeleteLocalRef(jstatus);
463 }
464 if(jmsg != nullptr) {
465 env->DeleteLocalRef(jmsg);
466 }
467 if(rocksdb_exception != nullptr) {
468 env->DeleteLocalRef(rocksdb_exception);
469 }
470 std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
471 return true;
472 }
473
474 // throw the RocksDBException
475 const jint rs = env->Throw(rocksdb_exception);
476 if(rs != JNI_OK) {
477 // exception could not be thrown
478 std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
479 if(jstatus != nullptr) {
480 env->DeleteLocalRef(jstatus);
481 }
482 if(jmsg != nullptr) {
483 env->DeleteLocalRef(jmsg);
484 }
485 if(rocksdb_exception != nullptr) {
486 env->DeleteLocalRef(rocksdb_exception);
487 }
488 return env->ExceptionCheck();
489 }
490
491 if(jstatus != nullptr) {
492 env->DeleteLocalRef(jstatus);
493 }
494 if(jmsg != nullptr) {
495 env->DeleteLocalRef(jmsg);
496 }
497 if(rocksdb_exception != nullptr) {
498 env->DeleteLocalRef(rocksdb_exception);
499 }
500
501 return true;
502 }
503};
504
505// The portal class for java.lang.IllegalArgumentException
506class IllegalArgumentExceptionJni :
507 public JavaException<IllegalArgumentExceptionJni> {
508 public:
509 /**
510 * Get the Java Class java.lang.IllegalArgumentException
511 *
512 * @param env A pointer to the Java environment
513 *
514 * @return The Java Class or nullptr if one of the
515 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
516 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
517 */
518 static jclass getJClass(JNIEnv* env) {
519 return JavaException::getJClass(env, "java/lang/IllegalArgumentException");
520 }
521
522 /**
523 * Create and throw a Java IllegalArgumentException with the provided status
524 *
525 * If s.ok() == true, then this function will not throw any exception.
526 *
527 * @param env A pointer to the Java environment
528 * @param s The status for the exception
529 *
530 * @return true if an exception was thrown, false otherwise
531 */
532 static bool ThrowNew(JNIEnv* env, const Status& s) {
533 assert(!s.ok());
534 if (s.ok()) {
535 return false;
536 }
537
538 // get the IllegalArgumentException class
539 jclass jclazz = getJClass(env);
540 if(jclazz == nullptr) {
541 // exception occurred accessing class
542 std::cerr << "IllegalArgumentExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
543 return env->ExceptionCheck();
544 }
545
546 return JavaException::ThrowNew(env, s.ToString());
547 }
548};
549
550
551// The portal class for org.rocksdb.Options
552class OptionsJni : public RocksDBNativeClass<
553 rocksdb::Options*, OptionsJni> {
554 public:
555 /**
556 * Get the Java Class org.rocksdb.Options
557 *
558 * @param env A pointer to the Java environment
559 *
560 * @return The Java Class or nullptr if one of the
561 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
562 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
563 */
564 static jclass getJClass(JNIEnv* env) {
565 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Options");
566 }
567};
568
569// The portal class for org.rocksdb.DBOptions
570class DBOptionsJni : public RocksDBNativeClass<
571 rocksdb::DBOptions*, DBOptionsJni> {
572 public:
573 /**
574 * Get the Java Class org.rocksdb.DBOptions
575 *
576 * @param env A pointer to the Java environment
577 *
578 * @return The Java Class or nullptr if one of the
579 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
580 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
581 */
582 static jclass getJClass(JNIEnv* env) {
583 return RocksDBNativeClass::getJClass(env, "org/rocksdb/DBOptions");
584 }
585};
586
587class ColumnFamilyDescriptorJni : public JavaClass {
588 public:
589 /**
590 * Get the Java Class org.rocksdb.ColumnFamilyDescriptor
591 *
592 * @param env A pointer to the Java environment
593 *
594 * @return The Java Class or nullptr if one of the
595 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
596 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
597 */
598 static jclass getJClass(JNIEnv* env) {
599 return JavaClass::getJClass(env, "org/rocksdb/ColumnFamilyDescriptor");
600 }
601
602 /**
603 * Get the Java Method: ColumnFamilyDescriptor#columnFamilyName
604 *
605 * @param env A pointer to the Java environment
606 *
607 * @return The Java Method ID or nullptr if the class or method id could not
608 * be retieved
609 */
610 static jmethodID getColumnFamilyNameMethod(JNIEnv* env) {
611 jclass jclazz = getJClass(env);
612 if(jclazz == nullptr) {
613 // exception occurred accessing class
614 return nullptr;
615 }
616
617 static jmethodID mid =
618 env->GetMethodID(jclazz, "columnFamilyName", "()[B");
619 assert(mid != nullptr);
620 return mid;
621 }
622
623 /**
624 * Get the Java Method: ColumnFamilyDescriptor#columnFamilyOptions
625 *
626 * @param env A pointer to the Java environment
627 *
628 * @return The Java Method ID or nullptr if the class or method id could not
629 * be retieved
630 */
631 static jmethodID getColumnFamilyOptionsMethod(JNIEnv* env) {
632 jclass jclazz = getJClass(env);
633 if(jclazz == nullptr) {
634 // exception occurred accessing class
635 return nullptr;
636 }
637
638 static jmethodID mid =
639 env->GetMethodID(jclazz, "columnFamilyOptions",
640 "()Lorg/rocksdb/ColumnFamilyOptions;");
641 assert(mid != nullptr);
642 return mid;
643 }
644};
645
646// The portal class for org.rocksdb.ColumnFamilyOptions
647class ColumnFamilyOptionsJni : public RocksDBNativeClass<
648 rocksdb::ColumnFamilyOptions*, ColumnFamilyOptionsJni> {
649 public:
650 /**
651 * Get the Java Class org.rocksdb.ColumnFamilyOptions
652 *
653 * @param env A pointer to the Java environment
654 *
655 * @return The Java Class or nullptr if one of the
656 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
657 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
658 */
659 static jclass getJClass(JNIEnv* env) {
660 return RocksDBNativeClass::getJClass(env,
661 "org/rocksdb/ColumnFamilyOptions");
662 }
663};
664
665// The portal class for org.rocksdb.WriteOptions
666class WriteOptionsJni : public RocksDBNativeClass<
667 rocksdb::WriteOptions*, WriteOptionsJni> {
668 public:
669 /**
670 * Get the Java Class org.rocksdb.WriteOptions
671 *
672 * @param env A pointer to the Java environment
673 *
674 * @return The Java Class or nullptr if one of the
675 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
676 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
677 */
678 static jclass getJClass(JNIEnv* env) {
679 return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteOptions");
680 }
681};
682
683// The portal class for org.rocksdb.ReadOptions
684class ReadOptionsJni : public RocksDBNativeClass<
685 rocksdb::ReadOptions*, ReadOptionsJni> {
686 public:
687 /**
688 * Get the Java Class org.rocksdb.ReadOptions
689 *
690 * @param env A pointer to the Java environment
691 *
692 * @return The Java Class or nullptr if one of the
693 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
694 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
695 */
696 static jclass getJClass(JNIEnv* env) {
697 return RocksDBNativeClass::getJClass(env, "org/rocksdb/ReadOptions");
698 }
699};
700
701// The portal class for org.rocksdb.WriteBatch
702class WriteBatchJni : public RocksDBNativeClass<
703 rocksdb::WriteBatch*, WriteBatchJni> {
704 public:
705 /**
706 * Get the Java Class org.rocksdb.WriteBatch
707 *
708 * @param env A pointer to the Java environment
709 *
710 * @return The Java Class or nullptr if one of the
711 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
712 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
713 */
714 static jclass getJClass(JNIEnv* env) {
715 return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteBatch");
716 }
717};
718
719// The portal class for org.rocksdb.WriteBatch.Handler
720class WriteBatchHandlerJni : public RocksDBNativeClass<
721 const rocksdb::WriteBatchHandlerJniCallback*,
722 WriteBatchHandlerJni> {
723 public:
724 /**
725 * Get the Java Class org.rocksdb.WriteBatch.Handler
726 *
727 * @param env A pointer to the Java environment
728 *
729 * @return The Java Class or nullptr if one of the
730 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
731 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
732 */
733 static jclass getJClass(JNIEnv* env) {
734 return RocksDBNativeClass::getJClass(env,
735 "org/rocksdb/WriteBatch$Handler");
736 }
737
738 /**
739 * Get the Java Method: WriteBatch.Handler#put
740 *
741 * @param env A pointer to the Java environment
742 *
743 * @return The Java Method ID or nullptr if the class or method id could not
744 * be retieved
745 */
746 static jmethodID getPutMethodId(JNIEnv* env) {
747 jclass jclazz = getJClass(env);
748 if(jclazz == nullptr) {
749 // exception occurred accessing class
750 return nullptr;
751 }
752
753 static jmethodID mid = env->GetMethodID(jclazz, "put", "([B[B)V");
754 assert(mid != nullptr);
755 return mid;
756 }
757
758 /**
759 * Get the Java Method: WriteBatch.Handler#merge
760 *
761 * @param env A pointer to the Java environment
762 *
763 * @return The Java Method ID or nullptr if the class or method id could not
764 * be retieved
765 */
766 static jmethodID getMergeMethodId(JNIEnv* env) {
767 jclass jclazz = getJClass(env);
768 if(jclazz == nullptr) {
769 // exception occurred accessing class
770 return nullptr;
771 }
772
773 static jmethodID mid = env->GetMethodID(jclazz, "merge", "([B[B)V");
774 assert(mid != nullptr);
775 return mid;
776 }
777
778 /**
779 * Get the Java Method: WriteBatch.Handler#delete
780 *
781 * @param env A pointer to the Java environment
782 *
783 * @return The Java Method ID or nullptr if the class or method id could not
784 * be retieved
785 */
786 static jmethodID getDeleteMethodId(JNIEnv* env) {
787 jclass jclazz = getJClass(env);
788 if(jclazz == nullptr) {
789 // exception occurred accessing class
790 return nullptr;
791 }
792
793 static jmethodID mid = env->GetMethodID(jclazz, "delete", "([B)V");
794 assert(mid != nullptr);
795 return mid;
796 }
797
798 /**
799 * Get the Java Method: WriteBatch.Handler#deleteRange
800 *
801 * @param env A pointer to the Java environment
802 *
803 * @return The Java Method ID or nullptr if the class or method id could not
804 * be retieved
805 */
806 static jmethodID getDeleteRangeMethodId(JNIEnv* env) {
807 jclass jclazz = getJClass(env);
808 if (jclazz == nullptr) {
809 // exception occurred accessing class
810 return nullptr;
811 }
812
813 static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "([B[B)V");
814 assert(mid != nullptr);
815 return mid;
816 }
817
818 /**
819 * Get the Java Method: WriteBatch.Handler#logData
820 *
821 * @param env A pointer to the Java environment
822 *
823 * @return The Java Method ID or nullptr if the class or method id could not
824 * be retieved
825 */
826 static jmethodID getLogDataMethodId(JNIEnv* env) {
827 jclass jclazz = getJClass(env);
828 if(jclazz == nullptr) {
829 // exception occurred accessing class
830 return nullptr;
831 }
832
833 static jmethodID mid = env->GetMethodID(jclazz, "logData", "([B)V");
834 assert(mid != nullptr);
835 return mid;
836 }
837
838 /**
839 * Get the Java Method: WriteBatch.Handler#shouldContinue
840 *
841 * @param env A pointer to the Java environment
842 *
843 * @return The Java Method ID or nullptr if the class or method id could not
844 * be retieved
845 */
846 static jmethodID getContinueMethodId(JNIEnv* env) {
847 jclass jclazz = getJClass(env);
848 if(jclazz == nullptr) {
849 // exception occurred accessing class
850 return nullptr;
851 }
852
853 static jmethodID mid = env->GetMethodID(jclazz, "shouldContinue", "()Z");
854 assert(mid != nullptr);
855 return mid;
856 }
857};
858
859// The portal class for org.rocksdb.WriteBatchWithIndex
860class WriteBatchWithIndexJni : public RocksDBNativeClass<
861 rocksdb::WriteBatchWithIndex*, WriteBatchWithIndexJni> {
862 public:
863 /**
864 * Get the Java Class org.rocksdb.WriteBatchWithIndex
865 *
866 * @param env A pointer to the Java environment
867 *
868 * @return The Java Class or nullptr if one of the
869 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
870 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
871 */
872 static jclass getJClass(JNIEnv* env) {
873 return RocksDBNativeClass::getJClass(env,
874 "org/rocksdb/WriteBatchWithIndex");
875 }
876};
877
878// The portal class for org.rocksdb.HistogramData
879class HistogramDataJni : public JavaClass {
880 public:
881 /**
882 * Get the Java Class org.rocksdb.HistogramData
883 *
884 * @param env A pointer to the Java environment
885 *
886 * @return The Java Class or nullptr if one of the
887 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
888 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
889 */
890 static jclass getJClass(JNIEnv* env) {
891 return JavaClass::getJClass(env, "org/rocksdb/HistogramData");
892 }
893
894 /**
895 * Get the Java Method: HistogramData constructor
896 *
897 * @param env A pointer to the Java environment
898 *
899 * @return The Java Method ID or nullptr if the class or method id could not
900 * be retieved
901 */
902 static jmethodID getConstructorMethodId(JNIEnv* env) {
903 jclass jclazz = getJClass(env);
904 if(jclazz == nullptr) {
905 // exception occurred accessing class
906 return nullptr;
907 }
908
909 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(DDDDD)V");
910 assert(mid != nullptr);
911 return mid;
912 }
913};
914
915// The portal class for org.rocksdb.BackupableDBOptions
916class BackupableDBOptionsJni : public RocksDBNativeClass<
917 rocksdb::BackupableDBOptions*, BackupableDBOptionsJni> {
918 public:
919 /**
920 * Get the Java Class org.rocksdb.BackupableDBOptions
921 *
922 * @param env A pointer to the Java environment
923 *
924 * @return The Java Class or nullptr if one of the
925 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
926 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
927 */
928 static jclass getJClass(JNIEnv* env) {
929 return RocksDBNativeClass::getJClass(env,
930 "org/rocksdb/BackupableDBOptions");
931 }
932};
933
934// The portal class for org.rocksdb.BackupEngine
935class BackupEngineJni : public RocksDBNativeClass<
936 rocksdb::BackupEngine*, BackupEngineJni> {
937 public:
938 /**
939 * Get the Java Class org.rocksdb.BackupableEngine
940 *
941 * @param env A pointer to the Java environment
942 *
943 * @return The Java Class or nullptr if one of the
944 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
945 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
946 */
947 static jclass getJClass(JNIEnv* env) {
948 return RocksDBNativeClass::getJClass(env, "org/rocksdb/BackupEngine");
949 }
950};
951
952// The portal class for org.rocksdb.RocksIterator
953class IteratorJni : public RocksDBNativeClass<
954 rocksdb::Iterator*, IteratorJni> {
955 public:
956 /**
957 * Get the Java Class org.rocksdb.RocksIterator
958 *
959 * @param env A pointer to the Java environment
960 *
961 * @return The Java Class or nullptr if one of the
962 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
963 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
964 */
965 static jclass getJClass(JNIEnv* env) {
966 return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksIterator");
967 }
968};
969
970// The portal class for org.rocksdb.Filter
971class FilterJni : public RocksDBNativeClass<
972 std::shared_ptr<rocksdb::FilterPolicy>*, FilterJni> {
973 public:
974 /**
975 * Get the Java Class org.rocksdb.Filter
976 *
977 * @param env A pointer to the Java environment
978 *
979 * @return The Java Class or nullptr if one of the
980 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
981 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
982 */
983 static jclass getJClass(JNIEnv* env) {
984 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Filter");
985 }
986};
987
988// The portal class for org.rocksdb.ColumnFamilyHandle
989class ColumnFamilyHandleJni : public RocksDBNativeClass<
990 rocksdb::ColumnFamilyHandle*, ColumnFamilyHandleJni> {
991 public:
992 /**
993 * Get the Java Class org.rocksdb.ColumnFamilyHandle
994 *
995 * @param env A pointer to the Java environment
996 *
997 * @return The Java Class or nullptr if one of the
998 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
999 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1000 */
1001 static jclass getJClass(JNIEnv* env) {
1002 return RocksDBNativeClass::getJClass(env,
1003 "org/rocksdb/ColumnFamilyHandle");
1004 }
1005};
1006
1007// The portal class for org.rocksdb.FlushOptions
1008class FlushOptionsJni : public RocksDBNativeClass<
1009 rocksdb::FlushOptions*, FlushOptionsJni> {
1010 public:
1011 /**
1012 * Get the Java Class org.rocksdb.FlushOptions
1013 *
1014 * @param env A pointer to the Java environment
1015 *
1016 * @return The Java Class or nullptr if one of the
1017 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1018 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1019 */
1020 static jclass getJClass(JNIEnv* env) {
1021 return RocksDBNativeClass::getJClass(env, "org/rocksdb/FlushOptions");
1022 }
1023};
1024
1025// The portal class for org.rocksdb.ComparatorOptions
1026class ComparatorOptionsJni : public RocksDBNativeClass<
1027 rocksdb::ComparatorJniCallbackOptions*, ComparatorOptionsJni> {
1028 public:
1029 /**
1030 * Get the Java Class org.rocksdb.ComparatorOptions
1031 *
1032 * @param env A pointer to the Java environment
1033 *
1034 * @return The Java Class or nullptr if one of the
1035 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1036 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1037 */
1038 static jclass getJClass(JNIEnv* env) {
1039 return RocksDBNativeClass::getJClass(env, "org/rocksdb/ComparatorOptions");
1040 }
1041};
1042
1043// The portal class for org.rocksdb.AbstractComparator
1044class AbstractComparatorJni : public RocksDBNativeClass<
1045 const rocksdb::BaseComparatorJniCallback*,
1046 AbstractComparatorJni> {
1047 public:
1048 /**
1049 * Get the Java Class org.rocksdb.AbstractComparator
1050 *
1051 * @param env A pointer to the Java environment
1052 *
1053 * @return The Java Class or nullptr if one of the
1054 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1055 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1056 */
1057 static jclass getJClass(JNIEnv* env) {
1058 return RocksDBNativeClass::getJClass(env,
1059 "org/rocksdb/AbstractComparator");
1060 }
1061
1062 /**
1063 * Get the Java Method: Comparator#name
1064 *
1065 * @param env A pointer to the Java environment
1066 *
1067 * @return The Java Method ID or nullptr if the class or method id could not
1068 * be retieved
1069 */
1070 static jmethodID getNameMethodId(JNIEnv* env) {
1071 jclass jclazz = getJClass(env);
1072 if(jclazz == nullptr) {
1073 // exception occurred accessing class
1074 return nullptr;
1075 }
1076
1077 static jmethodID mid =
1078 env->GetMethodID(jclazz, "name", "()Ljava/lang/String;");
1079 assert(mid != nullptr);
1080 return mid;
1081 }
1082
1083 /**
1084 * Get the Java Method: Comparator#compare
1085 *
1086 * @param env A pointer to the Java environment
1087 *
1088 * @return The Java Method ID or nullptr if the class or method id could not
1089 * be retieved
1090 */
1091 static jmethodID getCompareMethodId(JNIEnv* env) {
1092 jclass jclazz = getJClass(env);
1093 if(jclazz == nullptr) {
1094 // exception occurred accessing class
1095 return nullptr;
1096 }
1097
1098 static jmethodID mid =
1099 env->GetMethodID(jclazz, "compare",
1100 "(Lorg/rocksdb/AbstractSlice;Lorg/rocksdb/AbstractSlice;)I");
1101 assert(mid != nullptr);
1102 return mid;
1103 }
1104
1105 /**
1106 * Get the Java Method: Comparator#findShortestSeparator
1107 *
1108 * @param env A pointer to the Java environment
1109 *
1110 * @return The Java Method ID or nullptr if the class or method id could not
1111 * be retieved
1112 */
1113 static jmethodID getFindShortestSeparatorMethodId(JNIEnv* env) {
1114 jclass jclazz = getJClass(env);
1115 if(jclazz == nullptr) {
1116 // exception occurred accessing class
1117 return nullptr;
1118 }
1119
1120 static jmethodID mid =
1121 env->GetMethodID(jclazz, "findShortestSeparator",
1122 "(Ljava/lang/String;Lorg/rocksdb/AbstractSlice;)Ljava/lang/String;");
1123 assert(mid != nullptr);
1124 return mid;
1125 }
1126
1127 /**
1128 * Get the Java Method: Comparator#findShortSuccessor
1129 *
1130 * @param env A pointer to the Java environment
1131 *
1132 * @return The Java Method ID or nullptr if the class or method id could not
1133 * be retieved
1134 */
1135 static jmethodID getFindShortSuccessorMethodId(JNIEnv* env) {
1136 jclass jclazz = getJClass(env);
1137 if(jclazz == nullptr) {
1138 // exception occurred accessing class
1139 return nullptr;
1140 }
1141
1142 static jmethodID mid =
1143 env->GetMethodID(jclazz, "findShortSuccessor",
1144 "(Ljava/lang/String;)Ljava/lang/String;");
1145 assert(mid != nullptr);
1146 return mid;
1147 }
1148};
1149
1150// The portal class for org.rocksdb.AbstractSlice
1151class AbstractSliceJni : public NativeRocksMutableObject<
1152 const rocksdb::Slice*, AbstractSliceJni> {
1153 public:
1154 /**
1155 * Get the Java Class org.rocksdb.AbstractSlice
1156 *
1157 * @param env A pointer to the Java environment
1158 *
1159 * @return The Java Class or nullptr if one of the
1160 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1161 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1162 */
1163 static jclass getJClass(JNIEnv* env) {
1164 return RocksDBNativeClass::getJClass(env, "org/rocksdb/AbstractSlice");
1165 }
1166};
1167
1168// The portal class for org.rocksdb.Slice
1169class SliceJni : public NativeRocksMutableObject<
1170 const rocksdb::Slice*, AbstractSliceJni> {
1171 public:
1172 /**
1173 * Get the Java Class org.rocksdb.Slice
1174 *
1175 * @param env A pointer to the Java environment
1176 *
1177 * @return The Java Class or nullptr if one of the
1178 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1179 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1180 */
1181 static jclass getJClass(JNIEnv* env) {
1182 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Slice");
1183 }
1184
1185 /**
1186 * Constructs a Slice object
1187 *
1188 * @param env A pointer to the Java environment
1189 *
1190 * @return A reference to a Java Slice object, or a nullptr if an
1191 * exception occurs
1192 */
1193 static jobject construct0(JNIEnv* env) {
1194 jclass jclazz = getJClass(env);
1195 if(jclazz == nullptr) {
1196 // exception occurred accessing class
1197 return nullptr;
1198 }
1199
1200 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
1201 if(mid == nullptr) {
1202 // exception occurred accessing method
1203 return nullptr;
1204 }
1205
1206 jobject jslice = env->NewObject(jclazz, mid);
1207 if(env->ExceptionCheck()) {
1208 return nullptr;
1209 }
1210
1211 return jslice;
1212 }
1213};
1214
1215// The portal class for org.rocksdb.DirectSlice
1216class DirectSliceJni : public NativeRocksMutableObject<
1217 const rocksdb::Slice*, AbstractSliceJni> {
1218 public:
1219 /**
1220 * Get the Java Class org.rocksdb.DirectSlice
1221 *
1222 * @param env A pointer to the Java environment
1223 *
1224 * @return The Java Class or nullptr if one of the
1225 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1226 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1227 */
1228 static jclass getJClass(JNIEnv* env) {
1229 return RocksDBNativeClass::getJClass(env, "org/rocksdb/DirectSlice");
1230 }
1231
1232 /**
1233 * Constructs a DirectSlice object
1234 *
1235 * @param env A pointer to the Java environment
1236 *
1237 * @return A reference to a Java DirectSlice object, or a nullptr if an
1238 * exception occurs
1239 */
1240 static jobject construct0(JNIEnv* env) {
1241 jclass jclazz = getJClass(env);
1242 if(jclazz == nullptr) {
1243 // exception occurred accessing class
1244 return nullptr;
1245 }
1246
1247 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
1248 if(mid == nullptr) {
1249 // exception occurred accessing method
1250 return nullptr;
1251 }
1252
1253 jobject jdirect_slice = env->NewObject(jclazz, mid);
1254 if(env->ExceptionCheck()) {
1255 return nullptr;
1256 }
1257
1258 return jdirect_slice;
1259 }
1260};
1261
1262// The portal class for java.util.List
1263class ListJni : public JavaClass {
1264 public:
1265 /**
1266 * Get the Java Class java.util.List
1267 *
1268 * @param env A pointer to the Java environment
1269 *
1270 * @return The Java Class or nullptr if one of the
1271 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1272 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1273 */
1274 static jclass getListClass(JNIEnv* env) {
1275 return JavaClass::getJClass(env, "java/util/List");
1276 }
1277
1278 /**
1279 * Get the Java Class java.util.ArrayList
1280 *
1281 * @param env A pointer to the Java environment
1282 *
1283 * @return The Java Class or nullptr if one of the
1284 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1285 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1286 */
1287 static jclass getArrayListClass(JNIEnv* env) {
1288 return JavaClass::getJClass(env, "java/util/ArrayList");
1289 }
1290
1291 /**
1292 * Get the Java Class java.util.Iterator
1293 *
1294 * @param env A pointer to the Java environment
1295 *
1296 * @return The Java Class or nullptr if one of the
1297 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1298 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1299 */
1300 static jclass getIteratorClass(JNIEnv* env) {
1301 return JavaClass::getJClass(env, "java/util/Iterator");
1302 }
1303
1304 /**
1305 * Get the Java Method: List#iterator
1306 *
1307 * @param env A pointer to the Java environment
1308 *
1309 * @return The Java Method ID or nullptr if the class or method id could not
1310 * be retieved
1311 */
1312 static jmethodID getIteratorMethod(JNIEnv* env) {
1313 jclass jlist_clazz = getListClass(env);
1314 if(jlist_clazz == nullptr) {
1315 // exception occurred accessing class
1316 return nullptr;
1317 }
1318
1319 static jmethodID mid =
1320 env->GetMethodID(jlist_clazz, "iterator", "()Ljava/util/Iterator;");
1321 assert(mid != nullptr);
1322 return mid;
1323 }
1324
1325 /**
1326 * Get the Java Method: Iterator#hasNext
1327 *
1328 * @param env A pointer to the Java environment
1329 *
1330 * @return The Java Method ID or nullptr if the class or method id could not
1331 * be retieved
1332 */
1333 static jmethodID getHasNextMethod(JNIEnv* env) {
1334 jclass jiterator_clazz = getIteratorClass(env);
1335 if(jiterator_clazz == nullptr) {
1336 // exception occurred accessing class
1337 return nullptr;
1338 }
1339
1340 static jmethodID mid = env->GetMethodID(jiterator_clazz, "hasNext", "()Z");
1341 assert(mid != nullptr);
1342 return mid;
1343 }
1344
1345 /**
1346 * Get the Java Method: Iterator#next
1347 *
1348 * @param env A pointer to the Java environment
1349 *
1350 * @return The Java Method ID or nullptr if the class or method id could not
1351 * be retieved
1352 */
1353 static jmethodID getNextMethod(JNIEnv* env) {
1354 jclass jiterator_clazz = getIteratorClass(env);
1355 if(jiterator_clazz == nullptr) {
1356 // exception occurred accessing class
1357 return nullptr;
1358 }
1359
1360 static jmethodID mid =
1361 env->GetMethodID(jiterator_clazz, "next", "()Ljava/lang/Object;");
1362 assert(mid != nullptr);
1363 return mid;
1364 }
1365
1366 /**
1367 * Get the Java Method: ArrayList constructor
1368 *
1369 * @param env A pointer to the Java environment
1370 *
1371 * @return The Java Method ID or nullptr if the class or method id could not
1372 * be retieved
1373 */
1374 static jmethodID getArrayListConstructorMethodId(JNIEnv* env) {
1375 jclass jarray_list_clazz = getArrayListClass(env);
1376 if(jarray_list_clazz == nullptr) {
1377 // exception occurred accessing class
1378 return nullptr;
1379 }
1380 static jmethodID mid =
1381 env->GetMethodID(jarray_list_clazz, "<init>", "(I)V");
1382 assert(mid != nullptr);
1383 return mid;
1384 }
1385
1386 /**
1387 * Get the Java Method: List#add
1388 *
1389 * @param env A pointer to the Java environment
1390 *
1391 * @return The Java Method ID or nullptr if the class or method id could not
1392 * be retieved
1393 */
1394 static jmethodID getListAddMethodId(JNIEnv* env) {
1395 jclass jlist_clazz = getListClass(env);
1396 if(jlist_clazz == nullptr) {
1397 // exception occurred accessing class
1398 return nullptr;
1399 }
1400
1401 static jmethodID mid =
1402 env->GetMethodID(jlist_clazz, "add", "(Ljava/lang/Object;)Z");
1403 assert(mid != nullptr);
1404 return mid;
1405 }
1406};
1407
1408// The portal class for java.lang.Byte
1409class ByteJni : public JavaClass {
1410 public:
1411 /**
1412 * Get the Java Class java.lang.Byte
1413 *
1414 * @param env A pointer to the Java environment
1415 *
1416 * @return The Java Class or nullptr if one of the
1417 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1418 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1419 */
1420 static jclass getJClass(JNIEnv* env) {
1421 return JavaClass::getJClass(env, "java/lang/Byte");
1422 }
1423
1424 /**
1425 * Get the Java Class byte[]
1426 *
1427 * @param env A pointer to the Java environment
1428 *
1429 * @return The Java Class or nullptr if one of the
1430 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1431 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1432 */
1433 static jclass getArrayJClass(JNIEnv* env) {
1434 return JavaClass::getJClass(env, "[B");
1435 }
1436
1437 /**
1438 * Creates a new 2-dimensional Java Byte Array byte[][]
1439 *
1440 * @param env A pointer to the Java environment
1441 * @param len The size of the first dimension
1442 *
1443 * @return A reference to the Java byte[][] or nullptr if an exception occurs
1444 */
1445 static jobjectArray new2dByteArray(JNIEnv* env, const jsize len) {
1446 jclass clazz = getArrayJClass(env);
1447 if(clazz == nullptr) {
1448 // exception occurred accessing class
1449 return nullptr;
1450 }
1451
1452 return env->NewObjectArray(len, clazz, nullptr);
1453 }
1454
1455 /**
1456 * Get the Java Method: Byte#byteValue
1457 *
1458 * @param env A pointer to the Java environment
1459 *
1460 * @return The Java Method ID or nullptr if the class or method id could not
1461 * be retieved
1462 */
1463 static jmethodID getByteValueMethod(JNIEnv* env) {
1464 jclass clazz = getJClass(env);
1465 if(clazz == nullptr) {
1466 // exception occurred accessing class
1467 return nullptr;
1468 }
1469
1470 static jmethodID mid = env->GetMethodID(clazz, "byteValue", "()B");
1471 assert(mid != nullptr);
1472 return mid;
1473 }
1474};
1475
1476// The portal class for java.lang.StringBuilder
1477class StringBuilderJni : public JavaClass {
1478 public:
1479 /**
1480 * Get the Java Class java.lang.StringBuilder
1481 *
1482 * @param env A pointer to the Java environment
1483 *
1484 * @return The Java Class or nullptr if one of the
1485 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1486 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1487 */
1488 static jclass getJClass(JNIEnv* env) {
1489 return JavaClass::getJClass(env, "java/lang/StringBuilder");
1490 }
1491
1492 /**
1493 * Get the Java Method: StringBuilder#append
1494 *
1495 * @param env A pointer to the Java environment
1496 *
1497 * @return The Java Method ID or nullptr if the class or method id could not
1498 * be retieved
1499 */
1500 static jmethodID getListAddMethodId(JNIEnv* env) {
1501 jclass jclazz = getJClass(env);
1502 if(jclazz == nullptr) {
1503 // exception occurred accessing class
1504 return nullptr;
1505 }
1506
1507 static jmethodID mid =
1508 env->GetMethodID(jclazz, "append",
1509 "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1510 assert(mid != nullptr);
1511 return mid;
1512 }
1513
1514 /**
1515 * Appends a C-style string to a StringBuilder
1516 *
1517 * @param env A pointer to the Java environment
1518 * @param jstring_builder Reference to a java.lang.StringBuilder
1519 * @param c_str A C-style string to append to the StringBuilder
1520 *
1521 * @return A reference to the updated StringBuilder, or a nullptr if
1522 * an exception occurs
1523 */
1524 static jobject append(JNIEnv* env, jobject jstring_builder,
1525 const char* c_str) {
1526 jmethodID mid = getListAddMethodId(env);
1527 if(mid == nullptr) {
1528 // exception occurred accessing class or method
1529 return nullptr;
1530 }
1531
1532 jstring new_value_str = env->NewStringUTF(c_str);
1533 if(new_value_str == nullptr) {
1534 // exception thrown: OutOfMemoryError
1535 return nullptr;
1536 }
1537
1538 jobject jresult_string_builder =
1539 env->CallObjectMethod(jstring_builder, mid, new_value_str);
1540 if(env->ExceptionCheck()) {
1541 // exception occurred
1542 env->DeleteLocalRef(new_value_str);
1543 return nullptr;
1544 }
1545
1546 return jresult_string_builder;
1547 }
1548};
1549
1550// The portal class for org.rocksdb.BackupInfo
1551class BackupInfoJni : public JavaClass {
1552 public:
1553 /**
1554 * Get the Java Class org.rocksdb.BackupInfo
1555 *
1556 * @param env A pointer to the Java environment
1557 *
1558 * @return The Java Class or nullptr if one of the
1559 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1560 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1561 */
1562 static jclass getJClass(JNIEnv* env) {
1563 return JavaClass::getJClass(env, "org/rocksdb/BackupInfo");
1564 }
1565
1566 /**
1567 * Constructs a BackupInfo object
1568 *
1569 * @param env A pointer to the Java environment
1570 * @param backup_id id of the backup
1571 * @param timestamp timestamp of the backup
1572 * @param size size of the backup
1573 * @param number_files number of files related to the backup
1574 *
1575 * @return A reference to a Java BackupInfo object, or a nullptr if an
1576 * exception occurs
1577 */
1578 static jobject construct0(JNIEnv* env, uint32_t backup_id, int64_t timestamp,
1579 uint64_t size, uint32_t number_files) {
1580 jclass jclazz = getJClass(env);
1581 if(jclazz == nullptr) {
1582 // exception occurred accessing class
1583 return nullptr;
1584 }
1585
1586 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(IJJI)V");
1587 if(mid == nullptr) {
1588 // exception occurred accessing method
1589 return nullptr;
1590 }
1591
1592 jobject jbackup_info =
1593 env->NewObject(jclazz, mid, backup_id, timestamp, size, number_files);
1594 if(env->ExceptionCheck()) {
1595 return nullptr;
1596 }
1597
1598 return jbackup_info;
1599 }
1600};
1601
1602class BackupInfoListJni {
1603 public:
1604 /**
1605 * Converts a C++ std::vector<BackupInfo> object to
1606 * a Java ArrayList<org.rocksdb.BackupInfo> object
1607 *
1608 * @param env A pointer to the Java environment
1609 * @param backup_infos A vector of BackupInfo
1610 *
1611 * @return Either a reference to a Java ArrayList object, or a nullptr
1612 * if an exception occurs
1613 */
1614 static jobject getBackupInfo(JNIEnv* env,
1615 std::vector<BackupInfo> backup_infos) {
1616 jclass jarray_list_clazz = rocksdb::ListJni::getArrayListClass(env);
1617 if(jarray_list_clazz == nullptr) {
1618 // exception occurred accessing class
1619 return nullptr;
1620 }
1621
1622 jmethodID cstr_mid = rocksdb::ListJni::getArrayListConstructorMethodId(env);
1623 if(cstr_mid == nullptr) {
1624 // exception occurred accessing method
1625 return nullptr;
1626 }
1627
1628 jmethodID add_mid = rocksdb::ListJni::getListAddMethodId(env);
1629 if(add_mid == nullptr) {
1630 // exception occurred accessing method
1631 return nullptr;
1632 }
1633
1634 // create java list
1635 jobject jbackup_info_handle_list =
1636 env->NewObject(jarray_list_clazz, cstr_mid, backup_infos.size());
1637 if(env->ExceptionCheck()) {
1638 // exception occured constructing object
1639 return nullptr;
1640 }
1641
1642 // insert in java list
1643 auto end = backup_infos.end();
1644 for (auto it = backup_infos.begin(); it != end; ++it) {
1645 auto backup_info = *it;
1646
1647 jobject obj = rocksdb::BackupInfoJni::construct0(env,
1648 backup_info.backup_id,
1649 backup_info.timestamp,
1650 backup_info.size,
1651 backup_info.number_files);
1652 if(env->ExceptionCheck()) {
1653 // exception occured constructing object
1654 if(obj != nullptr) {
1655 env->DeleteLocalRef(obj);
1656 }
1657 if(jbackup_info_handle_list != nullptr) {
1658 env->DeleteLocalRef(jbackup_info_handle_list);
1659 }
1660 return nullptr;
1661 }
1662
1663 jboolean rs =
1664 env->CallBooleanMethod(jbackup_info_handle_list, add_mid, obj);
1665 if(env->ExceptionCheck() || rs == JNI_FALSE) {
1666 // exception occured calling method, or could not add
1667 if(obj != nullptr) {
1668 env->DeleteLocalRef(obj);
1669 }
1670 if(jbackup_info_handle_list != nullptr) {
1671 env->DeleteLocalRef(jbackup_info_handle_list);
1672 }
1673 return nullptr;
1674 }
1675 }
1676
1677 return jbackup_info_handle_list;
1678 }
1679};
1680
1681// The portal class for org.rocksdb.WBWIRocksIterator
1682class WBWIRocksIteratorJni : public JavaClass {
1683 public:
1684 /**
1685 * Get the Java Class org.rocksdb.WBWIRocksIterator
1686 *
1687 * @param env A pointer to the Java environment
1688 *
1689 * @return The Java Class or nullptr if one of the
1690 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1691 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1692 */
1693 static jclass getJClass(JNIEnv* env) {
1694 return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator");
1695 }
1696
1697 /**
1698 * Get the Java Field: WBWIRocksIterator#entry
1699 *
1700 * @param env A pointer to the Java environment
1701 *
1702 * @return The Java Field ID or nullptr if the class or field id could not
1703 * be retieved
1704 */
1705 static jfieldID getWriteEntryField(JNIEnv* env) {
1706 jclass jclazz = getJClass(env);
1707 if(jclazz == nullptr) {
1708 // exception occurred accessing class
1709 return nullptr;
1710 }
1711
1712 static jfieldID fid =
1713 env->GetFieldID(jclazz, "entry",
1714 "Lorg/rocksdb/WBWIRocksIterator$WriteEntry;");
1715 assert(fid != nullptr);
1716 return fid;
1717 }
1718
1719 /**
1720 * Gets the value of the WBWIRocksIterator#entry
1721 *
1722 * @param env A pointer to the Java environment
1723 * @param jwbwi_rocks_iterator A reference to a WBWIIterator
1724 *
1725 * @return A reference to a Java WBWIRocksIterator.WriteEntry object, or
1726 * a nullptr if an exception occurs
1727 */
1728 static jobject getWriteEntry(JNIEnv* env, jobject jwbwi_rocks_iterator) {
1729 assert(jwbwi_rocks_iterator != nullptr);
1730
1731 jfieldID jwrite_entry_field = getWriteEntryField(env);
1732 if(jwrite_entry_field == nullptr) {
1733 // exception occurred accessing the field
1734 return nullptr;
1735 }
1736
1737 jobject jwe = env->GetObjectField(jwbwi_rocks_iterator, jwrite_entry_field);
1738 assert(jwe != nullptr);
1739 return jwe;
1740 }
1741};
1742
1743// The portal class for org.rocksdb.WBWIRocksIterator.WriteType
1744class WriteTypeJni : public JavaClass {
1745 public:
1746 /**
1747 * Get the PUT enum field value of WBWIRocksIterator.WriteType
1748 *
1749 * @param env A pointer to the Java environment
1750 *
1751 * @return A reference to the enum field value or a nullptr if
1752 * the enum field value could not be retrieved
1753 */
1754 static jobject PUT(JNIEnv* env) {
1755 return getEnum(env, "PUT");
1756 }
1757
1758 /**
1759 * Get the MERGE enum field value of WBWIRocksIterator.WriteType
1760 *
1761 * @param env A pointer to the Java environment
1762 *
1763 * @return A reference to the enum field value or a nullptr if
1764 * the enum field value could not be retrieved
1765 */
1766 static jobject MERGE(JNIEnv* env) {
1767 return getEnum(env, "MERGE");
1768 }
1769
1770 /**
1771 * Get the DELETE enum field value of WBWIRocksIterator.WriteType
1772 *
1773 * @param env A pointer to the Java environment
1774 *
1775 * @return A reference to the enum field value or a nullptr if
1776 * the enum field value could not be retrieved
1777 */
1778 static jobject DELETE(JNIEnv* env) {
1779 return getEnum(env, "DELETE");
1780 }
1781
1782 /**
1783 * Get the LOG enum field value of WBWIRocksIterator.WriteType
1784 *
1785 * @param env A pointer to the Java environment
1786 *
1787 * @return A reference to the enum field value or a nullptr if
1788 * the enum field value could not be retrieved
1789 */
1790 static jobject LOG(JNIEnv* env) {
1791 return getEnum(env, "LOG");
1792 }
1793
1794 private:
1795 /**
1796 * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteType
1797 *
1798 * @param env A pointer to the Java environment
1799 *
1800 * @return The Java Class or nullptr if one of the
1801 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1802 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1803 */
1804 static jclass getJClass(JNIEnv* env) {
1805 return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteType");
1806 }
1807
1808 /**
1809 * Get an enum field of org.rocksdb.WBWIRocksIterator.WriteType
1810 *
1811 * @param env A pointer to the Java environment
1812 * @param name The name of the enum field
1813 *
1814 * @return A reference to the enum field value or a nullptr if
1815 * the enum field value could not be retrieved
1816 */
1817 static jobject getEnum(JNIEnv* env, const char name[]) {
1818 jclass jclazz = getJClass(env);
1819 if(jclazz == nullptr) {
1820 // exception occurred accessing class
1821 return nullptr;
1822 }
1823
1824 jfieldID jfid =
1825 env->GetStaticFieldID(jclazz, name,
1826 "Lorg/rocksdb/WBWIRocksIterator$WriteType;");
1827 if(env->ExceptionCheck()) {
1828 // exception occured while getting field
1829 return nullptr;
1830 } else if(jfid == nullptr) {
1831 return nullptr;
1832 }
1833
1834 jobject jwrite_type = env->GetStaticObjectField(jclazz, jfid);
1835 assert(jwrite_type != nullptr);
1836 return jwrite_type;
1837 }
1838};
1839
1840// The portal class for org.rocksdb.WBWIRocksIterator.WriteEntry
1841class WriteEntryJni : public JavaClass {
1842 public:
1843 /**
1844 * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteEntry
1845 *
1846 * @param env A pointer to the Java environment
1847 *
1848 * @return The Java Class or nullptr if one of the
1849 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1850 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1851 */
1852 static jclass getJClass(JNIEnv* env) {
1853 return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteEntry");
1854 }
1855};
1856
1857// The portal class for org.rocksdb.InfoLogLevel
1858class InfoLogLevelJni : public JavaClass {
1859 public:
1860 /**
1861 * Get the DEBUG_LEVEL enum field value of InfoLogLevel
1862 *
1863 * @param env A pointer to the Java environment
1864 *
1865 * @return A reference to the enum field value or a nullptr if
1866 * the enum field value could not be retrieved
1867 */
1868 static jobject DEBUG_LEVEL(JNIEnv* env) {
1869 return getEnum(env, "DEBUG_LEVEL");
1870 }
1871
1872 /**
1873 * Get the INFO_LEVEL enum field value of InfoLogLevel
1874 *
1875 * @param env A pointer to the Java environment
1876 *
1877 * @return A reference to the enum field value or a nullptr if
1878 * the enum field value could not be retrieved
1879 */
1880 static jobject INFO_LEVEL(JNIEnv* env) {
1881 return getEnum(env, "INFO_LEVEL");
1882 }
1883
1884 /**
1885 * Get the WARN_LEVEL enum field value of InfoLogLevel
1886 *
1887 * @param env A pointer to the Java environment
1888 *
1889 * @return A reference to the enum field value or a nullptr if
1890 * the enum field value could not be retrieved
1891 */
1892 static jobject WARN_LEVEL(JNIEnv* env) {
1893 return getEnum(env, "WARN_LEVEL");
1894 }
1895
1896 /**
1897 * Get the ERROR_LEVEL enum field value of InfoLogLevel
1898 *
1899 * @param env A pointer to the Java environment
1900 *
1901 * @return A reference to the enum field value or a nullptr if
1902 * the enum field value could not be retrieved
1903 */
1904 static jobject ERROR_LEVEL(JNIEnv* env) {
1905 return getEnum(env, "ERROR_LEVEL");
1906 }
1907
1908 /**
1909 * Get the FATAL_LEVEL enum field value of InfoLogLevel
1910 *
1911 * @param env A pointer to the Java environment
1912 *
1913 * @return A reference to the enum field value or a nullptr if
1914 * the enum field value could not be retrieved
1915 */
1916 static jobject FATAL_LEVEL(JNIEnv* env) {
1917 return getEnum(env, "FATAL_LEVEL");
1918 }
1919
1920 /**
1921 * Get the HEADER_LEVEL enum field value of InfoLogLevel
1922 *
1923 * @param env A pointer to the Java environment
1924 *
1925 * @return A reference to the enum field value or a nullptr if
1926 * the enum field value could not be retrieved
1927 */
1928 static jobject HEADER_LEVEL(JNIEnv* env) {
1929 return getEnum(env, "HEADER_LEVEL");
1930 }
1931
1932 private:
1933 /**
1934 * Get the Java Class org.rocksdb.InfoLogLevel
1935 *
1936 * @param env A pointer to the Java environment
1937 *
1938 * @return The Java Class or nullptr if one of the
1939 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1940 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1941 */
1942 static jclass getJClass(JNIEnv* env) {
1943 return JavaClass::getJClass(env, "org/rocksdb/InfoLogLevel");
1944 }
1945
1946 /**
1947 * Get an enum field of org.rocksdb.InfoLogLevel
1948 *
1949 * @param env A pointer to the Java environment
1950 * @param name The name of the enum field
1951 *
1952 * @return A reference to the enum field value or a nullptr if
1953 * the enum field value could not be retrieved
1954 */
1955 static jobject getEnum(JNIEnv* env, const char name[]) {
1956 jclass jclazz = getJClass(env);
1957 if(jclazz == nullptr) {
1958 // exception occurred accessing class
1959 return nullptr;
1960 }
1961
1962 jfieldID jfid =
1963 env->GetStaticFieldID(jclazz, name, "Lorg/rocksdb/InfoLogLevel;");
1964 if(env->ExceptionCheck()) {
1965 // exception occured while getting field
1966 return nullptr;
1967 } else if(jfid == nullptr) {
1968 return nullptr;
1969 }
1970
1971 jobject jinfo_log_level = env->GetStaticObjectField(jclazz, jfid);
1972 assert(jinfo_log_level != nullptr);
1973 return jinfo_log_level;
1974 }
1975};
1976
1977// The portal class for org.rocksdb.Logger
1978class LoggerJni : public RocksDBNativeClass<
1979 std::shared_ptr<rocksdb::LoggerJniCallback>*, LoggerJni> {
1980 public:
1981 /**
1982 * Get the Java Class org/rocksdb/Logger
1983 *
1984 * @param env A pointer to the Java environment
1985 *
1986 * @return The Java Class or nullptr if one of the
1987 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1988 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1989 */
1990 static jclass getJClass(JNIEnv* env) {
1991 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Logger");
1992 }
1993
1994 /**
1995 * Get the Java Method: Logger#log
1996 *
1997 * @param env A pointer to the Java environment
1998 *
1999 * @return The Java Method ID or nullptr if the class or method id could not
2000 * be retieved
2001 */
2002 static jmethodID getLogMethodId(JNIEnv* env) {
2003 jclass jclazz = getJClass(env);
2004 if(jclazz == nullptr) {
2005 // exception occurred accessing class
2006 return nullptr;
2007 }
2008
2009 static jmethodID mid =
2010 env->GetMethodID(jclazz, "log",
2011 "(Lorg/rocksdb/InfoLogLevel;Ljava/lang/String;)V");
2012 assert(mid != nullptr);
2013 return mid;
2014 }
2015};
2016
2017// The portal class for org.rocksdb.TransactionLogIterator.BatchResult
2018class BatchResultJni : public JavaClass {
2019 public:
2020 /**
2021 * Get the Java Class org.rocksdb.TransactionLogIterator.BatchResult
2022 *
2023 * @param env A pointer to the Java environment
2024 *
2025 * @return The Java Class or nullptr if one of the
2026 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2027 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2028 */
2029 static jclass getJClass(JNIEnv* env) {
2030 return JavaClass::getJClass(env,
2031 "org/rocksdb/TransactionLogIterator$BatchResult");
2032 }
2033
2034 /**
2035 * Create a new Java org.rocksdb.TransactionLogIterator.BatchResult object
2036 * with the same properties as the provided C++ rocksdb::BatchResult object
2037 *
2038 * @param env A pointer to the Java environment
2039 * @param batch_result The rocksdb::BatchResult object
2040 *
2041 * @return A reference to a Java
2042 * org.rocksdb.TransactionLogIterator.BatchResult object,
2043 * or nullptr if an an exception occurs
2044 */
2045 static jobject construct(JNIEnv* env,
2046 rocksdb::BatchResult& batch_result) {
2047 jclass jclazz = getJClass(env);
2048 if(jclazz == nullptr) {
2049 // exception occurred accessing class
2050 return nullptr;
2051 }
2052
2053 jmethodID mid = env->GetMethodID(
2054 jclazz, "<init>", "(JJ)V");
2055 if(mid == nullptr) {
2056 // exception thrown: NoSuchMethodException or OutOfMemoryError
2057 return nullptr;
2058 }
2059
2060 jobject jbatch_result = env->NewObject(jclazz, mid,
2061 batch_result.sequence, batch_result.writeBatchPtr.get());
2062 if(jbatch_result == nullptr) {
2063 // exception thrown: InstantiationException or OutOfMemoryError
2064 return nullptr;
2065 }
2066
2067 batch_result.writeBatchPtr.release();
2068 return jbatch_result;
2069 }
2070};
2071
2072// The portal class for org.rocksdb.CompactionStopStyle
2073class CompactionStopStyleJni {
2074 public:
2075 // Returns the equivalent org.rocksdb.CompactionStopStyle for the provided
2076 // C++ rocksdb::CompactionStopStyle enum
2077 static jbyte toJavaCompactionStopStyle(
2078 const rocksdb::CompactionStopStyle& compaction_stop_style) {
2079 switch(compaction_stop_style) {
2080 case rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize:
2081 return 0x0;
2082 case rocksdb::CompactionStopStyle::kCompactionStopStyleTotalSize:
2083 return 0x1;
2084 default:
2085 return 0x7F; // undefined
2086 }
2087 }
2088
2089 // Returns the equivalent C++ rocksdb::CompactionStopStyle enum for the
2090 // provided Java org.rocksdb.CompactionStopStyle
2091 static rocksdb::CompactionStopStyle toCppCompactionStopStyle(
2092 jbyte jcompaction_stop_style) {
2093 switch(jcompaction_stop_style) {
2094 case 0x0:
2095 return rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize;
2096 case 0x1:
2097 return rocksdb::CompactionStopStyle::kCompactionStopStyleTotalSize;
2098 default:
2099 // undefined/default
2100 return rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize;
2101 }
2102 }
2103};
2104
2105// The portal class for org.rocksdb.CompressionType
2106class CompressionTypeJni {
2107 public:
2108 // Returns the equivalent org.rocksdb.CompressionType for the provided
2109 // C++ rocksdb::CompressionType enum
2110 static jbyte toJavaCompressionType(
2111 const rocksdb::CompressionType& compression_type) {
2112 switch(compression_type) {
2113 case rocksdb::CompressionType::kNoCompression:
2114 return 0x0;
2115 case rocksdb::CompressionType::kSnappyCompression:
2116 return 0x1;
2117 case rocksdb::CompressionType::kZlibCompression:
2118 return 0x2;
2119 case rocksdb::CompressionType::kBZip2Compression:
2120 return 0x3;
2121 case rocksdb::CompressionType::kLZ4Compression:
2122 return 0x4;
2123 case rocksdb::CompressionType::kLZ4HCCompression:
2124 return 0x5;
2125 case rocksdb::CompressionType::kXpressCompression:
2126 return 0x6;
2127 case rocksdb::CompressionType::kZSTD:
2128 return 0x7;
2129 case rocksdb::CompressionType::kDisableCompressionOption:
2130 default:
2131 return 0x7F;
2132 }
2133 }
2134
2135 // Returns the equivalent C++ rocksdb::CompressionType enum for the
2136 // provided Java org.rocksdb.CompressionType
2137 static rocksdb::CompressionType toCppCompressionType(
2138 jbyte jcompression_type) {
2139 switch(jcompression_type) {
2140 case 0x0:
2141 return rocksdb::CompressionType::kNoCompression;
2142 case 0x1:
2143 return rocksdb::CompressionType::kSnappyCompression;
2144 case 0x2:
2145 return rocksdb::CompressionType::kZlibCompression;
2146 case 0x3:
2147 return rocksdb::CompressionType::kBZip2Compression;
2148 case 0x4:
2149 return rocksdb::CompressionType::kLZ4Compression;
2150 case 0x5:
2151 return rocksdb::CompressionType::kLZ4HCCompression;
2152 case 0x6:
2153 return rocksdb::CompressionType::kXpressCompression;
2154 case 0x7:
2155 return rocksdb::CompressionType::kZSTD;
2156 case 0x7F:
2157 default:
2158 return rocksdb::CompressionType::kDisableCompressionOption;
2159 }
2160 }
2161};
2162
2163// The portal class for org.rocksdb.CompactionPriority
2164class CompactionPriorityJni {
2165 public:
2166 // Returns the equivalent org.rocksdb.CompactionPriority for the provided
2167 // C++ rocksdb::CompactionPri enum
2168 static jbyte toJavaCompactionPriority(
2169 const rocksdb::CompactionPri& compaction_priority) {
2170 switch(compaction_priority) {
2171 case rocksdb::CompactionPri::kByCompensatedSize:
2172 return 0x0;
2173 case rocksdb::CompactionPri::kOldestLargestSeqFirst:
2174 return 0x1;
2175 case rocksdb::CompactionPri::kOldestSmallestSeqFirst:
2176 return 0x2;
2177 case rocksdb::CompactionPri::kMinOverlappingRatio:
2178 return 0x3;
2179 default:
2180 return 0x0; // undefined
2181 }
2182 }
2183
2184 // Returns the equivalent C++ rocksdb::CompactionPri enum for the
2185 // provided Java org.rocksdb.CompactionPriority
2186 static rocksdb::CompactionPri toCppCompactionPriority(
2187 jbyte jcompaction_priority) {
2188 switch(jcompaction_priority) {
2189 case 0x0:
2190 return rocksdb::CompactionPri::kByCompensatedSize;
2191 case 0x1:
2192 return rocksdb::CompactionPri::kOldestLargestSeqFirst;
2193 case 0x2:
2194 return rocksdb::CompactionPri::kOldestSmallestSeqFirst;
2195 case 0x3:
2196 return rocksdb::CompactionPri::kMinOverlappingRatio;
2197 default:
2198 // undefined/default
2199 return rocksdb::CompactionPri::kByCompensatedSize;
2200 }
2201 }
2202};
2203
2204// The portal class for org.rocksdb.AccessHint
2205class AccessHintJni {
2206 public:
2207 // Returns the equivalent org.rocksdb.AccessHint for the provided
2208 // C++ rocksdb::DBOptions::AccessHint enum
2209 static jbyte toJavaAccessHint(
2210 const rocksdb::DBOptions::AccessHint& access_hint) {
2211 switch(access_hint) {
2212 case rocksdb::DBOptions::AccessHint::NONE:
2213 return 0x0;
2214 case rocksdb::DBOptions::AccessHint::NORMAL:
2215 return 0x1;
2216 case rocksdb::DBOptions::AccessHint::SEQUENTIAL:
2217 return 0x2;
2218 case rocksdb::DBOptions::AccessHint::WILLNEED:
2219 return 0x3;
2220 default:
2221 // undefined/default
2222 return 0x1;
2223 }
2224 }
2225
2226 // Returns the equivalent C++ rocksdb::DBOptions::AccessHint enum for the
2227 // provided Java org.rocksdb.AccessHint
2228 static rocksdb::DBOptions::AccessHint toCppAccessHint(jbyte jaccess_hint) {
2229 switch(jaccess_hint) {
2230 case 0x0:
2231 return rocksdb::DBOptions::AccessHint::NONE;
2232 case 0x1:
2233 return rocksdb::DBOptions::AccessHint::NORMAL;
2234 case 0x2:
2235 return rocksdb::DBOptions::AccessHint::SEQUENTIAL;
2236 case 0x3:
2237 return rocksdb::DBOptions::AccessHint::WILLNEED;
2238 default:
2239 // undefined/default
2240 return rocksdb::DBOptions::AccessHint::NORMAL;
2241 }
2242 }
2243};
2244
2245// The portal class for org.rocksdb.WALRecoveryMode
2246class WALRecoveryModeJni {
2247 public:
2248 // Returns the equivalent org.rocksdb.WALRecoveryMode for the provided
2249 // C++ rocksdb::WALRecoveryMode enum
2250 static jbyte toJavaWALRecoveryMode(
2251 const rocksdb::WALRecoveryMode& wal_recovery_mode) {
2252 switch(wal_recovery_mode) {
2253 case rocksdb::WALRecoveryMode::kTolerateCorruptedTailRecords:
2254 return 0x0;
2255 case rocksdb::WALRecoveryMode::kAbsoluteConsistency:
2256 return 0x1;
2257 case rocksdb::WALRecoveryMode::kPointInTimeRecovery:
2258 return 0x2;
2259 case rocksdb::WALRecoveryMode::kSkipAnyCorruptedRecords:
2260 return 0x3;
2261 default:
2262 // undefined/default
2263 return 0x2;
2264 }
2265 }
2266
2267 // Returns the equivalent C++ rocksdb::WALRecoveryMode enum for the
2268 // provided Java org.rocksdb.WALRecoveryMode
2269 static rocksdb::WALRecoveryMode toCppWALRecoveryMode(jbyte jwal_recovery_mode) {
2270 switch(jwal_recovery_mode) {
2271 case 0x0:
2272 return rocksdb::WALRecoveryMode::kTolerateCorruptedTailRecords;
2273 case 0x1:
2274 return rocksdb::WALRecoveryMode::kAbsoluteConsistency;
2275 case 0x2:
2276 return rocksdb::WALRecoveryMode::kPointInTimeRecovery;
2277 case 0x3:
2278 return rocksdb::WALRecoveryMode::kSkipAnyCorruptedRecords;
2279 default:
2280 // undefined/default
2281 return rocksdb::WALRecoveryMode::kPointInTimeRecovery;
2282 }
2283 }
2284};
2285
2286// various utility functions for working with RocksDB and JNI
2287class JniUtil {
2288 public:
2289 /**
2290 * Obtains a reference to the JNIEnv from
2291 * the JVM
2292 *
2293 * If the current thread is not attached to the JavaVM
2294 * then it will be attached so as to retrieve the JNIEnv
2295 *
2296 * If a thread is attached, it must later be manually
2297 * released by calling JavaVM::DetachCurrentThread.
2298 * This can be handled by always matching calls to this
2299 * function with calls to {@link JniUtil::releaseJniEnv(JavaVM*, jboolean)}
2300 *
2301 * @param jvm (IN) A pointer to the JavaVM instance
2302 * @param attached (OUT) A pointer to a boolean which
2303 * will be set to JNI_TRUE if we had to attach the thread
2304 *
2305 * @return A pointer to the JNIEnv or nullptr if a fatal error
2306 * occurs and the JNIEnv cannot be retrieved
2307 */
2308 static JNIEnv* getJniEnv(JavaVM* jvm, jboolean* attached) {
2309 assert(jvm != nullptr);
2310
2311 JNIEnv *env;
2312 const jint env_rs = jvm->GetEnv(reinterpret_cast<void**>(&env),
2313 JNI_VERSION_1_2);
2314
2315 if(env_rs == JNI_OK) {
2316 // current thread is already attached, return the JNIEnv
2317 *attached = JNI_FALSE;
2318 return env;
2319 } else if(env_rs == JNI_EDETACHED) {
2320 // current thread is not attached, attempt to attach
2321 const jint rs_attach = jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);
2322 if(rs_attach == JNI_OK) {
2323 *attached = JNI_TRUE;
2324 return env;
2325 } else {
2326 // error, could not attach the thread
2327 std::cerr << "JniUtil::getJinEnv - Fatal: could not attach current thread to JVM!" << std::endl;
2328 return nullptr;
2329 }
2330 } else if(env_rs == JNI_EVERSION) {
2331 // error, JDK does not support JNI_VERSION_1_2+
2332 std::cerr << "JniUtil::getJinEnv - Fatal: JDK does not support JNI_VERSION_1_2" << std::endl;
2333 return nullptr;
2334 } else {
2335 std::cerr << "JniUtil::getJinEnv - Fatal: Unknown error: env_rs=" << env_rs << std::endl;
2336 return nullptr;
2337 }
2338 }
2339
2340 /**
2341 * Counterpart to {@link JniUtil::getJniEnv(JavaVM*, jboolean*)}
2342 *
2343 * Detachess the current thread from the JVM if it was previously
2344 * attached
2345 *
2346 * @param jvm (IN) A pointer to the JavaVM instance
2347 * @param attached (IN) JNI_TRUE if we previously had to attach the thread
2348 * to the JavaVM to get the JNIEnv
2349 */
2350 static void releaseJniEnv(JavaVM* jvm, jboolean& attached) {
2351 assert(jvm != nullptr);
2352 if(attached == JNI_TRUE) {
2353 const jint rs_detach = jvm->DetachCurrentThread();
2354 assert(rs_detach == JNI_OK);
2355 if(rs_detach != JNI_OK) {
2356 std::cerr << "JniUtil::getJinEnv - Warn: Unable to detach current thread from JVM!" << std::endl;
2357 }
2358 }
2359 }
2360
2361 /**
2362 * Copies a Java String[] to a C++ std::vector<std::string>
2363 *
2364 * @param env (IN) A pointer to the java environment
2365 * @param jss (IN) The Java String array to copy
2366 * @param has_exception (OUT) will be set to JNI_TRUE
2367 * if an OutOfMemoryError or ArrayIndexOutOfBoundsException
2368 * exception occurs
2369 *
2370 * @return A std::vector<std:string> containing copies of the Java strings
2371 */
2372 static std::vector<std::string> copyStrings(JNIEnv* env,
2373 jobjectArray jss, jboolean* has_exception) {
2374 return rocksdb::JniUtil::copyStrings(env, jss,
2375 env->GetArrayLength(jss), has_exception);
2376 }
2377
2378 /**
2379 * Copies a Java String[] to a C++ std::vector<std::string>
2380 *
2381 * @param env (IN) A pointer to the java environment
2382 * @param jss (IN) The Java String array to copy
2383 * @param jss_len (IN) The length of the Java String array to copy
2384 * @param has_exception (OUT) will be set to JNI_TRUE
2385 * if an OutOfMemoryError or ArrayIndexOutOfBoundsException
2386 * exception occurs
2387 *
2388 * @return A std::vector<std:string> containing copies of the Java strings
2389 */
2390 static std::vector<std::string> copyStrings(JNIEnv* env,
2391 jobjectArray jss, const jsize jss_len, jboolean* has_exception) {
2392 std::vector<std::string> strs;
2393 for (jsize i = 0; i < jss_len; i++) {
2394 jobject js = env->GetObjectArrayElement(jss, i);
2395 if(env->ExceptionCheck()) {
2396 // exception thrown: ArrayIndexOutOfBoundsException
2397 *has_exception = JNI_TRUE;
2398 return strs;
2399 }
2400
2401 jstring jstr = static_cast<jstring>(js);
2402 const char* str = env->GetStringUTFChars(jstr, nullptr);
2403 if(str == nullptr) {
2404 // exception thrown: OutOfMemoryError
2405 env->DeleteLocalRef(js);
2406 *has_exception = JNI_TRUE;
2407 return strs;
2408 }
2409
2410 strs.push_back(std::string(str));
2411
2412 env->ReleaseStringUTFChars(jstr, str);
2413 env->DeleteLocalRef(js);
2414 }
2415
2416 *has_exception = JNI_FALSE;
2417 return strs;
2418 }
2419
2420 /**
2421 * Copies a jstring to a std::string
2422 * and releases the original jstring
2423 *
2424 * If an exception occurs, then JNIEnv::ExceptionCheck()
2425 * will have been called
2426 *
2427 * @param env (IN) A pointer to the java environment
2428 * @param js (IN) The java string to copy
2429 * @param has_exception (OUT) will be set to JNI_TRUE
2430 * if an OutOfMemoryError exception occurs
2431 *
2432 * @return A std:string copy of the jstring, or an
2433 * empty std::string if has_exception == JNI_TRUE
2434 */
2435 static std::string copyString(JNIEnv* env, jstring js,
2436 jboolean* has_exception) {
2437 const char *utf = env->GetStringUTFChars(js, nullptr);
2438 if(utf == nullptr) {
2439 // exception thrown: OutOfMemoryError
2440 env->ExceptionCheck();
2441 *has_exception = JNI_TRUE;
2442 return std::string();
2443 } else if(env->ExceptionCheck()) {
2444 // exception thrown
2445 env->ReleaseStringUTFChars(js, utf);
2446 *has_exception = JNI_TRUE;
2447 return std::string();
2448 }
2449
2450 std::string name(utf);
2451 env->ReleaseStringUTFChars(js, utf);
2452 *has_exception = JNI_FALSE;
2453 return name;
2454 }
2455
2456 /**
2457 * Copies bytes from a std::string to a jByteArray
2458 *
2459 * @param env A pointer to the java environment
2460 * @param bytes The bytes to copy
2461 *
2462 * @return the Java byte[] or nullptr if an exception occurs
2463 */
2464 static jbyteArray copyBytes(JNIEnv* env, std::string bytes) {
2465 const jsize jlen = static_cast<jsize>(bytes.size());
2466
2467 jbyteArray jbytes = env->NewByteArray(jlen);
2468 if(jbytes == nullptr) {
2469 // exception thrown: OutOfMemoryError
2470 return nullptr;
2471 }
2472
2473 env->SetByteArrayRegion(jbytes, 0, jlen,
2474 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(bytes.c_str())));
2475 if(env->ExceptionCheck()) {
2476 // exception thrown: ArrayIndexOutOfBoundsException
2477 env->DeleteLocalRef(jbytes);
2478 return nullptr;
2479 }
2480
2481 return jbytes;
2482 }
2483
2484 /**
2485 * Given a Java byte[][] which is an array of java.lang.Strings
2486 * where each String is a byte[], the passed function `string_fn`
2487 * will be called on each String, the result is the collected by
2488 * calling the passed function `collector_fn`
2489 *
2490 * @param env (IN) A pointer to the java environment
2491 * @param jbyte_strings (IN) A Java array of Strings expressed as bytes
2492 * @param string_fn (IN) A transform function to call for each String
2493 * @param collector_fn (IN) A collector which is called for the result
2494 * of each `string_fn`
2495 * @param has_exception (OUT) will be set to JNI_TRUE
2496 * if an ArrayIndexOutOfBoundsException or OutOfMemoryError
2497 * exception occurs
2498 */
2499 template <typename T> static void byteStrings(JNIEnv* env,
2500 jobjectArray jbyte_strings,
2501 std::function<T(const char*, const size_t)> string_fn,
2502 std::function<void(size_t, T)> collector_fn,
2503 jboolean *has_exception) {
2504 const jsize jlen = env->GetArrayLength(jbyte_strings);
2505
2506 for(jsize i = 0; i < jlen; i++) {
2507 jobject jbyte_string_obj = env->GetObjectArrayElement(jbyte_strings, i);
2508 if(env->ExceptionCheck()) {
2509 // exception thrown: ArrayIndexOutOfBoundsException
2510 *has_exception = JNI_TRUE; // signal error
2511 return;
2512 }
2513
2514 jbyteArray jbyte_string_ary =
2515 reinterpret_cast<jbyteArray>(jbyte_string_obj);
2516 T result = byteString(env, jbyte_string_ary, string_fn, has_exception);
2517
2518 env->DeleteLocalRef(jbyte_string_obj);
2519
2520 if(*has_exception == JNI_TRUE) {
2521 // exception thrown: OutOfMemoryError
2522 return;
2523 }
2524
2525 collector_fn(i, result);
2526 }
2527
2528 *has_exception = JNI_FALSE;
2529 }
2530
2531 /**
2532 * Given a Java String which is expressed as a Java Byte Array byte[],
2533 * the passed function `string_fn` will be called on the String
2534 * and the result returned
2535 *
2536 * @param env (IN) A pointer to the java environment
2537 * @param jbyte_string_ary (IN) A Java String expressed in bytes
2538 * @param string_fn (IN) A transform function to call on the String
2539 * @param has_exception (OUT) will be set to JNI_TRUE
2540 * if an OutOfMemoryError exception occurs
2541 */
2542 template <typename T> static T byteString(JNIEnv* env,
2543 jbyteArray jbyte_string_ary,
2544 std::function<T(const char*, const size_t)> string_fn,
2545 jboolean* has_exception) {
2546 const jsize jbyte_string_len = env->GetArrayLength(jbyte_string_ary);
2547 jbyte* jbyte_string =
2548 env->GetByteArrayElements(jbyte_string_ary, nullptr);
2549 if(jbyte_string == nullptr) {
2550 // exception thrown: OutOfMemoryError
2551 *has_exception = JNI_TRUE;
2552 return nullptr; // signal error
2553 }
2554
2555 T result =
2556 string_fn(reinterpret_cast<char *>(jbyte_string), jbyte_string_len);
2557
2558 env->ReleaseByteArrayElements(jbyte_string_ary, jbyte_string, JNI_ABORT);
2559
2560 *has_exception = JNI_FALSE;
2561 return result;
2562 }
2563
2564 /**
2565 * Converts a std::vector<string> to a Java byte[][] where each Java String
2566 * is expressed as a Java Byte Array byte[].
2567 *
2568 * @param env A pointer to the java environment
2569 * @param strings A vector of Strings
2570 *
2571 * @return A Java array of Strings expressed as bytes
2572 */
2573 static jobjectArray stringsBytes(JNIEnv* env, std::vector<std::string> strings) {
2574 jclass jcls_ba = ByteJni::getArrayJClass(env);
2575 if(jcls_ba == nullptr) {
2576 // exception occurred
2577 return nullptr;
2578 }
2579
2580 const jsize len = static_cast<jsize>(strings.size());
2581
2582 jobjectArray jbyte_strings = env->NewObjectArray(len, jcls_ba, nullptr);
2583 if(jbyte_strings == nullptr) {
2584 // exception thrown: OutOfMemoryError
2585 return nullptr;
2586 }
2587
2588 for (jsize i = 0; i < len; i++) {
2589 std::string *str = &strings[i];
2590 const jsize str_len = static_cast<jsize>(str->size());
2591
2592 jbyteArray jbyte_string_ary = env->NewByteArray(str_len);
2593 if(jbyte_string_ary == nullptr) {
2594 // exception thrown: OutOfMemoryError
2595 env->DeleteLocalRef(jbyte_strings);
2596 return nullptr;
2597 }
2598
2599 env->SetByteArrayRegion(
2600 jbyte_string_ary, 0, str_len,
2601 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(str->c_str())));
2602 if(env->ExceptionCheck()) {
2603 // exception thrown: ArrayIndexOutOfBoundsException
2604 env->DeleteLocalRef(jbyte_string_ary);
2605 env->DeleteLocalRef(jbyte_strings);
2606 return nullptr;
2607 }
2608
2609 env->SetObjectArrayElement(jbyte_strings, i, jbyte_string_ary);
2610 if(env->ExceptionCheck()) {
2611 // exception thrown: ArrayIndexOutOfBoundsException
2612 // or ArrayStoreException
2613 env->DeleteLocalRef(jbyte_string_ary);
2614 env->DeleteLocalRef(jbyte_strings);
2615 return nullptr;
2616 }
2617
2618 env->DeleteLocalRef(jbyte_string_ary);
2619 }
2620
2621 return jbyte_strings;
2622 }
2623
2624 /*
2625 * Helper for operations on a key and value
2626 * for example WriteBatch->Put
2627 *
2628 * TODO(AR) could be extended to cover returning rocksdb::Status
2629 * from `op` and used for RocksDB->Put etc.
2630 */
2631 static void kv_op(
2632 std::function<void(rocksdb::Slice, rocksdb::Slice)> op,
2633 JNIEnv* env, jobject jobj,
2634 jbyteArray jkey, jint jkey_len,
2635 jbyteArray jentry_value, jint jentry_value_len) {
2636 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
2637 if(env->ExceptionCheck()) {
2638 // exception thrown: OutOfMemoryError
2639 return;
2640 }
2641
2642 jbyte* value = env->GetByteArrayElements(jentry_value, nullptr);
2643 if(env->ExceptionCheck()) {
2644 // exception thrown: OutOfMemoryError
2645 if(key != nullptr) {
2646 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2647 }
2648 return;
2649 }
2650
2651 rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
2652 rocksdb::Slice value_slice(reinterpret_cast<char*>(value),
2653 jentry_value_len);
2654
2655 op(key_slice, value_slice);
2656
2657 if(value != nullptr) {
2658 env->ReleaseByteArrayElements(jentry_value, value, JNI_ABORT);
2659 }
2660 if(key != nullptr) {
2661 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2662 }
2663 }
2664
2665 /*
2666 * Helper for operations on a key
2667 * for example WriteBatch->Delete
2668 *
2669 * TODO(AR) could be extended to cover returning rocksdb::Status
2670 * from `op` and used for RocksDB->Delete etc.
2671 */
2672 static void k_op(
2673 std::function<void(rocksdb::Slice)> op,
2674 JNIEnv* env, jobject jobj,
2675 jbyteArray jkey, jint jkey_len) {
2676 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
2677 if(env->ExceptionCheck()) {
2678 // exception thrown: OutOfMemoryError
2679 return;
2680 }
2681
2682 rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
2683
2684 op(key_slice);
2685
2686 if(key != nullptr) {
2687 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2688 }
2689 }
2690
2691 /*
2692 * Helper for operations on a value
2693 * for example WriteBatchWithIndex->GetFromBatch
2694 */
2695 static jbyteArray v_op(
2696 std::function<rocksdb::Status(rocksdb::Slice, std::string*)> op,
2697 JNIEnv* env, jbyteArray jkey, jint jkey_len) {
2698 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
2699 if(env->ExceptionCheck()) {
2700 // exception thrown: OutOfMemoryError
2701 return nullptr;
2702 }
2703
2704 rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
2705
2706 std::string value;
2707 rocksdb::Status s = op(key_slice, &value);
2708
2709 if(key != nullptr) {
2710 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2711 }
2712
2713 if (s.IsNotFound()) {
2714 return nullptr;
2715 }
2716
2717 if (s.ok()) {
2718 jbyteArray jret_value =
2719 env->NewByteArray(static_cast<jsize>(value.size()));
2720 if(jret_value == nullptr) {
2721 // exception thrown: OutOfMemoryError
2722 return nullptr;
2723 }
2724
2725 env->SetByteArrayRegion(jret_value, 0, static_cast<jsize>(value.size()),
2726 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.c_str())));
2727 if(env->ExceptionCheck()) {
2728 // exception thrown: ArrayIndexOutOfBoundsException
2729 if(jret_value != nullptr) {
2730 env->DeleteLocalRef(jret_value);
2731 }
2732 return nullptr;
2733 }
2734
2735 return jret_value;
2736 }
2737
2738 rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
2739 return nullptr;
2740 }
2741};
2742
2743} // namespace rocksdb
2744#endif // JAVA_ROCKSJNI_PORTAL_H_