]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/java/rocksjni/portal.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / rocksdb / java / rocksjni / portal.h
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
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
11fdf7f2 13#include <cstring>
7c673cae
FG
14#include <jni.h>
15#include <functional>
16#include <iostream>
11fdf7f2 17#include <iterator>
7c673cae 18#include <limits>
11fdf7f2 19#include <memory>
7c673cae 20#include <string>
11fdf7f2 21#include <type_traits>
7c673cae
FG
22#include <vector>
23
24#include "rocksdb/db.h"
25#include "rocksdb/filter_policy.h"
11fdf7f2 26#include "rocksdb/rate_limiter.h"
7c673cae
FG
27#include "rocksdb/status.h"
28#include "rocksdb/utilities/backupable_db.h"
11fdf7f2 29#include "rocksdb/utilities/transaction_db.h"
7c673cae 30#include "rocksdb/utilities/write_batch_with_index.h"
11fdf7f2 31#include "rocksjni/compaction_filter_factory_jnicallback.h"
7c673cae
FG
32#include "rocksjni/comparatorjnicallback.h"
33#include "rocksjni/loggerjnicallback.h"
11fdf7f2 34#include "rocksjni/transaction_notifier_jnicallback.h"
7c673cae
FG
35#include "rocksjni/writebatchhandlerjnicallback.h"
36
37// Remove macro on windows
38#ifdef DELETE
39#undef DELETE
40#endif
41
42namespace rocksdb {
43
44// Detect if jlong overflows size_t
45inline Status check_if_jlong_fits_size_t(const jlong& jvalue) {
46 Status s = Status::OK();
47 if (static_cast<uint64_t>(jvalue) > std::numeric_limits<size_t>::max()) {
48 s = Status::InvalidArgument(Slice("jlong overflows 32 bit value."));
49 }
50 return s;
51}
52
53class JavaClass {
54 public:
55 /**
56 * Gets and initializes a Java Class
57 *
58 * @param env A pointer to the Java environment
59 * @param jclazz_name The fully qualified JNI name of the Java Class
60 * e.g. "java/lang/String"
61 *
62 * @return The Java Class or nullptr if one of the
63 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
64 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
65 */
66 static jclass getJClass(JNIEnv* env, const char* jclazz_name) {
67 jclass jclazz = env->FindClass(jclazz_name);
68 assert(jclazz != nullptr);
69 return jclazz;
70 }
71};
72
73// Native class template
74template<class PTR, class DERIVED> class RocksDBNativeClass : public JavaClass {
75};
76
77// Native class template for sub-classes of RocksMutableObject
78template<class PTR, class DERIVED> class NativeRocksMutableObject
79 : public RocksDBNativeClass<PTR, DERIVED> {
80 public:
81
82 /**
83 * Gets the Java Method ID for the
84 * RocksMutableObject#setNativeHandle(long, boolean) method
85 *
86 * @param env A pointer to the Java environment
87 * @return The Java Method ID or nullptr the RocksMutableObject class cannot
88 * be accessed, or if one of the NoSuchMethodError,
89 * ExceptionInInitializerError or OutOfMemoryError exceptions is thrown
90 */
91 static jmethodID getSetNativeHandleMethod(JNIEnv* env) {
92 static jclass jclazz = DERIVED::getJClass(env);
93 if(jclazz == nullptr) {
94 return nullptr;
95 }
96
97 static jmethodID mid = env->GetMethodID(
98 jclazz, "setNativeHandle", "(JZ)V");
99 assert(mid != nullptr);
100 return mid;
101 }
102
103 /**
104 * Sets the C++ object pointer handle in the Java object
105 *
106 * @param env A pointer to the Java environment
107 * @param jobj The Java object on which to set the pointer handle
108 * @param ptr The C++ object pointer
109 * @param java_owns_handle JNI_TRUE if ownership of the C++ object is
110 * managed by the Java object
111 *
112 * @return true if a Java exception is pending, false otherwise
113 */
114 static bool setHandle(JNIEnv* env, jobject jobj, PTR ptr,
115 jboolean java_owns_handle) {
116 assert(jobj != nullptr);
117 static jmethodID mid = getSetNativeHandleMethod(env);
118 if(mid == nullptr) {
119 return true; // signal exception
120 }
121
122 env->CallVoidMethod(jobj, mid, reinterpret_cast<jlong>(ptr), java_owns_handle);
123 if(env->ExceptionCheck()) {
124 return true; // signal exception
125 }
126
127 return false;
128 }
129};
130
131// Java Exception template
132template<class DERIVED> class JavaException : public JavaClass {
133 public:
134 /**
135 * Create and throw a java exception with the provided message
136 *
137 * @param env A pointer to the Java environment
138 * @param msg The message for the exception
139 *
140 * @return true if an exception was thrown, false otherwise
141 */
142 static bool ThrowNew(JNIEnv* env, const std::string& msg) {
143 jclass jclazz = DERIVED::getJClass(env);
144 if(jclazz == nullptr) {
145 // exception occurred accessing class
146 std::cerr << "JavaException::ThrowNew - Error: unexpected exception!" << std::endl;
147 return env->ExceptionCheck();
148 }
149
150 const jint rs = env->ThrowNew(jclazz, msg.c_str());
151 if(rs != JNI_OK) {
152 // exception could not be thrown
153 std::cerr << "JavaException::ThrowNew - Fatal: could not throw exception!" << std::endl;
154 return env->ExceptionCheck();
155 }
156
157 return true;
158 }
159};
160
161// The portal class for org.rocksdb.RocksDB
162class RocksDBJni : public RocksDBNativeClass<rocksdb::DB*, RocksDBJni> {
163 public:
164 /**
165 * Get the Java Class org.rocksdb.RocksDB
166 *
167 * @param env A pointer to the Java environment
168 *
169 * @return The Java Class or nullptr if one of the
170 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
171 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
172 */
173 static jclass getJClass(JNIEnv* env) {
174 return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksDB");
175 }
176};
177
11fdf7f2
TL
178// The portal class for org.rocksdb.Status.Code
179class CodeJni : public JavaClass {
180 public:
181 /**
182 * Get the Java Class org.rocksdb.Status.Code
183 *
184 * @param env A pointer to the Java environment
185 *
186 * @return The Java Class or nullptr if one of the
187 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
188 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
189 */
190 static jclass getJClass(JNIEnv* env) {
191 return JavaClass::getJClass(env, "org/rocksdb/Status$Code");
192 }
193
194 /**
195 * Get the Java Method: Status.Code#getValue
196 *
197 * @param env A pointer to the Java environment
198 *
199 * @return The Java Method ID or nullptr if the class or method id could not
200 * be retieved
201 */
202 static jmethodID getValueMethod(JNIEnv* env) {
203 jclass jclazz = getJClass(env);
204 if(jclazz == nullptr) {
205 // exception occurred accessing class
206 return nullptr;
207 }
208
209 static jmethodID mid =
210 env->GetMethodID(jclazz, "getValue", "()b");
211 assert(mid != nullptr);
212 return mid;
213 }
214};
215
216// The portal class for org.rocksdb.Status.SubCode
217class SubCodeJni : public JavaClass {
218 public:
219 /**
220 * Get the Java Class org.rocksdb.Status.SubCode
221 *
222 * @param env A pointer to the Java environment
223 *
224 * @return The Java Class or nullptr if one of the
225 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
226 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
227 */
228 static jclass getJClass(JNIEnv* env) {
229 return JavaClass::getJClass(env, "org/rocksdb/Status$SubCode");
230 }
231
232 /**
233 * Get the Java Method: Status.SubCode#getValue
234 *
235 * @param env A pointer to the Java environment
236 *
237 * @return The Java Method ID or nullptr if the class or method id could not
238 * be retieved
239 */
240 static jmethodID getValueMethod(JNIEnv* env) {
241 jclass jclazz = getJClass(env);
242 if(jclazz == nullptr) {
243 // exception occurred accessing class
244 return nullptr;
245 }
246
247 static jmethodID mid =
248 env->GetMethodID(jclazz, "getValue", "()b");
249 assert(mid != nullptr);
250 return mid;
251 }
252
253 static rocksdb::Status::SubCode toCppSubCode(const jbyte jsub_code) {
254 switch (jsub_code) {
255 case 0x0:
256 return rocksdb::Status::SubCode::kNone;
257 case 0x1:
258 return rocksdb::Status::SubCode::kMutexTimeout;
259 case 0x2:
260 return rocksdb::Status::SubCode::kLockTimeout;
261 case 0x3:
262 return rocksdb::Status::SubCode::kLockLimit;
263 case 0x4:
264 return rocksdb::Status::SubCode::kNoSpace;
265 case 0x5:
266 return rocksdb::Status::SubCode::kDeadlock;
267 case 0x6:
268 return rocksdb::Status::SubCode::kStaleFile;
269 case 0x7:
270 return rocksdb::Status::SubCode::kMemoryLimit;
271
272 case 0x7F:
273 default:
274 return rocksdb::Status::SubCode::kNone;
275 }
276 }
277};
278
7c673cae
FG
279// The portal class for org.rocksdb.Status
280class StatusJni : public RocksDBNativeClass<rocksdb::Status*, StatusJni> {
281 public:
282 /**
283 * Get the Java Class org.rocksdb.Status
284 *
285 * @param env A pointer to the Java environment
286 *
287 * @return The Java Class or nullptr if one of the
288 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
289 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
290 */
291 static jclass getJClass(JNIEnv* env) {
292 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Status");
293 }
294
11fdf7f2
TL
295 /**
296 * Get the Java Method: Status#getCode
297 *
298 * @param env A pointer to the Java environment
299 *
300 * @return The Java Method ID or nullptr if the class or method id could not
301 * be retieved
302 */
303 static jmethodID getCodeMethod(JNIEnv* env) {
304 jclass jclazz = getJClass(env);
305 if(jclazz == nullptr) {
306 // exception occurred accessing class
307 return nullptr;
308 }
309
310 static jmethodID mid =
311 env->GetMethodID(jclazz, "getCode", "()Lorg/rocksdb/Status$Code;");
312 assert(mid != nullptr);
313 return mid;
314 }
315
316 /**
317 * Get the Java Method: Status#getSubCode
318 *
319 * @param env A pointer to the Java environment
320 *
321 * @return The Java Method ID or nullptr if the class or method id could not
322 * be retieved
323 */
324 static jmethodID getSubCodeMethod(JNIEnv* env) {
325 jclass jclazz = getJClass(env);
326 if(jclazz == nullptr) {
327 // exception occurred accessing class
328 return nullptr;
329 }
330
331 static jmethodID mid =
332 env->GetMethodID(jclazz, "getSubCode", "()Lorg/rocksdb/Status$SubCode;");
333 assert(mid != nullptr);
334 return mid;
335 }
336
337 /**
338 * Get the Java Method: Status#getState
339 *
340 * @param env A pointer to the Java environment
341 *
342 * @return The Java Method ID or nullptr if the class or method id could not
343 * be retieved
344 */
345 static jmethodID getStateMethod(JNIEnv* env) {
346 jclass jclazz = getJClass(env);
347 if(jclazz == nullptr) {
348 // exception occurred accessing class
349 return nullptr;
350 }
351
352 static jmethodID mid =
353 env->GetMethodID(jclazz, "getState", "()Ljava/lang/String;");
354 assert(mid != nullptr);
355 return mid;
356 }
357
7c673cae
FG
358 /**
359 * Create a new Java org.rocksdb.Status object with the same properties as
360 * the provided C++ rocksdb::Status object
361 *
362 * @param env A pointer to the Java environment
363 * @param status The rocksdb::Status object
364 *
365 * @return A reference to a Java org.rocksdb.Status object, or nullptr
366 * if an an exception occurs
367 */
368 static jobject construct(JNIEnv* env, const Status& status) {
369 jclass jclazz = getJClass(env);
370 if(jclazz == nullptr) {
371 // exception occurred accessing class
372 return nullptr;
373 }
374
375 jmethodID mid =
376 env->GetMethodID(jclazz, "<init>", "(BBLjava/lang/String;)V");
377 if(mid == nullptr) {
378 // exception thrown: NoSuchMethodException or OutOfMemoryError
379 return nullptr;
380 }
381
382 // convert the Status state for Java
383 jstring jstate = nullptr;
384 if (status.getState() != nullptr) {
385 const char* const state = status.getState();
386 jstate = env->NewStringUTF(state);
387 if(env->ExceptionCheck()) {
388 if(jstate != nullptr) {
389 env->DeleteLocalRef(jstate);
390 }
391 return nullptr;
392 }
393 }
394
395 jobject jstatus =
396 env->NewObject(jclazz, mid, toJavaStatusCode(status.code()),
397 toJavaStatusSubCode(status.subcode()), jstate);
398 if(env->ExceptionCheck()) {
399 // exception occurred
400 if(jstate != nullptr) {
401 env->DeleteLocalRef(jstate);
402 }
403 return nullptr;
404 }
405
406 if(jstate != nullptr) {
407 env->DeleteLocalRef(jstate);
408 }
409
410 return jstatus;
411 }
412
413 // Returns the equivalent org.rocksdb.Status.Code for the provided
414 // C++ rocksdb::Status::Code enum
415 static jbyte toJavaStatusCode(const rocksdb::Status::Code& code) {
416 switch (code) {
417 case rocksdb::Status::Code::kOk:
418 return 0x0;
419 case rocksdb::Status::Code::kNotFound:
420 return 0x1;
421 case rocksdb::Status::Code::kCorruption:
422 return 0x2;
423 case rocksdb::Status::Code::kNotSupported:
424 return 0x3;
425 case rocksdb::Status::Code::kInvalidArgument:
426 return 0x4;
427 case rocksdb::Status::Code::kIOError:
428 return 0x5;
429 case rocksdb::Status::Code::kMergeInProgress:
430 return 0x6;
431 case rocksdb::Status::Code::kIncomplete:
432 return 0x7;
433 case rocksdb::Status::Code::kShutdownInProgress:
434 return 0x8;
435 case rocksdb::Status::Code::kTimedOut:
436 return 0x9;
437 case rocksdb::Status::Code::kAborted:
438 return 0xA;
439 case rocksdb::Status::Code::kBusy:
440 return 0xB;
441 case rocksdb::Status::Code::kExpired:
442 return 0xC;
443 case rocksdb::Status::Code::kTryAgain:
444 return 0xD;
445 default:
446 return 0x7F; // undefined
447 }
448 }
449
450 // Returns the equivalent org.rocksdb.Status.SubCode for the provided
451 // C++ rocksdb::Status::SubCode enum
452 static jbyte toJavaStatusSubCode(const rocksdb::Status::SubCode& subCode) {
453 switch (subCode) {
454 case rocksdb::Status::SubCode::kNone:
455 return 0x0;
456 case rocksdb::Status::SubCode::kMutexTimeout:
457 return 0x1;
458 case rocksdb::Status::SubCode::kLockTimeout:
459 return 0x2;
460 case rocksdb::Status::SubCode::kLockLimit:
461 return 0x3;
11fdf7f2
TL
462 case rocksdb::Status::SubCode::kNoSpace:
463 return 0x4;
464 case rocksdb::Status::SubCode::kDeadlock:
465 return 0x5;
466 case rocksdb::Status::SubCode::kStaleFile:
467 return 0x6;
468 case rocksdb::Status::SubCode::kMemoryLimit:
469 return 0x7;
7c673cae
FG
470 default:
471 return 0x7F; // undefined
472 }
473 }
11fdf7f2
TL
474
475 // Returns the equivalent rocksdb::Status for the Java org.rocksdb.Status
476 static std::unique_ptr<rocksdb::Status> toCppStatus(JNIEnv* env, const jobject jstatus) {
477 jmethodID mid_code = getCodeMethod(env);
478 if (mid_code == nullptr) {
479 // exception occurred
480 return nullptr;
481 }
482 jobject jcode = env->CallObjectMethod(jstatus, mid_code);
483 if (env->ExceptionCheck()) {
484 // exception occurred
485 return nullptr;
486 }
487
488 jmethodID mid_code_value = rocksdb::CodeJni::getValueMethod(env);
489 if (mid_code_value == nullptr) {
490 // exception occurred
491 return nullptr;
492 }
493 jbyte jcode_value = env->CallByteMethod(jcode, mid_code_value);
494 if (env->ExceptionCheck()) {
495 // exception occurred
496 if (jcode != nullptr) {
497 env->DeleteLocalRef(jcode);
498 }
499 return nullptr;
500 }
501
502 jmethodID mid_subCode = getSubCodeMethod(env);
503 if (mid_subCode == nullptr) {
504 // exception occurred
505 return nullptr;
506 }
507 jobject jsubCode = env->CallObjectMethod(jstatus, mid_subCode);
508 if (env->ExceptionCheck()) {
509 // exception occurred
510 if (jcode != nullptr) {
511 env->DeleteLocalRef(jcode);
512 }
513 return nullptr;
514 }
515
516 jbyte jsubCode_value = 0x0; // None
517 if (jsubCode != nullptr) {
518 jmethodID mid_subCode_value = rocksdb::SubCodeJni::getValueMethod(env);
519 if (mid_subCode_value == nullptr) {
520 // exception occurred
521 return nullptr;
522 }
523 jsubCode_value =env->CallByteMethod(jsubCode, mid_subCode_value);
524 if (env->ExceptionCheck()) {
525 // exception occurred
526 if (jcode != nullptr) {
527 env->DeleteLocalRef(jcode);
528 }
529 return nullptr;
530 }
531 }
532
533 jmethodID mid_state = getStateMethod(env);
534 if (mid_state == nullptr) {
535 // exception occurred
536 return nullptr;
537 }
538 jobject jstate = env->CallObjectMethod(jstatus, mid_state);
539 if (env->ExceptionCheck()) {
540 // exception occurred
541 if (jsubCode != nullptr) {
542 env->DeleteLocalRef(jsubCode);
543 }
544 if (jcode != nullptr) {
545 env->DeleteLocalRef(jcode);
546 }
547 return nullptr;
548 }
549
550 std::unique_ptr<rocksdb::Status> status;
551 switch (jcode_value) {
552 case 0x0:
553 //Ok
554 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::OK()));
555 break;
556 case 0x1:
557 //NotFound
558 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::NotFound(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
559 break;
560 case 0x2:
561 //Corruption
562 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::Corruption(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
563 break;
564 case 0x3:
565 //NotSupported
566 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::NotSupported(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
567 break;
568 case 0x4:
569 //InvalidArgument
570 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::InvalidArgument(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
571 break;
572 case 0x5:
573 //IOError
574 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::IOError(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
575 break;
576 case 0x6:
577 //MergeInProgress
578 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::MergeInProgress(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
579 break;
580 case 0x7:
581 //Incomplete
582 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::Incomplete(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
583 break;
584 case 0x8:
585 //ShutdownInProgress
586 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::ShutdownInProgress(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
587 break;
588 case 0x9:
589 //TimedOut
590 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::TimedOut(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
591 break;
592 case 0xA:
593 //Aborted
594 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::Aborted(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
595 break;
596 case 0xB:
597 //Busy
598 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::Busy(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
599 break;
600 case 0xC:
601 //Expired
602 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::Expired(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
603 break;
604 case 0xD:
605 //TryAgain
606 status = std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::TryAgain(rocksdb::SubCodeJni::toCppSubCode(jsubCode_value))));
607 break;
608 case 0x7F:
609 default:
610 return nullptr;
611 }
612
613 // delete all local refs
614 if (jstate != nullptr) {
615 env->DeleteLocalRef(jstate);
616 }
617 if (jsubCode != nullptr) {
618 env->DeleteLocalRef(jsubCode);
619 }
620 if (jcode != nullptr) {
621 env->DeleteLocalRef(jcode);
622 }
623
624 return status;
625 }
7c673cae
FG
626};
627
628// The portal class for org.rocksdb.RocksDBException
629class RocksDBExceptionJni :
630 public JavaException<RocksDBExceptionJni> {
631 public:
632 /**
633 * Get the Java Class org.rocksdb.RocksDBException
634 *
635 * @param env A pointer to the Java environment
636 *
637 * @return The Java Class or nullptr if one of the
638 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
639 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
640 */
641 static jclass getJClass(JNIEnv* env) {
642 return JavaException::getJClass(env, "org/rocksdb/RocksDBException");
643 }
644
645 /**
646 * Create and throw a Java RocksDBException with the provided message
647 *
648 * @param env A pointer to the Java environment
649 * @param msg The message for the exception
650 *
651 * @return true if an exception was thrown, false otherwise
652 */
653 static bool ThrowNew(JNIEnv* env, const std::string& msg) {
654 return JavaException::ThrowNew(env, msg);
655 }
656
11fdf7f2
TL
657 /**
658 * Create and throw a Java RocksDBException with the provided status
659 *
660 * If s->ok() == true, then this function will not throw any exception.
661 *
662 * @param env A pointer to the Java environment
663 * @param s The status for the exception
664 *
665 * @return true if an exception was thrown, false otherwise
666 */
667 static bool ThrowNew(JNIEnv* env, std::unique_ptr<Status>& s) {
668 return rocksdb::RocksDBExceptionJni::ThrowNew(env, *(s.get()));
669 }
670
7c673cae
FG
671 /**
672 * Create and throw a Java RocksDBException with the provided status
673 *
674 * If s.ok() == true, then this function will not throw any exception.
675 *
676 * @param env A pointer to the Java environment
677 * @param s The status for the exception
678 *
679 * @return true if an exception was thrown, false otherwise
680 */
681 static bool ThrowNew(JNIEnv* env, const Status& s) {
682 assert(!s.ok());
683 if (s.ok()) {
684 return false;
685 }
686
687 // get the RocksDBException class
688 jclass jclazz = getJClass(env);
689 if(jclazz == nullptr) {
690 // exception occurred accessing class
691 std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
692 return env->ExceptionCheck();
693 }
694
695 // get the constructor of org.rocksdb.RocksDBException
696 jmethodID mid =
697 env->GetMethodID(jclazz, "<init>", "(Lorg/rocksdb/Status;)V");
698 if(mid == nullptr) {
699 // exception thrown: NoSuchMethodException or OutOfMemoryError
700 std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
701 return env->ExceptionCheck();
702 }
703
704 // get the Java status object
705 jobject jstatus = StatusJni::construct(env, s);
706 if(jstatus == nullptr) {
707 // exception occcurred
708 std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
709 return env->ExceptionCheck();
710 }
711
712 // construct the RocksDBException
713 jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jstatus));
714 if(env->ExceptionCheck()) {
715 if(jstatus != nullptr) {
716 env->DeleteLocalRef(jstatus);
717 }
718 if(rocksdb_exception != nullptr) {
719 env->DeleteLocalRef(rocksdb_exception);
720 }
721 std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
722 return true;
723 }
724
725 // throw the RocksDBException
726 const jint rs = env->Throw(rocksdb_exception);
727 if(rs != JNI_OK) {
728 // exception could not be thrown
729 std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
730 if(jstatus != nullptr) {
731 env->DeleteLocalRef(jstatus);
732 }
733 if(rocksdb_exception != nullptr) {
734 env->DeleteLocalRef(rocksdb_exception);
735 }
736 return env->ExceptionCheck();
737 }
738
739 if(jstatus != nullptr) {
740 env->DeleteLocalRef(jstatus);
741 }
742 if(rocksdb_exception != nullptr) {
743 env->DeleteLocalRef(rocksdb_exception);
744 }
745
746 return true;
747 }
748
749 /**
750 * Create and throw a Java RocksDBException with the provided message
751 * and status
752 *
753 * If s.ok() == true, then this function will not throw any exception.
754 *
755 * @param env A pointer to the Java environment
756 * @param msg The message for the exception
757 * @param s The status for the exception
758 *
759 * @return true if an exception was thrown, false otherwise
760 */
761 static bool ThrowNew(JNIEnv* env, const std::string& msg, const Status& s) {
762 assert(!s.ok());
763 if (s.ok()) {
764 return false;
765 }
766
767 // get the RocksDBException class
768 jclass jclazz = getJClass(env);
769 if(jclazz == nullptr) {
770 // exception occurred accessing class
771 std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
772 return env->ExceptionCheck();
773 }
774
775 // get the constructor of org.rocksdb.RocksDBException
776 jmethodID mid =
777 env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;Lorg/rocksdb/Status;)V");
778 if(mid == nullptr) {
779 // exception thrown: NoSuchMethodException or OutOfMemoryError
780 std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
781 return env->ExceptionCheck();
782 }
783
784 jstring jmsg = env->NewStringUTF(msg.c_str());
785 if(jmsg == nullptr) {
786 // exception thrown: OutOfMemoryError
787 std::cerr << "RocksDBExceptionJni::ThrowNew/msg - Error: unexpected exception!" << std::endl;
788 return env->ExceptionCheck();
789 }
790
791 // get the Java status object
792 jobject jstatus = StatusJni::construct(env, s);
793 if(jstatus == nullptr) {
794 // exception occcurred
795 std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
796 if(jmsg != nullptr) {
797 env->DeleteLocalRef(jmsg);
798 }
799 return env->ExceptionCheck();
800 }
801
802 // construct the RocksDBException
803 jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jmsg, jstatus));
804 if(env->ExceptionCheck()) {
805 if(jstatus != nullptr) {
806 env->DeleteLocalRef(jstatus);
807 }
808 if(jmsg != nullptr) {
809 env->DeleteLocalRef(jmsg);
810 }
811 if(rocksdb_exception != nullptr) {
812 env->DeleteLocalRef(rocksdb_exception);
813 }
814 std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
815 return true;
816 }
817
818 // throw the RocksDBException
819 const jint rs = env->Throw(rocksdb_exception);
820 if(rs != JNI_OK) {
821 // exception could not be thrown
822 std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
823 if(jstatus != nullptr) {
824 env->DeleteLocalRef(jstatus);
825 }
826 if(jmsg != nullptr) {
827 env->DeleteLocalRef(jmsg);
828 }
829 if(rocksdb_exception != nullptr) {
830 env->DeleteLocalRef(rocksdb_exception);
831 }
832 return env->ExceptionCheck();
833 }
834
835 if(jstatus != nullptr) {
836 env->DeleteLocalRef(jstatus);
837 }
838 if(jmsg != nullptr) {
839 env->DeleteLocalRef(jmsg);
840 }
841 if(rocksdb_exception != nullptr) {
842 env->DeleteLocalRef(rocksdb_exception);
843 }
844
845 return true;
846 }
11fdf7f2
TL
847
848 /**
849 * Get the Java Method: RocksDBException#getStatus
850 *
851 * @param env A pointer to the Java environment
852 *
853 * @return The Java Method ID or nullptr if the class or method id could not
854 * be retieved
855 */
856 static jmethodID getStatusMethod(JNIEnv* env) {
857 jclass jclazz = getJClass(env);
858 if(jclazz == nullptr) {
859 // exception occurred accessing class
860 return nullptr;
861 }
862
863 static jmethodID mid =
864 env->GetMethodID(jclazz, "getStatus", "()Lorg/rocksdb/Status;");
865 assert(mid != nullptr);
866 return mid;
867 }
868
869 static std::unique_ptr<rocksdb::Status> toCppStatus(
870 JNIEnv* env, jthrowable jrocksdb_exception) {
871 if(!env->IsInstanceOf(jrocksdb_exception, getJClass(env))) {
872 // not an instance of RocksDBException
873 return nullptr;
874 }
875
876 // get the java status object
877 jmethodID mid = getStatusMethod(env);
878 if(mid == nullptr) {
879 // exception occurred accessing class or method
880 return nullptr;
881 }
882
883 jobject jstatus = env->CallObjectMethod(jrocksdb_exception, mid);
884 if(env->ExceptionCheck()) {
885 // exception occurred
886 return nullptr;
887 }
888
889 if(jstatus == nullptr) {
890 return nullptr; // no status available
891 }
892
893 return rocksdb::StatusJni::toCppStatus(env, jstatus);
894 }
7c673cae
FG
895};
896
897// The portal class for java.lang.IllegalArgumentException
898class IllegalArgumentExceptionJni :
899 public JavaException<IllegalArgumentExceptionJni> {
900 public:
901 /**
902 * Get the Java Class java.lang.IllegalArgumentException
903 *
904 * @param env A pointer to the Java environment
905 *
906 * @return The Java Class or nullptr if one of the
907 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
908 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
909 */
910 static jclass getJClass(JNIEnv* env) {
911 return JavaException::getJClass(env, "java/lang/IllegalArgumentException");
912 }
913
914 /**
915 * Create and throw a Java IllegalArgumentException with the provided status
916 *
917 * If s.ok() == true, then this function will not throw any exception.
918 *
919 * @param env A pointer to the Java environment
920 * @param s The status for the exception
921 *
922 * @return true if an exception was thrown, false otherwise
923 */
924 static bool ThrowNew(JNIEnv* env, const Status& s) {
925 assert(!s.ok());
926 if (s.ok()) {
927 return false;
928 }
929
930 // get the IllegalArgumentException class
931 jclass jclazz = getJClass(env);
932 if(jclazz == nullptr) {
933 // exception occurred accessing class
934 std::cerr << "IllegalArgumentExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
935 return env->ExceptionCheck();
936 }
937
938 return JavaException::ThrowNew(env, s.ToString());
939 }
940};
941
942
943// The portal class for org.rocksdb.Options
944class OptionsJni : public RocksDBNativeClass<
945 rocksdb::Options*, OptionsJni> {
946 public:
947 /**
948 * Get the Java Class org.rocksdb.Options
949 *
950 * @param env A pointer to the Java environment
951 *
952 * @return The Java Class or nullptr if one of the
953 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
954 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
955 */
956 static jclass getJClass(JNIEnv* env) {
957 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Options");
958 }
959};
960
961// The portal class for org.rocksdb.DBOptions
962class DBOptionsJni : public RocksDBNativeClass<
963 rocksdb::DBOptions*, DBOptionsJni> {
964 public:
965 /**
966 * Get the Java Class org.rocksdb.DBOptions
967 *
968 * @param env A pointer to the Java environment
969 *
970 * @return The Java Class or nullptr if one of the
971 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
972 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
973 */
974 static jclass getJClass(JNIEnv* env) {
975 return RocksDBNativeClass::getJClass(env, "org/rocksdb/DBOptions");
976 }
977};
978
11fdf7f2
TL
979// The portal class for org.rocksdb.ColumnFamilyOptions
980class ColumnFamilyOptionsJni
981 : public RocksDBNativeClass<rocksdb::ColumnFamilyOptions*,
982 ColumnFamilyOptionsJni> {
7c673cae
FG
983 public:
984 /**
11fdf7f2 985 * Get the Java Class org.rocksdb.ColumnFamilyOptions
7c673cae
FG
986 *
987 * @param env A pointer to the Java environment
988 *
989 * @return The Java Class or nullptr if one of the
990 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
991 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
992 */
993 static jclass getJClass(JNIEnv* env) {
11fdf7f2
TL
994 return RocksDBNativeClass::getJClass(env,
995 "org/rocksdb/ColumnFamilyOptions");
7c673cae
FG
996 }
997
998 /**
11fdf7f2
TL
999 * Create a new Java org.rocksdb.ColumnFamilyOptions object with the same
1000 * properties as the provided C++ rocksdb::ColumnFamilyOptions object
7c673cae
FG
1001 *
1002 * @param env A pointer to the Java environment
11fdf7f2 1003 * @param cfoptions A pointer to rocksdb::ColumnFamilyOptions object
7c673cae 1004 *
11fdf7f2
TL
1005 * @return A reference to a Java org.rocksdb.ColumnFamilyOptions object, or
1006 * nullptr if an an exception occurs
7c673cae 1007 */
11fdf7f2
TL
1008 static jobject construct(JNIEnv* env, const ColumnFamilyOptions* cfoptions) {
1009 auto* cfo = new rocksdb::ColumnFamilyOptions(*cfoptions);
7c673cae
FG
1010 jclass jclazz = getJClass(env);
1011 if(jclazz == nullptr) {
1012 // exception occurred accessing class
1013 return nullptr;
1014 }
1015
11fdf7f2
TL
1016 jmethodID mid = env->GetMethodID(jclazz, "<init>", "(J)V");
1017 if (mid == nullptr) {
1018 // exception thrown: NoSuchMethodException or OutOfMemoryError
7c673cae
FG
1019 return nullptr;
1020 }
1021
11fdf7f2
TL
1022 jobject jcfd = env->NewObject(jclazz, mid, reinterpret_cast<jlong>(cfo));
1023 if (env->ExceptionCheck()) {
1024 return nullptr;
1025 }
7c673cae 1026
11fdf7f2 1027 return jcfd;
7c673cae
FG
1028 }
1029};
1030
1031// The portal class for org.rocksdb.WriteOptions
1032class WriteOptionsJni : public RocksDBNativeClass<
1033 rocksdb::WriteOptions*, WriteOptionsJni> {
1034 public:
1035 /**
1036 * Get the Java Class org.rocksdb.WriteOptions
1037 *
1038 * @param env A pointer to the Java environment
1039 *
1040 * @return The Java Class or nullptr if one of the
1041 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1042 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1043 */
1044 static jclass getJClass(JNIEnv* env) {
1045 return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteOptions");
1046 }
1047};
1048
1049// The portal class for org.rocksdb.ReadOptions
1050class ReadOptionsJni : public RocksDBNativeClass<
1051 rocksdb::ReadOptions*, ReadOptionsJni> {
1052 public:
1053 /**
1054 * Get the Java Class org.rocksdb.ReadOptions
1055 *
1056 * @param env A pointer to the Java environment
1057 *
1058 * @return The Java Class or nullptr if one of the
1059 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1060 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1061 */
1062 static jclass getJClass(JNIEnv* env) {
1063 return RocksDBNativeClass::getJClass(env, "org/rocksdb/ReadOptions");
1064 }
1065};
1066
1067// The portal class for org.rocksdb.WriteBatch
1068class WriteBatchJni : public RocksDBNativeClass<
1069 rocksdb::WriteBatch*, WriteBatchJni> {
1070 public:
1071 /**
1072 * Get the Java Class org.rocksdb.WriteBatch
1073 *
1074 * @param env A pointer to the Java environment
1075 *
1076 * @return The Java Class or nullptr if one of the
1077 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1078 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1079 */
1080 static jclass getJClass(JNIEnv* env) {
1081 return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteBatch");
1082 }
11fdf7f2
TL
1083
1084 /**
1085 * Create a new Java org.rocksdb.WriteBatch object
1086 *
1087 * @param env A pointer to the Java environment
1088 * @param wb A pointer to rocksdb::WriteBatch object
1089 *
1090 * @return A reference to a Java org.rocksdb.WriteBatch object, or
1091 * nullptr if an an exception occurs
1092 */
1093 static jobject construct(JNIEnv* env, const WriteBatch* wb) {
1094 jclass jclazz = getJClass(env);
1095 if(jclazz == nullptr) {
1096 // exception occurred accessing class
1097 return nullptr;
1098 }
1099
1100 jmethodID mid = env->GetMethodID(jclazz, "<init>", "(J)V");
1101 if (mid == nullptr) {
1102 // exception thrown: NoSuchMethodException or OutOfMemoryError
1103 return nullptr;
1104 }
1105
1106 jobject jwb = env->NewObject(jclazz, mid, reinterpret_cast<jlong>(wb));
1107 if (env->ExceptionCheck()) {
1108 return nullptr;
1109 }
1110
1111 return jwb;
1112 }
7c673cae
FG
1113};
1114
1115// The portal class for org.rocksdb.WriteBatch.Handler
1116class WriteBatchHandlerJni : public RocksDBNativeClass<
1117 const rocksdb::WriteBatchHandlerJniCallback*,
1118 WriteBatchHandlerJni> {
1119 public:
1120 /**
1121 * Get the Java Class org.rocksdb.WriteBatch.Handler
1122 *
1123 * @param env A pointer to the Java environment
1124 *
1125 * @return The Java Class or nullptr if one of the
1126 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1127 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1128 */
1129 static jclass getJClass(JNIEnv* env) {
1130 return RocksDBNativeClass::getJClass(env,
1131 "org/rocksdb/WriteBatch$Handler");
1132 }
1133
1134 /**
1135 * Get the Java Method: WriteBatch.Handler#put
1136 *
1137 * @param env A pointer to the Java environment
1138 *
1139 * @return The Java Method ID or nullptr if the class or method id could not
1140 * be retieved
1141 */
11fdf7f2 1142 static jmethodID getPutCfMethodId(JNIEnv* env) {
7c673cae
FG
1143 jclass jclazz = getJClass(env);
1144 if(jclazz == nullptr) {
1145 // exception occurred accessing class
1146 return nullptr;
1147 }
1148
11fdf7f2 1149 static jmethodID mid = env->GetMethodID(jclazz, "put", "(I[B[B)V");
7c673cae
FG
1150 assert(mid != nullptr);
1151 return mid;
1152 }
1153
1154 /**
11fdf7f2 1155 * Get the Java Method: WriteBatch.Handler#put
7c673cae
FG
1156 *
1157 * @param env A pointer to the Java environment
1158 *
1159 * @return The Java Method ID or nullptr if the class or method id could not
1160 * be retieved
1161 */
11fdf7f2 1162 static jmethodID getPutMethodId(JNIEnv* env) {
7c673cae
FG
1163 jclass jclazz = getJClass(env);
1164 if(jclazz == nullptr) {
1165 // exception occurred accessing class
1166 return nullptr;
1167 }
1168
11fdf7f2 1169 static jmethodID mid = env->GetMethodID(jclazz, "put", "([B[B)V");
7c673cae
FG
1170 assert(mid != nullptr);
1171 return mid;
1172 }
1173
1174 /**
11fdf7f2 1175 * Get the Java Method: WriteBatch.Handler#merge
7c673cae
FG
1176 *
1177 * @param env A pointer to the Java environment
1178 *
1179 * @return The Java Method ID or nullptr if the class or method id could not
1180 * be retieved
1181 */
11fdf7f2 1182 static jmethodID getMergeCfMethodId(JNIEnv* env) {
7c673cae
FG
1183 jclass jclazz = getJClass(env);
1184 if(jclazz == nullptr) {
1185 // exception occurred accessing class
1186 return nullptr;
1187 }
1188
11fdf7f2 1189 static jmethodID mid = env->GetMethodID(jclazz, "merge", "(I[B[B)V");
7c673cae
FG
1190 assert(mid != nullptr);
1191 return mid;
1192 }
1193
1194 /**
11fdf7f2 1195 * Get the Java Method: WriteBatch.Handler#merge
7c673cae
FG
1196 *
1197 * @param env A pointer to the Java environment
1198 *
1199 * @return The Java Method ID or nullptr if the class or method id could not
1200 * be retieved
1201 */
11fdf7f2 1202 static jmethodID getMergeMethodId(JNIEnv* env) {
7c673cae 1203 jclass jclazz = getJClass(env);
11fdf7f2 1204 if(jclazz == nullptr) {
7c673cae
FG
1205 // exception occurred accessing class
1206 return nullptr;
1207 }
1208
11fdf7f2 1209 static jmethodID mid = env->GetMethodID(jclazz, "merge", "([B[B)V");
7c673cae
FG
1210 assert(mid != nullptr);
1211 return mid;
1212 }
1213
1214 /**
11fdf7f2 1215 * Get the Java Method: WriteBatch.Handler#delete
7c673cae
FG
1216 *
1217 * @param env A pointer to the Java environment
1218 *
1219 * @return The Java Method ID or nullptr if the class or method id could not
1220 * be retieved
1221 */
11fdf7f2 1222 static jmethodID getDeleteCfMethodId(JNIEnv* env) {
7c673cae
FG
1223 jclass jclazz = getJClass(env);
1224 if(jclazz == nullptr) {
1225 // exception occurred accessing class
1226 return nullptr;
1227 }
1228
11fdf7f2 1229 static jmethodID mid = env->GetMethodID(jclazz, "delete", "(I[B)V");
7c673cae
FG
1230 assert(mid != nullptr);
1231 return mid;
1232 }
1233
1234 /**
11fdf7f2 1235 * Get the Java Method: WriteBatch.Handler#delete
7c673cae
FG
1236 *
1237 * @param env A pointer to the Java environment
1238 *
1239 * @return The Java Method ID or nullptr if the class or method id could not
1240 * be retieved
1241 */
11fdf7f2 1242 static jmethodID getDeleteMethodId(JNIEnv* env) {
7c673cae
FG
1243 jclass jclazz = getJClass(env);
1244 if(jclazz == nullptr) {
1245 // exception occurred accessing class
1246 return nullptr;
1247 }
1248
11fdf7f2 1249 static jmethodID mid = env->GetMethodID(jclazz, "delete", "([B)V");
7c673cae
FG
1250 assert(mid != nullptr);
1251 return mid;
1252 }
7c673cae 1253
7c673cae 1254 /**
11fdf7f2 1255 * Get the Java Method: WriteBatch.Handler#singleDelete
7c673cae
FG
1256 *
1257 * @param env A pointer to the Java environment
1258 *
11fdf7f2
TL
1259 * @return The Java Method ID or nullptr if the class or method id could not
1260 * be retieved
7c673cae 1261 */
11fdf7f2
TL
1262 static jmethodID getSingleDeleteCfMethodId(JNIEnv* env) {
1263 jclass jclazz = getJClass(env);
1264 if(jclazz == nullptr) {
1265 // exception occurred accessing class
1266 return nullptr;
1267 }
1268
1269 static jmethodID mid = env->GetMethodID(jclazz, "singleDelete", "(I[B)V");
1270 assert(mid != nullptr);
1271 return mid;
7c673cae 1272 }
7c673cae 1273
7c673cae 1274 /**
11fdf7f2 1275 * Get the Java Method: WriteBatch.Handler#singleDelete
7c673cae
FG
1276 *
1277 * @param env A pointer to the Java environment
1278 *
11fdf7f2
TL
1279 * @return The Java Method ID or nullptr if the class or method id could not
1280 * be retieved
7c673cae 1281 */
11fdf7f2
TL
1282 static jmethodID getSingleDeleteMethodId(JNIEnv* env) {
1283 jclass jclazz = getJClass(env);
1284 if(jclazz == nullptr) {
1285 // exception occurred accessing class
1286 return nullptr;
1287 }
1288
1289 static jmethodID mid = env->GetMethodID(jclazz, "singleDelete", "([B)V");
1290 assert(mid != nullptr);
1291 return mid;
7c673cae
FG
1292 }
1293
1294 /**
11fdf7f2 1295 * Get the Java Method: WriteBatch.Handler#deleteRange
7c673cae
FG
1296 *
1297 * @param env A pointer to the Java environment
1298 *
1299 * @return The Java Method ID or nullptr if the class or method id could not
1300 * be retieved
1301 */
11fdf7f2 1302 static jmethodID getDeleteRangeCfMethodId(JNIEnv* env) {
7c673cae 1303 jclass jclazz = getJClass(env);
11fdf7f2 1304 if (jclazz == nullptr) {
7c673cae
FG
1305 // exception occurred accessing class
1306 return nullptr;
1307 }
1308
11fdf7f2 1309 static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "(I[B[B)V");
7c673cae
FG
1310 assert(mid != nullptr);
1311 return mid;
1312 }
7c673cae 1313
7c673cae 1314 /**
11fdf7f2 1315 * Get the Java Method: WriteBatch.Handler#deleteRange
7c673cae
FG
1316 *
1317 * @param env A pointer to the Java environment
1318 *
11fdf7f2
TL
1319 * @return The Java Method ID or nullptr if the class or method id could not
1320 * be retieved
7c673cae 1321 */
11fdf7f2
TL
1322 static jmethodID getDeleteRangeMethodId(JNIEnv* env) {
1323 jclass jclazz = getJClass(env);
1324 if (jclazz == nullptr) {
1325 // exception occurred accessing class
1326 return nullptr;
1327 }
1328
1329 static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "([B[B)V");
1330 assert(mid != nullptr);
1331 return mid;
7c673cae 1332 }
7c673cae 1333
7c673cae 1334 /**
11fdf7f2 1335 * Get the Java Method: WriteBatch.Handler#logData
7c673cae
FG
1336 *
1337 * @param env A pointer to the Java environment
1338 *
11fdf7f2
TL
1339 * @return The Java Method ID or nullptr if the class or method id could not
1340 * be retieved
7c673cae 1341 */
11fdf7f2
TL
1342 static jmethodID getLogDataMethodId(JNIEnv* env) {
1343 jclass jclazz = getJClass(env);
1344 if(jclazz == nullptr) {
1345 // exception occurred accessing class
1346 return nullptr;
1347 }
1348
1349 static jmethodID mid = env->GetMethodID(jclazz, "logData", "([B)V");
1350 assert(mid != nullptr);
1351 return mid;
7c673cae 1352 }
7c673cae 1353
7c673cae 1354 /**
11fdf7f2 1355 * Get the Java Method: WriteBatch.Handler#putBlobIndex
7c673cae
FG
1356 *
1357 * @param env A pointer to the Java environment
1358 *
11fdf7f2
TL
1359 * @return The Java Method ID or nullptr if the class or method id could not
1360 * be retieved
7c673cae 1361 */
11fdf7f2
TL
1362 static jmethodID getPutBlobIndexCfMethodId(JNIEnv* env) {
1363 jclass jclazz = getJClass(env);
1364 if(jclazz == nullptr) {
1365 // exception occurred accessing class
1366 return nullptr;
1367 }
1368
1369 static jmethodID mid = env->GetMethodID(jclazz, "putBlobIndex", "(I[B[B)V");
1370 assert(mid != nullptr);
1371 return mid;
7c673cae 1372 }
7c673cae 1373
7c673cae 1374 /**
11fdf7f2 1375 * Get the Java Method: WriteBatch.Handler#markBeginPrepare
7c673cae
FG
1376 *
1377 * @param env A pointer to the Java environment
1378 *
11fdf7f2
TL
1379 * @return The Java Method ID or nullptr if the class or method id could not
1380 * be retieved
7c673cae 1381 */
11fdf7f2
TL
1382 static jmethodID getMarkBeginPrepareMethodId(JNIEnv* env) {
1383 jclass jclazz = getJClass(env);
1384 if(jclazz == nullptr) {
1385 // exception occurred accessing class
1386 return nullptr;
1387 }
1388
1389 static jmethodID mid = env->GetMethodID(jclazz, "markBeginPrepare", "()V");
1390 assert(mid != nullptr);
1391 return mid;
7c673cae 1392 }
7c673cae 1393
7c673cae 1394 /**
11fdf7f2 1395 * Get the Java Method: WriteBatch.Handler#markEndPrepare
7c673cae
FG
1396 *
1397 * @param env A pointer to the Java environment
1398 *
11fdf7f2
TL
1399 * @return The Java Method ID or nullptr if the class or method id could not
1400 * be retieved
7c673cae 1401 */
11fdf7f2
TL
1402 static jmethodID getMarkEndPrepareMethodId(JNIEnv* env) {
1403 jclass jclazz = getJClass(env);
1404 if(jclazz == nullptr) {
1405 // exception occurred accessing class
1406 return nullptr;
1407 }
1408
1409 static jmethodID mid = env->GetMethodID(jclazz, "markEndPrepare", "([B)V");
1410 assert(mid != nullptr);
1411 return mid;
7c673cae 1412 }
7c673cae 1413
7c673cae 1414 /**
11fdf7f2 1415 * Get the Java Method: WriteBatch.Handler#markNoop
7c673cae
FG
1416 *
1417 * @param env A pointer to the Java environment
1418 *
11fdf7f2
TL
1419 * @return The Java Method ID or nullptr if the class or method id could not
1420 * be retieved
7c673cae 1421 */
11fdf7f2
TL
1422 static jmethodID getMarkNoopMethodId(JNIEnv* env) {
1423 jclass jclazz = getJClass(env);
1424 if(jclazz == nullptr) {
1425 // exception occurred accessing class
1426 return nullptr;
1427 }
7c673cae 1428
11fdf7f2
TL
1429 static jmethodID mid = env->GetMethodID(jclazz, "markNoop", "(Z)V");
1430 assert(mid != nullptr);
1431 return mid;
7c673cae 1432 }
7c673cae 1433
7c673cae 1434 /**
11fdf7f2 1435 * Get the Java Method: WriteBatch.Handler#markRollback
7c673cae
FG
1436 *
1437 * @param env A pointer to the Java environment
1438 *
11fdf7f2
TL
1439 * @return The Java Method ID or nullptr if the class or method id could not
1440 * be retieved
7c673cae 1441 */
11fdf7f2
TL
1442 static jmethodID getMarkRollbackMethodId(JNIEnv* env) {
1443 jclass jclazz = getJClass(env);
1444 if(jclazz == nullptr) {
1445 // exception occurred accessing class
1446 return nullptr;
1447 }
1448
1449 static jmethodID mid = env->GetMethodID(jclazz, "markRollback", "([B)V");
1450 assert(mid != nullptr);
1451 return mid;
7c673cae
FG
1452 }
1453
1454 /**
11fdf7f2 1455 * Get the Java Method: WriteBatch.Handler#markCommit
7c673cae
FG
1456 *
1457 * @param env A pointer to the Java environment
1458 *
1459 * @return The Java Method ID or nullptr if the class or method id could not
1460 * be retieved
1461 */
11fdf7f2 1462 static jmethodID getMarkCommitMethodId(JNIEnv* env) {
7c673cae
FG
1463 jclass jclazz = getJClass(env);
1464 if(jclazz == nullptr) {
1465 // exception occurred accessing class
1466 return nullptr;
1467 }
1468
11fdf7f2 1469 static jmethodID mid = env->GetMethodID(jclazz, "markCommit", "([B)V");
7c673cae
FG
1470 assert(mid != nullptr);
1471 return mid;
1472 }
1473
1474 /**
11fdf7f2 1475 * Get the Java Method: WriteBatch.Handler#shouldContinue
7c673cae
FG
1476 *
1477 * @param env A pointer to the Java environment
1478 *
1479 * @return The Java Method ID or nullptr if the class or method id could not
1480 * be retieved
1481 */
11fdf7f2 1482 static jmethodID getContinueMethodId(JNIEnv* env) {
7c673cae
FG
1483 jclass jclazz = getJClass(env);
1484 if(jclazz == nullptr) {
1485 // exception occurred accessing class
1486 return nullptr;
1487 }
1488
11fdf7f2 1489 static jmethodID mid = env->GetMethodID(jclazz, "shouldContinue", "()Z");
7c673cae
FG
1490 assert(mid != nullptr);
1491 return mid;
1492 }
11fdf7f2 1493};
7c673cae 1494
11fdf7f2
TL
1495class WriteBatchSavePointJni : public JavaClass {
1496 public:
7c673cae 1497 /**
11fdf7f2
TL
1498 * Get the Java Class org.rocksdb.WriteBatch.SavePoint
1499 *
1500 * @param env A pointer to the Java environment
1501 *
1502 * @return The Java Class or nullptr if one of the
1503 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1504 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1505 */
1506 static jclass getJClass(JNIEnv* env) {
1507 return JavaClass::getJClass(env, "org/rocksdb/WriteBatch$SavePoint");
1508 }
1509
1510 /**
1511 * Get the Java Method: HistogramData constructor
7c673cae
FG
1512 *
1513 * @param env A pointer to the Java environment
1514 *
1515 * @return The Java Method ID or nullptr if the class or method id could not
1516 * be retieved
1517 */
11fdf7f2 1518 static jmethodID getConstructorMethodId(JNIEnv* env) {
7c673cae
FG
1519 jclass jclazz = getJClass(env);
1520 if(jclazz == nullptr) {
1521 // exception occurred accessing class
1522 return nullptr;
1523 }
1524
11fdf7f2 1525 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JJJ)V");
7c673cae
FG
1526 assert(mid != nullptr);
1527 return mid;
1528 }
1529
1530 /**
11fdf7f2 1531 * Create a new Java org.rocksdb.WriteBatch.SavePoint object
7c673cae
FG
1532 *
1533 * @param env A pointer to the Java environment
11fdf7f2 1534 * @param savePoint A pointer to rocksdb::WriteBatch::SavePoint object
7c673cae 1535 *
11fdf7f2
TL
1536 * @return A reference to a Java org.rocksdb.WriteBatch.SavePoint object, or
1537 * nullptr if an an exception occurs
7c673cae 1538 */
11fdf7f2 1539 static jobject construct(JNIEnv* env, const SavePoint &save_point) {
7c673cae
FG
1540 jclass jclazz = getJClass(env);
1541 if(jclazz == nullptr) {
1542 // exception occurred accessing class
1543 return nullptr;
1544 }
1545
11fdf7f2
TL
1546 jmethodID mid = getConstructorMethodId(env);
1547 if (mid == nullptr) {
1548 // exception thrown: NoSuchMethodException or OutOfMemoryError
1549 return nullptr;
1550 }
1551
1552 jobject jsave_point = env->NewObject(jclazz, mid,
1553 static_cast<jlong>(save_point.size),
1554 static_cast<jlong>(save_point.count),
1555 static_cast<jlong>(save_point.content_flags));
1556 if (env->ExceptionCheck()) {
1557 return nullptr;
1558 }
1559
1560 return jsave_point;
7c673cae
FG
1561 }
1562};
1563
11fdf7f2
TL
1564// The portal class for org.rocksdb.WriteBatchWithIndex
1565class WriteBatchWithIndexJni : public RocksDBNativeClass<
1566 rocksdb::WriteBatchWithIndex*, WriteBatchWithIndexJni> {
7c673cae
FG
1567 public:
1568 /**
11fdf7f2 1569 * Get the Java Class org.rocksdb.WriteBatchWithIndex
7c673cae
FG
1570 *
1571 * @param env A pointer to the Java environment
1572 *
1573 * @return The Java Class or nullptr if one of the
1574 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1575 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1576 */
1577 static jclass getJClass(JNIEnv* env) {
11fdf7f2
TL
1578 return RocksDBNativeClass::getJClass(env,
1579 "org/rocksdb/WriteBatchWithIndex");
7c673cae
FG
1580 }
1581};
1582
11fdf7f2
TL
1583// The portal class for org.rocksdb.HistogramData
1584class HistogramDataJni : public JavaClass {
7c673cae
FG
1585 public:
1586 /**
11fdf7f2 1587 * Get the Java Class org.rocksdb.HistogramData
7c673cae
FG
1588 *
1589 * @param env A pointer to the Java environment
1590 *
1591 * @return The Java Class or nullptr if one of the
1592 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1593 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1594 */
1595 static jclass getJClass(JNIEnv* env) {
11fdf7f2 1596 return JavaClass::getJClass(env, "org/rocksdb/HistogramData");
7c673cae
FG
1597 }
1598
1599 /**
11fdf7f2 1600 * Get the Java Method: HistogramData constructor
7c673cae
FG
1601 *
1602 * @param env A pointer to the Java environment
1603 *
11fdf7f2
TL
1604 * @return The Java Method ID or nullptr if the class or method id could not
1605 * be retieved
7c673cae 1606 */
11fdf7f2 1607 static jmethodID getConstructorMethodId(JNIEnv* env) {
7c673cae
FG
1608 jclass jclazz = getJClass(env);
1609 if(jclazz == nullptr) {
1610 // exception occurred accessing class
1611 return nullptr;
1612 }
1613
11fdf7f2
TL
1614 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(DDDDD)V");
1615 assert(mid != nullptr);
1616 return mid;
7c673cae
FG
1617 }
1618};
1619
11fdf7f2
TL
1620// The portal class for org.rocksdb.BackupableDBOptions
1621class BackupableDBOptionsJni : public RocksDBNativeClass<
1622 rocksdb::BackupableDBOptions*, BackupableDBOptionsJni> {
7c673cae
FG
1623 public:
1624 /**
11fdf7f2 1625 * Get the Java Class org.rocksdb.BackupableDBOptions
7c673cae
FG
1626 *
1627 * @param env A pointer to the Java environment
1628 *
1629 * @return The Java Class or nullptr if one of the
1630 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1631 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1632 */
1633 static jclass getJClass(JNIEnv* env) {
11fdf7f2
TL
1634 return RocksDBNativeClass::getJClass(env,
1635 "org/rocksdb/BackupableDBOptions");
7c673cae 1636 }
11fdf7f2 1637};
7c673cae 1638
11fdf7f2
TL
1639// The portal class for org.rocksdb.BackupEngine
1640class BackupEngineJni : public RocksDBNativeClass<
1641 rocksdb::BackupEngine*, BackupEngineJni> {
1642 public:
7c673cae 1643 /**
11fdf7f2 1644 * Get the Java Class org.rocksdb.BackupableEngine
7c673cae
FG
1645 *
1646 * @param env A pointer to the Java environment
1647 *
11fdf7f2
TL
1648 * @return The Java Class or nullptr if one of the
1649 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1650 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 1651 */
11fdf7f2
TL
1652 static jclass getJClass(JNIEnv* env) {
1653 return RocksDBNativeClass::getJClass(env, "org/rocksdb/BackupEngine");
7c673cae
FG
1654 }
1655};
1656
11fdf7f2
TL
1657// The portal class for org.rocksdb.RocksIterator
1658class IteratorJni : public RocksDBNativeClass<
1659 rocksdb::Iterator*, IteratorJni> {
7c673cae
FG
1660 public:
1661 /**
11fdf7f2 1662 * Get the Java Class org.rocksdb.RocksIterator
7c673cae
FG
1663 *
1664 * @param env A pointer to the Java environment
1665 *
1666 * @return The Java Class or nullptr if one of the
1667 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1668 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1669 */
11fdf7f2
TL
1670 static jclass getJClass(JNIEnv* env) {
1671 return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksIterator");
7c673cae 1672 }
11fdf7f2 1673};
7c673cae 1674
11fdf7f2
TL
1675// The portal class for org.rocksdb.Filter
1676class FilterJni : public RocksDBNativeClass<
1677 std::shared_ptr<rocksdb::FilterPolicy>*, FilterJni> {
1678 public:
7c673cae 1679 /**
11fdf7f2 1680 * Get the Java Class org.rocksdb.Filter
7c673cae
FG
1681 *
1682 * @param env A pointer to the Java environment
1683 *
1684 * @return The Java Class or nullptr if one of the
1685 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1686 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1687 */
11fdf7f2
TL
1688 static jclass getJClass(JNIEnv* env) {
1689 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Filter");
7c673cae 1690 }
11fdf7f2 1691};
7c673cae 1692
11fdf7f2
TL
1693// The portal class for org.rocksdb.ColumnFamilyHandle
1694class ColumnFamilyHandleJni : public RocksDBNativeClass<
1695 rocksdb::ColumnFamilyHandle*, ColumnFamilyHandleJni> {
1696 public:
7c673cae 1697 /**
11fdf7f2 1698 * Get the Java Class org.rocksdb.ColumnFamilyHandle
7c673cae
FG
1699 *
1700 * @param env A pointer to the Java environment
1701 *
1702 * @return The Java Class or nullptr if one of the
1703 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1704 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1705 */
11fdf7f2
TL
1706 static jclass getJClass(JNIEnv* env) {
1707 return RocksDBNativeClass::getJClass(env,
1708 "org/rocksdb/ColumnFamilyHandle");
7c673cae 1709 }
11fdf7f2 1710};
7c673cae 1711
11fdf7f2
TL
1712// The portal class for org.rocksdb.FlushOptions
1713class FlushOptionsJni : public RocksDBNativeClass<
1714 rocksdb::FlushOptions*, FlushOptionsJni> {
1715 public:
7c673cae 1716 /**
11fdf7f2 1717 * Get the Java Class org.rocksdb.FlushOptions
7c673cae
FG
1718 *
1719 * @param env A pointer to the Java environment
1720 *
11fdf7f2
TL
1721 * @return The Java Class or nullptr if one of the
1722 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1723 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 1724 */
11fdf7f2
TL
1725 static jclass getJClass(JNIEnv* env) {
1726 return RocksDBNativeClass::getJClass(env, "org/rocksdb/FlushOptions");
7c673cae 1727 }
11fdf7f2 1728};
7c673cae 1729
11fdf7f2
TL
1730// The portal class for org.rocksdb.ComparatorOptions
1731class ComparatorOptionsJni : public RocksDBNativeClass<
1732 rocksdb::ComparatorJniCallbackOptions*, ComparatorOptionsJni> {
1733 public:
7c673cae 1734 /**
11fdf7f2 1735 * Get the Java Class org.rocksdb.ComparatorOptions
7c673cae
FG
1736 *
1737 * @param env A pointer to the Java environment
1738 *
11fdf7f2
TL
1739 * @return The Java Class or nullptr if one of the
1740 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1741 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 1742 */
11fdf7f2
TL
1743 static jclass getJClass(JNIEnv* env) {
1744 return RocksDBNativeClass::getJClass(env, "org/rocksdb/ComparatorOptions");
7c673cae 1745 }
11fdf7f2 1746};
7c673cae 1747
11fdf7f2
TL
1748// The portal class for org.rocksdb.AbstractCompactionFilterFactory
1749class AbstractCompactionFilterFactoryJni : public RocksDBNativeClass<
1750 const rocksdb::CompactionFilterFactoryJniCallback*,
1751 AbstractCompactionFilterFactoryJni> {
1752 public:
7c673cae 1753 /**
11fdf7f2 1754 * Get the Java Class org.rocksdb.AbstractCompactionFilterFactory
7c673cae
FG
1755 *
1756 * @param env A pointer to the Java environment
1757 *
11fdf7f2
TL
1758 * @return The Java Class or nullptr if one of the
1759 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1760 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 1761 */
11fdf7f2
TL
1762 static jclass getJClass(JNIEnv* env) {
1763 return RocksDBNativeClass::getJClass(env,
1764 "org/rocksdb/AbstractCompactionFilterFactory");
7c673cae
FG
1765 }
1766
1767 /**
11fdf7f2 1768 * Get the Java Method: AbstractCompactionFilterFactory#name
7c673cae
FG
1769 *
1770 * @param env A pointer to the Java environment
1771 *
1772 * @return The Java Method ID or nullptr if the class or method id could not
1773 * be retieved
1774 */
11fdf7f2
TL
1775 static jmethodID getNameMethodId(JNIEnv* env) {
1776 jclass jclazz = getJClass(env);
1777 if(jclazz == nullptr) {
7c673cae
FG
1778 // exception occurred accessing class
1779 return nullptr;
1780 }
11fdf7f2
TL
1781
1782 static jmethodID mid = env->GetMethodID(
1783 jclazz, "name", "()Ljava/lang/String;");
7c673cae
FG
1784 assert(mid != nullptr);
1785 return mid;
1786 }
1787
1788 /**
11fdf7f2 1789 * Get the Java Method: AbstractCompactionFilterFactory#createCompactionFilter
7c673cae
FG
1790 *
1791 * @param env A pointer to the Java environment
1792 *
1793 * @return The Java Method ID or nullptr if the class or method id could not
1794 * be retieved
1795 */
11fdf7f2
TL
1796 static jmethodID getCreateCompactionFilterMethodId(JNIEnv* env) {
1797 jclass jclazz = getJClass(env);
1798 if(jclazz == nullptr) {
7c673cae
FG
1799 // exception occurred accessing class
1800 return nullptr;
1801 }
1802
11fdf7f2
TL
1803 static jmethodID mid = env->GetMethodID(jclazz,
1804 "createCompactionFilter",
1805 "(ZZ)J");
7c673cae
FG
1806 assert(mid != nullptr);
1807 return mid;
1808 }
1809};
1810
11fdf7f2
TL
1811// The portal class for org.rocksdb.AbstractTransactionNotifier
1812class AbstractTransactionNotifierJni : public RocksDBNativeClass<
1813 const rocksdb::TransactionNotifierJniCallback*,
1814 AbstractTransactionNotifierJni> {
7c673cae 1815 public:
7c673cae 1816 static jclass getJClass(JNIEnv* env) {
11fdf7f2
TL
1817 return RocksDBNativeClass::getJClass(env,
1818 "org/rocksdb/AbstractTransactionNotifier");
7c673cae
FG
1819 }
1820
11fdf7f2
TL
1821 // Get the java method `snapshotCreated`
1822 // of org.rocksdb.AbstractTransactionNotifier.
1823 static jmethodID getSnapshotCreatedMethodId(JNIEnv* env) {
1824 jclass jclazz = getJClass(env);
1825 if(jclazz == nullptr) {
1826 // exception occurred accessing class
1827 return nullptr;
1828 }
1829
1830 static jmethodID mid = env->GetMethodID(jclazz, "snapshotCreated", "(J)V");
1831 assert(mid != nullptr);
1832 return mid;
1833 }
1834};
1835
1836// The portal class for org.rocksdb.AbstractComparator
1837class AbstractComparatorJni : public RocksDBNativeClass<
1838 const rocksdb::BaseComparatorJniCallback*,
1839 AbstractComparatorJni> {
1840 public:
7c673cae 1841 /**
11fdf7f2 1842 * Get the Java Class org.rocksdb.AbstractComparator
7c673cae
FG
1843 *
1844 * @param env A pointer to the Java environment
1845 *
1846 * @return The Java Class or nullptr if one of the
1847 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1848 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1849 */
11fdf7f2
TL
1850 static jclass getJClass(JNIEnv* env) {
1851 return RocksDBNativeClass::getJClass(env,
1852 "org/rocksdb/AbstractComparator");
7c673cae
FG
1853 }
1854
1855 /**
11fdf7f2 1856 * Get the Java Method: Comparator#name
7c673cae
FG
1857 *
1858 * @param env A pointer to the Java environment
7c673cae 1859 *
11fdf7f2
TL
1860 * @return The Java Method ID or nullptr if the class or method id could not
1861 * be retieved
7c673cae 1862 */
11fdf7f2
TL
1863 static jmethodID getNameMethodId(JNIEnv* env) {
1864 jclass jclazz = getJClass(env);
1865 if(jclazz == nullptr) {
7c673cae
FG
1866 // exception occurred accessing class
1867 return nullptr;
1868 }
1869
11fdf7f2
TL
1870 static jmethodID mid =
1871 env->GetMethodID(jclazz, "name", "()Ljava/lang/String;");
1872 assert(mid != nullptr);
1873 return mid;
7c673cae
FG
1874 }
1875
1876 /**
11fdf7f2 1877 * Get the Java Method: Comparator#compare
7c673cae
FG
1878 *
1879 * @param env A pointer to the Java environment
1880 *
1881 * @return The Java Method ID or nullptr if the class or method id could not
1882 * be retieved
1883 */
11fdf7f2
TL
1884 static jmethodID getCompareMethodId(JNIEnv* env) {
1885 jclass jclazz = getJClass(env);
1886 if(jclazz == nullptr) {
7c673cae
FG
1887 // exception occurred accessing class
1888 return nullptr;
1889 }
1890
11fdf7f2
TL
1891 static jmethodID mid =
1892 env->GetMethodID(jclazz, "compare",
1893 "(Lorg/rocksdb/AbstractSlice;Lorg/rocksdb/AbstractSlice;)I");
7c673cae
FG
1894 assert(mid != nullptr);
1895 return mid;
1896 }
7c673cae 1897
7c673cae 1898 /**
11fdf7f2 1899 * Get the Java Method: Comparator#findShortestSeparator
7c673cae
FG
1900 *
1901 * @param env A pointer to the Java environment
1902 *
11fdf7f2
TL
1903 * @return The Java Method ID or nullptr if the class or method id could not
1904 * be retieved
7c673cae 1905 */
11fdf7f2
TL
1906 static jmethodID getFindShortestSeparatorMethodId(JNIEnv* env) {
1907 jclass jclazz = getJClass(env);
1908 if(jclazz == nullptr) {
1909 // exception occurred accessing class
1910 return nullptr;
1911 }
1912
1913 static jmethodID mid =
1914 env->GetMethodID(jclazz, "findShortestSeparator",
1915 "(Ljava/lang/String;Lorg/rocksdb/AbstractSlice;)Ljava/lang/String;");
1916 assert(mid != nullptr);
1917 return mid;
7c673cae
FG
1918 }
1919
1920 /**
11fdf7f2 1921 * Get the Java Method: Comparator#findShortSuccessor
7c673cae
FG
1922 *
1923 * @param env A pointer to the Java environment
1924 *
1925 * @return The Java Method ID or nullptr if the class or method id could not
1926 * be retieved
1927 */
11fdf7f2 1928 static jmethodID getFindShortSuccessorMethodId(JNIEnv* env) {
7c673cae
FG
1929 jclass jclazz = getJClass(env);
1930 if(jclazz == nullptr) {
1931 // exception occurred accessing class
1932 return nullptr;
1933 }
1934
1935 static jmethodID mid =
11fdf7f2
TL
1936 env->GetMethodID(jclazz, "findShortSuccessor",
1937 "(Ljava/lang/String;)Ljava/lang/String;");
7c673cae
FG
1938 assert(mid != nullptr);
1939 return mid;
1940 }
11fdf7f2 1941};
7c673cae 1942
11fdf7f2
TL
1943// The portal class for org.rocksdb.AbstractSlice
1944class AbstractSliceJni : public NativeRocksMutableObject<
1945 const rocksdb::Slice*, AbstractSliceJni> {
1946 public:
7c673cae 1947 /**
11fdf7f2 1948 * Get the Java Class org.rocksdb.AbstractSlice
7c673cae
FG
1949 *
1950 * @param env A pointer to the Java environment
7c673cae 1951 *
11fdf7f2
TL
1952 * @return The Java Class or nullptr if one of the
1953 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1954 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 1955 */
11fdf7f2
TL
1956 static jclass getJClass(JNIEnv* env) {
1957 return RocksDBNativeClass::getJClass(env, "org/rocksdb/AbstractSlice");
7c673cae
FG
1958 }
1959};
1960
11fdf7f2
TL
1961// The portal class for org.rocksdb.Slice
1962class SliceJni : public NativeRocksMutableObject<
1963 const rocksdb::Slice*, AbstractSliceJni> {
7c673cae
FG
1964 public:
1965 /**
11fdf7f2 1966 * Get the Java Class org.rocksdb.Slice
7c673cae
FG
1967 *
1968 * @param env A pointer to the Java environment
1969 *
1970 * @return The Java Class or nullptr if one of the
1971 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1972 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1973 */
1974 static jclass getJClass(JNIEnv* env) {
11fdf7f2 1975 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Slice");
7c673cae
FG
1976 }
1977
1978 /**
11fdf7f2 1979 * Constructs a Slice object
7c673cae
FG
1980 *
1981 * @param env A pointer to the Java environment
7c673cae 1982 *
11fdf7f2 1983 * @return A reference to a Java Slice object, or a nullptr if an
7c673cae
FG
1984 * exception occurs
1985 */
11fdf7f2 1986 static jobject construct0(JNIEnv* env) {
7c673cae
FG
1987 jclass jclazz = getJClass(env);
1988 if(jclazz == nullptr) {
1989 // exception occurred accessing class
1990 return nullptr;
1991 }
1992
11fdf7f2 1993 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
7c673cae
FG
1994 if(mid == nullptr) {
1995 // exception occurred accessing method
1996 return nullptr;
1997 }
1998
11fdf7f2 1999 jobject jslice = env->NewObject(jclazz, mid);
7c673cae
FG
2000 if(env->ExceptionCheck()) {
2001 return nullptr;
2002 }
2003
11fdf7f2 2004 return jslice;
7c673cae
FG
2005 }
2006};
2007
11fdf7f2
TL
2008// The portal class for org.rocksdb.DirectSlice
2009class DirectSliceJni : public NativeRocksMutableObject<
2010 const rocksdb::Slice*, AbstractSliceJni> {
7c673cae
FG
2011 public:
2012 /**
11fdf7f2 2013 * Get the Java Class org.rocksdb.DirectSlice
7c673cae
FG
2014 *
2015 * @param env A pointer to the Java environment
7c673cae 2016 *
11fdf7f2
TL
2017 * @return The Java Class or nullptr if one of the
2018 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2019 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 2020 */
11fdf7f2
TL
2021 static jclass getJClass(JNIEnv* env) {
2022 return RocksDBNativeClass::getJClass(env, "org/rocksdb/DirectSlice");
2023 }
2024
2025 /**
2026 * Constructs a DirectSlice object
2027 *
2028 * @param env A pointer to the Java environment
2029 *
2030 * @return A reference to a Java DirectSlice object, or a nullptr if an
2031 * exception occurs
2032 */
2033 static jobject construct0(JNIEnv* env) {
2034 jclass jclazz = getJClass(env);
2035 if(jclazz == nullptr) {
7c673cae
FG
2036 // exception occurred accessing class
2037 return nullptr;
2038 }
2039
11fdf7f2
TL
2040 static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
2041 if(mid == nullptr) {
7c673cae
FG
2042 // exception occurred accessing method
2043 return nullptr;
2044 }
2045
11fdf7f2
TL
2046 jobject jdirect_slice = env->NewObject(jclazz, mid);
2047 if(env->ExceptionCheck()) {
7c673cae
FG
2048 return nullptr;
2049 }
2050
11fdf7f2
TL
2051 return jdirect_slice;
2052 }
2053};
2054
2055// The portal class for java.util.List
2056class ListJni : public JavaClass {
2057 public:
2058 /**
2059 * Get the Java Class java.util.List
2060 *
2061 * @param env A pointer to the Java environment
2062 *
2063 * @return The Java Class or nullptr if one of the
2064 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2065 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2066 */
2067 static jclass getListClass(JNIEnv* env) {
2068 return JavaClass::getJClass(env, "java/util/List");
2069 }
2070
2071 /**
2072 * Get the Java Class java.util.ArrayList
2073 *
2074 * @param env A pointer to the Java environment
2075 *
2076 * @return The Java Class or nullptr if one of the
2077 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2078 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2079 */
2080 static jclass getArrayListClass(JNIEnv* env) {
2081 return JavaClass::getJClass(env, "java/util/ArrayList");
2082 }
2083
2084 /**
2085 * Get the Java Class java.util.Iterator
2086 *
2087 * @param env A pointer to the Java environment
2088 *
2089 * @return The Java Class or nullptr if one of the
2090 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2091 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2092 */
2093 static jclass getIteratorClass(JNIEnv* env) {
2094 return JavaClass::getJClass(env, "java/util/Iterator");
2095 }
2096
2097 /**
2098 * Get the Java Method: List#iterator
2099 *
2100 * @param env A pointer to the Java environment
2101 *
2102 * @return The Java Method ID or nullptr if the class or method id could not
2103 * be retieved
2104 */
2105 static jmethodID getIteratorMethod(JNIEnv* env) {
2106 jclass jlist_clazz = getListClass(env);
2107 if(jlist_clazz == nullptr) {
2108 // exception occurred accessing class
7c673cae
FG
2109 return nullptr;
2110 }
2111
11fdf7f2
TL
2112 static jmethodID mid =
2113 env->GetMethodID(jlist_clazz, "iterator", "()Ljava/util/Iterator;");
2114 assert(mid != nullptr);
2115 return mid;
2116 }
7c673cae 2117
11fdf7f2
TL
2118 /**
2119 * Get the Java Method: Iterator#hasNext
2120 *
2121 * @param env A pointer to the Java environment
2122 *
2123 * @return The Java Method ID or nullptr if the class or method id could not
2124 * be retieved
2125 */
2126 static jmethodID getHasNextMethod(JNIEnv* env) {
2127 jclass jiterator_clazz = getIteratorClass(env);
2128 if(jiterator_clazz == nullptr) {
2129 // exception occurred accessing class
2130 return nullptr;
2131 }
7c673cae 2132
11fdf7f2
TL
2133 static jmethodID mid = env->GetMethodID(jiterator_clazz, "hasNext", "()Z");
2134 assert(mid != nullptr);
2135 return mid;
2136 }
2137
2138 /**
2139 * Get the Java Method: Iterator#next
2140 *
2141 * @param env A pointer to the Java environment
2142 *
2143 * @return The Java Method ID or nullptr if the class or method id could not
2144 * be retieved
2145 */
2146 static jmethodID getNextMethod(JNIEnv* env) {
2147 jclass jiterator_clazz = getIteratorClass(env);
2148 if(jiterator_clazz == nullptr) {
2149 // exception occurred accessing class
2150 return nullptr;
7c673cae
FG
2151 }
2152
11fdf7f2
TL
2153 static jmethodID mid =
2154 env->GetMethodID(jiterator_clazz, "next", "()Ljava/lang/Object;");
2155 assert(mid != nullptr);
2156 return mid;
2157 }
2158
2159 /**
2160 * Get the Java Method: ArrayList constructor
2161 *
2162 * @param env A pointer to the Java environment
2163 *
2164 * @return The Java Method ID or nullptr if the class or method id could not
2165 * be retieved
2166 */
2167 static jmethodID getArrayListConstructorMethodId(JNIEnv* env) {
2168 jclass jarray_list_clazz = getArrayListClass(env);
2169 if(jarray_list_clazz == nullptr) {
2170 // exception occurred accessing class
2171 return nullptr;
2172 }
2173 static jmethodID mid =
2174 env->GetMethodID(jarray_list_clazz, "<init>", "(I)V");
2175 assert(mid != nullptr);
2176 return mid;
2177 }
2178
2179 /**
2180 * Get the Java Method: List#add
2181 *
2182 * @param env A pointer to the Java environment
2183 *
2184 * @return The Java Method ID or nullptr if the class or method id could not
2185 * be retieved
2186 */
2187 static jmethodID getListAddMethodId(JNIEnv* env) {
2188 jclass jlist_clazz = getListClass(env);
2189 if(jlist_clazz == nullptr) {
2190 // exception occurred accessing class
2191 return nullptr;
2192 }
2193
2194 static jmethodID mid =
2195 env->GetMethodID(jlist_clazz, "add", "(Ljava/lang/Object;)Z");
2196 assert(mid != nullptr);
2197 return mid;
7c673cae
FG
2198 }
2199};
2200
11fdf7f2
TL
2201// The portal class for java.lang.Byte
2202class ByteJni : public JavaClass {
7c673cae
FG
2203 public:
2204 /**
11fdf7f2 2205 * Get the Java Class java.lang.Byte
7c673cae
FG
2206 *
2207 * @param env A pointer to the Java environment
2208 *
2209 * @return The Java Class or nullptr if one of the
2210 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2211 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2212 */
2213 static jclass getJClass(JNIEnv* env) {
11fdf7f2 2214 return JavaClass::getJClass(env, "java/lang/Byte");
7c673cae
FG
2215 }
2216
2217 /**
11fdf7f2 2218 * Get the Java Class byte[]
7c673cae
FG
2219 *
2220 * @param env A pointer to the Java environment
2221 *
11fdf7f2
TL
2222 * @return The Java Class or nullptr if one of the
2223 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2224 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2225 */
2226 static jclass getArrayJClass(JNIEnv* env) {
2227 return JavaClass::getJClass(env, "[B");
2228 }
2229
2230 /**
2231 * Creates a new 2-dimensional Java Byte Array byte[][]
2232 *
2233 * @param env A pointer to the Java environment
2234 * @param len The size of the first dimension
2235 *
2236 * @return A reference to the Java byte[][] or nullptr if an exception occurs
2237 */
2238 static jobjectArray new2dByteArray(JNIEnv* env, const jsize len) {
2239 jclass clazz = getArrayJClass(env);
2240 if(clazz == nullptr) {
2241 // exception occurred accessing class
2242 return nullptr;
2243 }
2244
2245 return env->NewObjectArray(len, clazz, nullptr);
2246 }
2247
2248 /**
2249 * Get the Java Method: Byte#byteValue
2250 *
2251 * @param env A pointer to the Java environment
2252 *
2253 * @return The Java Method ID or nullptr if the class or method id could not
7c673cae
FG
2254 * be retieved
2255 */
11fdf7f2
TL
2256 static jmethodID getByteValueMethod(JNIEnv* env) {
2257 jclass clazz = getJClass(env);
2258 if(clazz == nullptr) {
7c673cae
FG
2259 // exception occurred accessing class
2260 return nullptr;
2261 }
2262
11fdf7f2
TL
2263 static jmethodID mid = env->GetMethodID(clazz, "byteValue", "()B");
2264 assert(mid != nullptr);
2265 return mid;
7c673cae 2266 }
11fdf7f2 2267};
7c673cae 2268
11fdf7f2
TL
2269// The portal class for java.lang.StringBuilder
2270class StringBuilderJni : public JavaClass {
2271 public:
7c673cae 2272 /**
11fdf7f2 2273 * Get the Java Class java.lang.StringBuilder
7c673cae 2274 *
11fdf7f2 2275 * @param env A pointer to the Java environment
7c673cae 2276 *
11fdf7f2
TL
2277 * @return The Java Class or nullptr if one of the
2278 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2279 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7c673cae 2280 */
11fdf7f2
TL
2281 static jclass getJClass(JNIEnv* env) {
2282 return JavaClass::getJClass(env, "java/lang/StringBuilder");
2283 }
7c673cae 2284
11fdf7f2
TL
2285 /**
2286 * Get the Java Method: StringBuilder#append
2287 *
2288 * @param env A pointer to the Java environment
2289 *
2290 * @return The Java Method ID or nullptr if the class or method id could not
2291 * be retieved
2292 */
2293 static jmethodID getListAddMethodId(JNIEnv* env) {
2294 jclass jclazz = getJClass(env);
2295 if(jclazz == nullptr) {
2296 // exception occurred accessing class
7c673cae
FG
2297 return nullptr;
2298 }
11fdf7f2
TL
2299
2300 static jmethodID mid =
2301 env->GetMethodID(jclazz, "append",
2302 "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
2303 assert(mid != nullptr);
2304 return mid;
2305 }
2306
2307 /**
2308 * Appends a C-style string to a StringBuilder
2309 *
2310 * @param env A pointer to the Java environment
2311 * @param jstring_builder Reference to a java.lang.StringBuilder
2312 * @param c_str A C-style string to append to the StringBuilder
2313 *
2314 * @return A reference to the updated StringBuilder, or a nullptr if
2315 * an exception occurs
2316 */
2317 static jobject append(JNIEnv* env, jobject jstring_builder,
2318 const char* c_str) {
2319 jmethodID mid = getListAddMethodId(env);
2320 if(mid == nullptr) {
2321 // exception occurred accessing class or method
2322 return nullptr;
2323 }
2324
2325 jstring new_value_str = env->NewStringUTF(c_str);
2326 if(new_value_str == nullptr) {
2327 // exception thrown: OutOfMemoryError
2328 return nullptr;
2329 }
2330
2331 jobject jresult_string_builder =
2332 env->CallObjectMethod(jstring_builder, mid, new_value_str);
2333 if(env->ExceptionCheck()) {
2334 // exception occurred
2335 env->DeleteLocalRef(new_value_str);
2336 return nullptr;
2337 }
2338
2339 return jresult_string_builder;
2340 }
2341};
2342
2343// The portal class for org.rocksdb.BackupInfo
2344class BackupInfoJni : public JavaClass {
2345 public:
2346 /**
2347 * Get the Java Class org.rocksdb.BackupInfo
2348 *
2349 * @param env A pointer to the Java environment
2350 *
2351 * @return The Java Class or nullptr if one of the
2352 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2353 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2354 */
2355 static jclass getJClass(JNIEnv* env) {
2356 return JavaClass::getJClass(env, "org/rocksdb/BackupInfo");
2357 }
2358
2359 /**
2360 * Constructs a BackupInfo object
2361 *
2362 * @param env A pointer to the Java environment
2363 * @param backup_id id of the backup
2364 * @param timestamp timestamp of the backup
2365 * @param size size of the backup
2366 * @param number_files number of files related to the backup
2367 * @param app_metadata application specific metadata
2368 *
2369 * @return A reference to a Java BackupInfo object, or a nullptr if an
2370 * exception occurs
2371 */
2372 static jobject construct0(JNIEnv* env, uint32_t backup_id, int64_t timestamp,
2373 uint64_t size, uint32_t number_files,
2374 const std::string& app_metadata) {
2375 jclass jclazz = getJClass(env);
2376 if(jclazz == nullptr) {
2377 // exception occurred accessing class
2378 return nullptr;
2379 }
2380
2381 static jmethodID mid =
2382 env->GetMethodID(jclazz, "<init>", "(IJJILjava/lang/String;)V");
2383 if(mid == nullptr) {
2384 // exception occurred accessing method
2385 return nullptr;
2386 }
2387
2388 jstring japp_metadata = nullptr;
2389 if (app_metadata != nullptr) {
2390 japp_metadata = env->NewStringUTF(app_metadata.c_str());
2391 if (japp_metadata == nullptr) {
2392 // exception occurred creating java string
2393 return nullptr;
2394 }
2395 }
2396
2397 jobject jbackup_info = env->NewObject(jclazz, mid, backup_id, timestamp,
2398 size, number_files, japp_metadata);
2399 if(env->ExceptionCheck()) {
2400 env->DeleteLocalRef(japp_metadata);
2401 return nullptr;
2402 }
2403
2404 return jbackup_info;
2405 }
2406};
2407
2408class BackupInfoListJni {
2409 public:
2410 /**
2411 * Converts a C++ std::vector<BackupInfo> object to
2412 * a Java ArrayList<org.rocksdb.BackupInfo> object
2413 *
2414 * @param env A pointer to the Java environment
2415 * @param backup_infos A vector of BackupInfo
2416 *
2417 * @return Either a reference to a Java ArrayList object, or a nullptr
2418 * if an exception occurs
2419 */
2420 static jobject getBackupInfo(JNIEnv* env,
2421 std::vector<BackupInfo> backup_infos) {
2422 jclass jarray_list_clazz = rocksdb::ListJni::getArrayListClass(env);
2423 if(jarray_list_clazz == nullptr) {
2424 // exception occurred accessing class
2425 return nullptr;
2426 }
2427
2428 jmethodID cstr_mid = rocksdb::ListJni::getArrayListConstructorMethodId(env);
2429 if(cstr_mid == nullptr) {
2430 // exception occurred accessing method
2431 return nullptr;
2432 }
2433
2434 jmethodID add_mid = rocksdb::ListJni::getListAddMethodId(env);
2435 if(add_mid == nullptr) {
2436 // exception occurred accessing method
2437 return nullptr;
2438 }
2439
2440 // create java list
2441 jobject jbackup_info_handle_list =
2442 env->NewObject(jarray_list_clazz, cstr_mid, backup_infos.size());
2443 if(env->ExceptionCheck()) {
2444 // exception occurred constructing object
2445 return nullptr;
2446 }
2447
2448 // insert in java list
2449 auto end = backup_infos.end();
2450 for (auto it = backup_infos.begin(); it != end; ++it) {
2451 auto backup_info = *it;
2452
2453 jobject obj = rocksdb::BackupInfoJni::construct0(
2454 env, backup_info.backup_id, backup_info.timestamp, backup_info.size,
2455 backup_info.number_files, backup_info.app_metadata);
2456 if(env->ExceptionCheck()) {
2457 // exception occurred constructing object
2458 if(obj != nullptr) {
2459 env->DeleteLocalRef(obj);
2460 }
2461 if(jbackup_info_handle_list != nullptr) {
2462 env->DeleteLocalRef(jbackup_info_handle_list);
2463 }
2464 return nullptr;
2465 }
2466
2467 jboolean rs =
2468 env->CallBooleanMethod(jbackup_info_handle_list, add_mid, obj);
2469 if(env->ExceptionCheck() || rs == JNI_FALSE) {
2470 // exception occurred calling method, or could not add
2471 if(obj != nullptr) {
2472 env->DeleteLocalRef(obj);
2473 }
2474 if(jbackup_info_handle_list != nullptr) {
2475 env->DeleteLocalRef(jbackup_info_handle_list);
2476 }
2477 return nullptr;
2478 }
2479 }
2480
2481 return jbackup_info_handle_list;
2482 }
2483};
2484
2485// The portal class for org.rocksdb.WBWIRocksIterator
2486class WBWIRocksIteratorJni : public JavaClass {
2487 public:
2488 /**
2489 * Get the Java Class org.rocksdb.WBWIRocksIterator
2490 *
2491 * @param env A pointer to the Java environment
2492 *
2493 * @return The Java Class or nullptr if one of the
2494 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2495 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2496 */
2497 static jclass getJClass(JNIEnv* env) {
2498 return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator");
2499 }
2500
2501 /**
2502 * Get the Java Field: WBWIRocksIterator#entry
2503 *
2504 * @param env A pointer to the Java environment
2505 *
2506 * @return The Java Field ID or nullptr if the class or field id could not
2507 * be retieved
2508 */
2509 static jfieldID getWriteEntryField(JNIEnv* env) {
2510 jclass jclazz = getJClass(env);
2511 if(jclazz == nullptr) {
2512 // exception occurred accessing class
2513 return nullptr;
2514 }
2515
2516 static jfieldID fid =
2517 env->GetFieldID(jclazz, "entry",
2518 "Lorg/rocksdb/WBWIRocksIterator$WriteEntry;");
2519 assert(fid != nullptr);
2520 return fid;
2521 }
2522
2523 /**
2524 * Gets the value of the WBWIRocksIterator#entry
2525 *
2526 * @param env A pointer to the Java environment
2527 * @param jwbwi_rocks_iterator A reference to a WBWIIterator
2528 *
2529 * @return A reference to a Java WBWIRocksIterator.WriteEntry object, or
2530 * a nullptr if an exception occurs
2531 */
2532 static jobject getWriteEntry(JNIEnv* env, jobject jwbwi_rocks_iterator) {
2533 assert(jwbwi_rocks_iterator != nullptr);
2534
2535 jfieldID jwrite_entry_field = getWriteEntryField(env);
2536 if(jwrite_entry_field == nullptr) {
2537 // exception occurred accessing the field
2538 return nullptr;
2539 }
2540
2541 jobject jwe = env->GetObjectField(jwbwi_rocks_iterator, jwrite_entry_field);
2542 assert(jwe != nullptr);
2543 return jwe;
2544 }
2545};
2546
2547// The portal class for org.rocksdb.WBWIRocksIterator.WriteType
2548class WriteTypeJni : public JavaClass {
2549 public:
2550 /**
2551 * Get the PUT enum field value of WBWIRocksIterator.WriteType
2552 *
2553 * @param env A pointer to the Java environment
2554 *
2555 * @return A reference to the enum field value or a nullptr if
2556 * the enum field value could not be retrieved
2557 */
2558 static jobject PUT(JNIEnv* env) {
2559 return getEnum(env, "PUT");
2560 }
2561
2562 /**
2563 * Get the MERGE enum field value of WBWIRocksIterator.WriteType
2564 *
2565 * @param env A pointer to the Java environment
2566 *
2567 * @return A reference to the enum field value or a nullptr if
2568 * the enum field value could not be retrieved
2569 */
2570 static jobject MERGE(JNIEnv* env) {
2571 return getEnum(env, "MERGE");
2572 }
2573
2574 /**
2575 * Get the DELETE enum field value of WBWIRocksIterator.WriteType
2576 *
2577 * @param env A pointer to the Java environment
2578 *
2579 * @return A reference to the enum field value or a nullptr if
2580 * the enum field value could not be retrieved
2581 */
2582 static jobject DELETE(JNIEnv* env) {
2583 return getEnum(env, "DELETE");
2584 }
2585
2586 /**
2587 * Get the LOG enum field value of WBWIRocksIterator.WriteType
2588 *
2589 * @param env A pointer to the Java environment
2590 *
2591 * @return A reference to the enum field value or a nullptr if
2592 * the enum field value could not be retrieved
2593 */
2594 static jobject LOG(JNIEnv* env) {
2595 return getEnum(env, "LOG");
2596 }
2597
2598 // Returns the equivalent org.rocksdb.WBWIRocksIterator.WriteType for the
2599 // provided C++ rocksdb::WriteType enum
2600 static jbyte toJavaWriteType(const rocksdb::WriteType& writeType) {
2601 switch (writeType) {
2602 case rocksdb::WriteType::kPutRecord:
2603 return 0x0;
2604 case rocksdb::WriteType::kMergeRecord:
2605 return 0x1;
2606 case rocksdb::WriteType::kDeleteRecord:
2607 return 0x2;
2608 case rocksdb::WriteType::kSingleDeleteRecord:
2609 return 0x3;
2610 case rocksdb::WriteType::kDeleteRangeRecord:
2611 return 0x4;
2612 case rocksdb::WriteType::kLogDataRecord:
2613 return 0x5;
2614 case rocksdb::WriteType::kXIDRecord:
2615 return 0x6;
2616 default:
2617 return 0x7F; // undefined
2618 }
2619 }
2620
2621 private:
2622 /**
2623 * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteType
2624 *
2625 * @param env A pointer to the Java environment
2626 *
2627 * @return The Java Class or nullptr if one of the
2628 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2629 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2630 */
2631 static jclass getJClass(JNIEnv* env) {
2632 return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteType");
2633 }
2634
2635 /**
2636 * Get an enum field of org.rocksdb.WBWIRocksIterator.WriteType
2637 *
2638 * @param env A pointer to the Java environment
2639 * @param name The name of the enum field
2640 *
2641 * @return A reference to the enum field value or a nullptr if
2642 * the enum field value could not be retrieved
2643 */
2644 static jobject getEnum(JNIEnv* env, const char name[]) {
2645 jclass jclazz = getJClass(env);
2646 if(jclazz == nullptr) {
2647 // exception occurred accessing class
2648 return nullptr;
2649 }
2650
2651 jfieldID jfid =
2652 env->GetStaticFieldID(jclazz, name,
2653 "Lorg/rocksdb/WBWIRocksIterator$WriteType;");
2654 if(env->ExceptionCheck()) {
2655 // exception occurred while getting field
2656 return nullptr;
2657 } else if(jfid == nullptr) {
2658 return nullptr;
2659 }
2660
2661 jobject jwrite_type = env->GetStaticObjectField(jclazz, jfid);
2662 assert(jwrite_type != nullptr);
2663 return jwrite_type;
2664 }
2665};
2666
2667// The portal class for org.rocksdb.WBWIRocksIterator.WriteEntry
2668class WriteEntryJni : public JavaClass {
2669 public:
2670 /**
2671 * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteEntry
2672 *
2673 * @param env A pointer to the Java environment
2674 *
2675 * @return The Java Class or nullptr if one of the
2676 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2677 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2678 */
2679 static jclass getJClass(JNIEnv* env) {
2680 return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteEntry");
2681 }
2682};
2683
2684// The portal class for org.rocksdb.InfoLogLevel
2685class InfoLogLevelJni : public JavaClass {
2686 public:
2687 /**
2688 * Get the DEBUG_LEVEL enum field value of InfoLogLevel
2689 *
2690 * @param env A pointer to the Java environment
2691 *
2692 * @return A reference to the enum field value or a nullptr if
2693 * the enum field value could not be retrieved
2694 */
2695 static jobject DEBUG_LEVEL(JNIEnv* env) {
2696 return getEnum(env, "DEBUG_LEVEL");
2697 }
2698
2699 /**
2700 * Get the INFO_LEVEL enum field value of InfoLogLevel
2701 *
2702 * @param env A pointer to the Java environment
2703 *
2704 * @return A reference to the enum field value or a nullptr if
2705 * the enum field value could not be retrieved
2706 */
2707 static jobject INFO_LEVEL(JNIEnv* env) {
2708 return getEnum(env, "INFO_LEVEL");
2709 }
2710
2711 /**
2712 * Get the WARN_LEVEL enum field value of InfoLogLevel
2713 *
2714 * @param env A pointer to the Java environment
2715 *
2716 * @return A reference to the enum field value or a nullptr if
2717 * the enum field value could not be retrieved
2718 */
2719 static jobject WARN_LEVEL(JNIEnv* env) {
2720 return getEnum(env, "WARN_LEVEL");
2721 }
2722
2723 /**
2724 * Get the ERROR_LEVEL enum field value of InfoLogLevel
2725 *
2726 * @param env A pointer to the Java environment
2727 *
2728 * @return A reference to the enum field value or a nullptr if
2729 * the enum field value could not be retrieved
2730 */
2731 static jobject ERROR_LEVEL(JNIEnv* env) {
2732 return getEnum(env, "ERROR_LEVEL");
2733 }
2734
2735 /**
2736 * Get the FATAL_LEVEL enum field value of InfoLogLevel
2737 *
2738 * @param env A pointer to the Java environment
2739 *
2740 * @return A reference to the enum field value or a nullptr if
2741 * the enum field value could not be retrieved
2742 */
2743 static jobject FATAL_LEVEL(JNIEnv* env) {
2744 return getEnum(env, "FATAL_LEVEL");
2745 }
2746
2747 /**
2748 * Get the HEADER_LEVEL enum field value of InfoLogLevel
2749 *
2750 * @param env A pointer to the Java environment
2751 *
2752 * @return A reference to the enum field value or a nullptr if
2753 * the enum field value could not be retrieved
2754 */
2755 static jobject HEADER_LEVEL(JNIEnv* env) {
2756 return getEnum(env, "HEADER_LEVEL");
2757 }
2758
2759 private:
2760 /**
2761 * Get the Java Class org.rocksdb.InfoLogLevel
2762 *
2763 * @param env A pointer to the Java environment
2764 *
2765 * @return The Java Class or nullptr if one of the
2766 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2767 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2768 */
2769 static jclass getJClass(JNIEnv* env) {
2770 return JavaClass::getJClass(env, "org/rocksdb/InfoLogLevel");
2771 }
2772
2773 /**
2774 * Get an enum field of org.rocksdb.InfoLogLevel
2775 *
2776 * @param env A pointer to the Java environment
2777 * @param name The name of the enum field
2778 *
2779 * @return A reference to the enum field value or a nullptr if
2780 * the enum field value could not be retrieved
2781 */
2782 static jobject getEnum(JNIEnv* env, const char name[]) {
2783 jclass jclazz = getJClass(env);
2784 if(jclazz == nullptr) {
2785 // exception occurred accessing class
2786 return nullptr;
2787 }
2788
2789 jfieldID jfid =
2790 env->GetStaticFieldID(jclazz, name, "Lorg/rocksdb/InfoLogLevel;");
2791 if(env->ExceptionCheck()) {
2792 // exception occurred while getting field
2793 return nullptr;
2794 } else if(jfid == nullptr) {
2795 return nullptr;
2796 }
2797
2798 jobject jinfo_log_level = env->GetStaticObjectField(jclazz, jfid);
2799 assert(jinfo_log_level != nullptr);
2800 return jinfo_log_level;
2801 }
2802};
2803
2804// The portal class for org.rocksdb.Logger
2805class LoggerJni : public RocksDBNativeClass<
2806 std::shared_ptr<rocksdb::LoggerJniCallback>*, LoggerJni> {
2807 public:
2808 /**
2809 * Get the Java Class org/rocksdb/Logger
2810 *
2811 * @param env A pointer to the Java environment
2812 *
2813 * @return The Java Class or nullptr if one of the
2814 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2815 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2816 */
2817 static jclass getJClass(JNIEnv* env) {
2818 return RocksDBNativeClass::getJClass(env, "org/rocksdb/Logger");
2819 }
2820
2821 /**
2822 * Get the Java Method: Logger#log
2823 *
2824 * @param env A pointer to the Java environment
2825 *
2826 * @return The Java Method ID or nullptr if the class or method id could not
2827 * be retieved
2828 */
2829 static jmethodID getLogMethodId(JNIEnv* env) {
2830 jclass jclazz = getJClass(env);
2831 if(jclazz == nullptr) {
2832 // exception occurred accessing class
2833 return nullptr;
2834 }
2835
2836 static jmethodID mid =
2837 env->GetMethodID(jclazz, "log",
2838 "(Lorg/rocksdb/InfoLogLevel;Ljava/lang/String;)V");
2839 assert(mid != nullptr);
2840 return mid;
2841 }
2842};
2843
2844// The portal class for org.rocksdb.TransactionLogIterator.BatchResult
2845class BatchResultJni : public JavaClass {
2846 public:
2847 /**
2848 * Get the Java Class org.rocksdb.TransactionLogIterator.BatchResult
2849 *
2850 * @param env A pointer to the Java environment
2851 *
2852 * @return The Java Class or nullptr if one of the
2853 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2854 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2855 */
2856 static jclass getJClass(JNIEnv* env) {
2857 return JavaClass::getJClass(env,
2858 "org/rocksdb/TransactionLogIterator$BatchResult");
2859 }
2860
2861 /**
2862 * Create a new Java org.rocksdb.TransactionLogIterator.BatchResult object
2863 * with the same properties as the provided C++ rocksdb::BatchResult object
2864 *
2865 * @param env A pointer to the Java environment
2866 * @param batch_result The rocksdb::BatchResult object
2867 *
2868 * @return A reference to a Java
2869 * org.rocksdb.TransactionLogIterator.BatchResult object,
2870 * or nullptr if an an exception occurs
2871 */
2872 static jobject construct(JNIEnv* env,
2873 rocksdb::BatchResult& batch_result) {
2874 jclass jclazz = getJClass(env);
2875 if(jclazz == nullptr) {
2876 // exception occurred accessing class
2877 return nullptr;
2878 }
2879
2880 jmethodID mid = env->GetMethodID(
2881 jclazz, "<init>", "(JJ)V");
2882 if(mid == nullptr) {
2883 // exception thrown: NoSuchMethodException or OutOfMemoryError
2884 return nullptr;
2885 }
2886
2887 jobject jbatch_result = env->NewObject(jclazz, mid,
2888 batch_result.sequence, batch_result.writeBatchPtr.get());
2889 if(jbatch_result == nullptr) {
2890 // exception thrown: InstantiationException or OutOfMemoryError
2891 return nullptr;
2892 }
2893
2894 batch_result.writeBatchPtr.release();
2895 return jbatch_result;
2896 }
2897};
2898
2899// The portal class for org.rocksdb.BottommostLevelCompaction
2900class BottommostLevelCompactionJni {
2901 public:
2902 // Returns the equivalent org.rocksdb.BottommostLevelCompaction for the provided
2903 // C++ rocksdb::BottommostLevelCompaction enum
2904 static jint toJavaBottommostLevelCompaction(
2905 const rocksdb::BottommostLevelCompaction& bottommost_level_compaction) {
2906 switch(bottommost_level_compaction) {
2907 case rocksdb::BottommostLevelCompaction::kSkip:
2908 return 0x0;
2909 case rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter:
2910 return 0x1;
2911 case rocksdb::BottommostLevelCompaction::kForce:
2912 return 0x2;
2913 default:
2914 return 0x7F; // undefined
2915 }
2916 }
2917
2918 // Returns the equivalent C++ rocksdb::BottommostLevelCompaction enum for the
2919 // provided Java org.rocksdb.BottommostLevelCompaction
2920 static rocksdb::BottommostLevelCompaction toCppBottommostLevelCompaction(
2921 jint bottommost_level_compaction) {
2922 switch(bottommost_level_compaction) {
2923 case 0x0:
2924 return rocksdb::BottommostLevelCompaction::kSkip;
2925 case 0x1:
2926 return rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter;
2927 case 0x2:
2928 return rocksdb::BottommostLevelCompaction::kForce;
2929 default:
2930 // undefined/default
2931 return rocksdb::BottommostLevelCompaction::kIfHaveCompactionFilter;
2932 }
2933 }
2934};
2935
2936// The portal class for org.rocksdb.CompactionStopStyle
2937class CompactionStopStyleJni {
2938 public:
2939 // Returns the equivalent org.rocksdb.CompactionStopStyle for the provided
2940 // C++ rocksdb::CompactionStopStyle enum
2941 static jbyte toJavaCompactionStopStyle(
2942 const rocksdb::CompactionStopStyle& compaction_stop_style) {
2943 switch(compaction_stop_style) {
2944 case rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize:
2945 return 0x0;
2946 case rocksdb::CompactionStopStyle::kCompactionStopStyleTotalSize:
2947 return 0x1;
2948 default:
2949 return 0x7F; // undefined
2950 }
2951 }
2952
2953 // Returns the equivalent C++ rocksdb::CompactionStopStyle enum for the
2954 // provided Java org.rocksdb.CompactionStopStyle
2955 static rocksdb::CompactionStopStyle toCppCompactionStopStyle(
2956 jbyte jcompaction_stop_style) {
2957 switch(jcompaction_stop_style) {
2958 case 0x0:
2959 return rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize;
2960 case 0x1:
2961 return rocksdb::CompactionStopStyle::kCompactionStopStyleTotalSize;
2962 default:
2963 // undefined/default
2964 return rocksdb::CompactionStopStyle::kCompactionStopStyleSimilarSize;
2965 }
2966 }
2967};
2968
2969// The portal class for org.rocksdb.CompressionType
2970class CompressionTypeJni {
2971 public:
2972 // Returns the equivalent org.rocksdb.CompressionType for the provided
2973 // C++ rocksdb::CompressionType enum
2974 static jbyte toJavaCompressionType(
2975 const rocksdb::CompressionType& compression_type) {
2976 switch(compression_type) {
2977 case rocksdb::CompressionType::kNoCompression:
2978 return 0x0;
2979 case rocksdb::CompressionType::kSnappyCompression:
2980 return 0x1;
2981 case rocksdb::CompressionType::kZlibCompression:
2982 return 0x2;
2983 case rocksdb::CompressionType::kBZip2Compression:
2984 return 0x3;
2985 case rocksdb::CompressionType::kLZ4Compression:
2986 return 0x4;
2987 case rocksdb::CompressionType::kLZ4HCCompression:
2988 return 0x5;
2989 case rocksdb::CompressionType::kXpressCompression:
2990 return 0x6;
2991 case rocksdb::CompressionType::kZSTD:
2992 return 0x7;
2993 case rocksdb::CompressionType::kDisableCompressionOption:
2994 default:
2995 return 0x7F;
2996 }
2997 }
2998
2999 // Returns the equivalent C++ rocksdb::CompressionType enum for the
3000 // provided Java org.rocksdb.CompressionType
3001 static rocksdb::CompressionType toCppCompressionType(
3002 jbyte jcompression_type) {
3003 switch(jcompression_type) {
3004 case 0x0:
3005 return rocksdb::CompressionType::kNoCompression;
3006 case 0x1:
3007 return rocksdb::CompressionType::kSnappyCompression;
3008 case 0x2:
3009 return rocksdb::CompressionType::kZlibCompression;
3010 case 0x3:
3011 return rocksdb::CompressionType::kBZip2Compression;
3012 case 0x4:
3013 return rocksdb::CompressionType::kLZ4Compression;
3014 case 0x5:
3015 return rocksdb::CompressionType::kLZ4HCCompression;
3016 case 0x6:
3017 return rocksdb::CompressionType::kXpressCompression;
3018 case 0x7:
3019 return rocksdb::CompressionType::kZSTD;
3020 case 0x7F:
3021 default:
3022 return rocksdb::CompressionType::kDisableCompressionOption;
3023 }
3024 }
3025};
3026
3027// The portal class for org.rocksdb.CompactionPriority
3028class CompactionPriorityJni {
3029 public:
3030 // Returns the equivalent org.rocksdb.CompactionPriority for the provided
3031 // C++ rocksdb::CompactionPri enum
3032 static jbyte toJavaCompactionPriority(
3033 const rocksdb::CompactionPri& compaction_priority) {
3034 switch(compaction_priority) {
3035 case rocksdb::CompactionPri::kByCompensatedSize:
3036 return 0x0;
3037 case rocksdb::CompactionPri::kOldestLargestSeqFirst:
3038 return 0x1;
3039 case rocksdb::CompactionPri::kOldestSmallestSeqFirst:
3040 return 0x2;
3041 case rocksdb::CompactionPri::kMinOverlappingRatio:
3042 return 0x3;
3043 default:
3044 return 0x0; // undefined
3045 }
3046 }
3047
3048 // Returns the equivalent C++ rocksdb::CompactionPri enum for the
3049 // provided Java org.rocksdb.CompactionPriority
3050 static rocksdb::CompactionPri toCppCompactionPriority(
3051 jbyte jcompaction_priority) {
3052 switch(jcompaction_priority) {
3053 case 0x0:
3054 return rocksdb::CompactionPri::kByCompensatedSize;
3055 case 0x1:
3056 return rocksdb::CompactionPri::kOldestLargestSeqFirst;
3057 case 0x2:
3058 return rocksdb::CompactionPri::kOldestSmallestSeqFirst;
3059 case 0x3:
3060 return rocksdb::CompactionPri::kMinOverlappingRatio;
3061 default:
3062 // undefined/default
3063 return rocksdb::CompactionPri::kByCompensatedSize;
3064 }
3065 }
3066};
3067
3068// The portal class for org.rocksdb.AccessHint
3069class AccessHintJni {
3070 public:
3071 // Returns the equivalent org.rocksdb.AccessHint for the provided
3072 // C++ rocksdb::DBOptions::AccessHint enum
3073 static jbyte toJavaAccessHint(
3074 const rocksdb::DBOptions::AccessHint& access_hint) {
3075 switch(access_hint) {
3076 case rocksdb::DBOptions::AccessHint::NONE:
3077 return 0x0;
3078 case rocksdb::DBOptions::AccessHint::NORMAL:
3079 return 0x1;
3080 case rocksdb::DBOptions::AccessHint::SEQUENTIAL:
3081 return 0x2;
3082 case rocksdb::DBOptions::AccessHint::WILLNEED:
3083 return 0x3;
3084 default:
3085 // undefined/default
3086 return 0x1;
3087 }
3088 }
3089
3090 // Returns the equivalent C++ rocksdb::DBOptions::AccessHint enum for the
3091 // provided Java org.rocksdb.AccessHint
3092 static rocksdb::DBOptions::AccessHint toCppAccessHint(jbyte jaccess_hint) {
3093 switch(jaccess_hint) {
3094 case 0x0:
3095 return rocksdb::DBOptions::AccessHint::NONE;
3096 case 0x1:
3097 return rocksdb::DBOptions::AccessHint::NORMAL;
3098 case 0x2:
3099 return rocksdb::DBOptions::AccessHint::SEQUENTIAL;
3100 case 0x3:
3101 return rocksdb::DBOptions::AccessHint::WILLNEED;
3102 default:
3103 // undefined/default
3104 return rocksdb::DBOptions::AccessHint::NORMAL;
3105 }
3106 }
3107};
3108
3109// The portal class for org.rocksdb.WALRecoveryMode
3110class WALRecoveryModeJni {
3111 public:
3112 // Returns the equivalent org.rocksdb.WALRecoveryMode for the provided
3113 // C++ rocksdb::WALRecoveryMode enum
3114 static jbyte toJavaWALRecoveryMode(
3115 const rocksdb::WALRecoveryMode& wal_recovery_mode) {
3116 switch(wal_recovery_mode) {
3117 case rocksdb::WALRecoveryMode::kTolerateCorruptedTailRecords:
3118 return 0x0;
3119 case rocksdb::WALRecoveryMode::kAbsoluteConsistency:
3120 return 0x1;
3121 case rocksdb::WALRecoveryMode::kPointInTimeRecovery:
3122 return 0x2;
3123 case rocksdb::WALRecoveryMode::kSkipAnyCorruptedRecords:
3124 return 0x3;
3125 default:
3126 // undefined/default
3127 return 0x2;
3128 }
3129 }
3130
3131 // Returns the equivalent C++ rocksdb::WALRecoveryMode enum for the
3132 // provided Java org.rocksdb.WALRecoveryMode
3133 static rocksdb::WALRecoveryMode toCppWALRecoveryMode(jbyte jwal_recovery_mode) {
3134 switch(jwal_recovery_mode) {
3135 case 0x0:
3136 return rocksdb::WALRecoveryMode::kTolerateCorruptedTailRecords;
3137 case 0x1:
3138 return rocksdb::WALRecoveryMode::kAbsoluteConsistency;
3139 case 0x2:
3140 return rocksdb::WALRecoveryMode::kPointInTimeRecovery;
3141 case 0x3:
3142 return rocksdb::WALRecoveryMode::kSkipAnyCorruptedRecords;
3143 default:
3144 // undefined/default
3145 return rocksdb::WALRecoveryMode::kPointInTimeRecovery;
3146 }
3147 }
3148};
3149
3150// The portal class for org.rocksdb.TickerType
3151class TickerTypeJni {
3152 public:
3153 // Returns the equivalent org.rocksdb.TickerType for the provided
3154 // C++ rocksdb::Tickers enum
3155 static jbyte toJavaTickerType(
3156 const rocksdb::Tickers& tickers) {
3157 switch(tickers) {
3158 case rocksdb::Tickers::BLOCK_CACHE_MISS:
3159 return 0x0;
3160 case rocksdb::Tickers::BLOCK_CACHE_HIT:
3161 return 0x1;
3162 case rocksdb::Tickers::BLOCK_CACHE_ADD:
3163 return 0x2;
3164 case rocksdb::Tickers::BLOCK_CACHE_ADD_FAILURES:
3165 return 0x3;
3166 case rocksdb::Tickers::BLOCK_CACHE_INDEX_MISS:
3167 return 0x4;
3168 case rocksdb::Tickers::BLOCK_CACHE_INDEX_HIT:
3169 return 0x5;
3170 case rocksdb::Tickers::BLOCK_CACHE_INDEX_ADD:
3171 return 0x6;
3172 case rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_INSERT:
3173 return 0x7;
3174 case rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_EVICT:
3175 return 0x8;
3176 case rocksdb::Tickers::BLOCK_CACHE_FILTER_MISS:
3177 return 0x9;
3178 case rocksdb::Tickers::BLOCK_CACHE_FILTER_HIT:
3179 return 0xA;
3180 case rocksdb::Tickers::BLOCK_CACHE_FILTER_ADD:
3181 return 0xB;
3182 case rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_INSERT:
3183 return 0xC;
3184 case rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_EVICT:
3185 return 0xD;
3186 case rocksdb::Tickers::BLOCK_CACHE_DATA_MISS:
3187 return 0xE;
3188 case rocksdb::Tickers::BLOCK_CACHE_DATA_HIT:
3189 return 0xF;
3190 case rocksdb::Tickers::BLOCK_CACHE_DATA_ADD:
3191 return 0x10;
3192 case rocksdb::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT:
3193 return 0x11;
3194 case rocksdb::Tickers::BLOCK_CACHE_BYTES_READ:
3195 return 0x12;
3196 case rocksdb::Tickers::BLOCK_CACHE_BYTES_WRITE:
3197 return 0x13;
3198 case rocksdb::Tickers::BLOOM_FILTER_USEFUL:
3199 return 0x14;
3200 case rocksdb::Tickers::PERSISTENT_CACHE_HIT:
3201 return 0x15;
3202 case rocksdb::Tickers::PERSISTENT_CACHE_MISS:
3203 return 0x16;
3204 case rocksdb::Tickers::SIM_BLOCK_CACHE_HIT:
3205 return 0x17;
3206 case rocksdb::Tickers::SIM_BLOCK_CACHE_MISS:
3207 return 0x18;
3208 case rocksdb::Tickers::MEMTABLE_HIT:
3209 return 0x19;
3210 case rocksdb::Tickers::MEMTABLE_MISS:
3211 return 0x1A;
3212 case rocksdb::Tickers::GET_HIT_L0:
3213 return 0x1B;
3214 case rocksdb::Tickers::GET_HIT_L1:
3215 return 0x1C;
3216 case rocksdb::Tickers::GET_HIT_L2_AND_UP:
3217 return 0x1D;
3218 case rocksdb::Tickers::COMPACTION_KEY_DROP_NEWER_ENTRY:
3219 return 0x1E;
3220 case rocksdb::Tickers::COMPACTION_KEY_DROP_OBSOLETE:
3221 return 0x1F;
3222 case rocksdb::Tickers::COMPACTION_KEY_DROP_RANGE_DEL:
3223 return 0x20;
3224 case rocksdb::Tickers::COMPACTION_KEY_DROP_USER:
3225 return 0x21;
3226 case rocksdb::Tickers::COMPACTION_RANGE_DEL_DROP_OBSOLETE:
3227 return 0x22;
3228 case rocksdb::Tickers::NUMBER_KEYS_WRITTEN:
3229 return 0x23;
3230 case rocksdb::Tickers::NUMBER_KEYS_READ:
3231 return 0x24;
3232 case rocksdb::Tickers::NUMBER_KEYS_UPDATED:
3233 return 0x25;
3234 case rocksdb::Tickers::BYTES_WRITTEN:
3235 return 0x26;
3236 case rocksdb::Tickers::BYTES_READ:
3237 return 0x27;
3238 case rocksdb::Tickers::NUMBER_DB_SEEK:
3239 return 0x28;
3240 case rocksdb::Tickers::NUMBER_DB_NEXT:
3241 return 0x29;
3242 case rocksdb::Tickers::NUMBER_DB_PREV:
3243 return 0x2A;
3244 case rocksdb::Tickers::NUMBER_DB_SEEK_FOUND:
3245 return 0x2B;
3246 case rocksdb::Tickers::NUMBER_DB_NEXT_FOUND:
3247 return 0x2C;
3248 case rocksdb::Tickers::NUMBER_DB_PREV_FOUND:
3249 return 0x2D;
3250 case rocksdb::Tickers::ITER_BYTES_READ:
3251 return 0x2E;
3252 case rocksdb::Tickers::NO_FILE_CLOSES:
3253 return 0x2F;
3254 case rocksdb::Tickers::NO_FILE_OPENS:
3255 return 0x30;
3256 case rocksdb::Tickers::NO_FILE_ERRORS:
3257 return 0x31;
3258 case rocksdb::Tickers::STALL_L0_SLOWDOWN_MICROS:
3259 return 0x32;
3260 case rocksdb::Tickers::STALL_MEMTABLE_COMPACTION_MICROS:
3261 return 0x33;
3262 case rocksdb::Tickers::STALL_L0_NUM_FILES_MICROS:
3263 return 0x34;
3264 case rocksdb::Tickers::STALL_MICROS:
3265 return 0x35;
3266 case rocksdb::Tickers::DB_MUTEX_WAIT_MICROS:
3267 return 0x36;
3268 case rocksdb::Tickers::RATE_LIMIT_DELAY_MILLIS:
3269 return 0x37;
3270 case rocksdb::Tickers::NO_ITERATORS:
3271 return 0x38;
3272 case rocksdb::Tickers::NUMBER_MULTIGET_CALLS:
3273 return 0x39;
3274 case rocksdb::Tickers::NUMBER_MULTIGET_KEYS_READ:
3275 return 0x3A;
3276 case rocksdb::Tickers::NUMBER_MULTIGET_BYTES_READ:
3277 return 0x3B;
3278 case rocksdb::Tickers::NUMBER_FILTERED_DELETES:
3279 return 0x3C;
3280 case rocksdb::Tickers::NUMBER_MERGE_FAILURES:
3281 return 0x3D;
3282 case rocksdb::Tickers::BLOOM_FILTER_PREFIX_CHECKED:
3283 return 0x3E;
3284 case rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL:
3285 return 0x3F;
3286 case rocksdb::Tickers::NUMBER_OF_RESEEKS_IN_ITERATION:
3287 return 0x40;
3288 case rocksdb::Tickers::GET_UPDATES_SINCE_CALLS:
3289 return 0x41;
3290 case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_MISS:
3291 return 0x42;
3292 case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_HIT:
3293 return 0x43;
3294 case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD:
3295 return 0x44;
3296 case rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD_FAILURES:
3297 return 0x45;
3298 case rocksdb::Tickers::WAL_FILE_SYNCED:
3299 return 0x46;
3300 case rocksdb::Tickers::WAL_FILE_BYTES:
3301 return 0x47;
3302 case rocksdb::Tickers::WRITE_DONE_BY_SELF:
3303 return 0x48;
3304 case rocksdb::Tickers::WRITE_DONE_BY_OTHER:
3305 return 0x49;
3306 case rocksdb::Tickers::WRITE_TIMEDOUT:
3307 return 0x4A;
3308 case rocksdb::Tickers::WRITE_WITH_WAL:
3309 return 0x4B;
3310 case rocksdb::Tickers::COMPACT_READ_BYTES:
3311 return 0x4C;
3312 case rocksdb::Tickers::COMPACT_WRITE_BYTES:
3313 return 0x4D;
3314 case rocksdb::Tickers::FLUSH_WRITE_BYTES:
3315 return 0x4E;
3316 case rocksdb::Tickers::NUMBER_DIRECT_LOAD_TABLE_PROPERTIES:
3317 return 0x4F;
3318 case rocksdb::Tickers::NUMBER_SUPERVERSION_ACQUIRES:
3319 return 0x50;
3320 case rocksdb::Tickers::NUMBER_SUPERVERSION_RELEASES:
3321 return 0x51;
3322 case rocksdb::Tickers::NUMBER_SUPERVERSION_CLEANUPS:
3323 return 0x52;
3324 case rocksdb::Tickers::NUMBER_BLOCK_COMPRESSED:
3325 return 0x53;
3326 case rocksdb::Tickers::NUMBER_BLOCK_DECOMPRESSED:
3327 return 0x54;
3328 case rocksdb::Tickers::NUMBER_BLOCK_NOT_COMPRESSED:
3329 return 0x55;
3330 case rocksdb::Tickers::MERGE_OPERATION_TOTAL_TIME:
3331 return 0x56;
3332 case rocksdb::Tickers::FILTER_OPERATION_TOTAL_TIME:
3333 return 0x57;
3334 case rocksdb::Tickers::ROW_CACHE_HIT:
3335 return 0x58;
3336 case rocksdb::Tickers::ROW_CACHE_MISS:
3337 return 0x59;
3338 case rocksdb::Tickers::READ_AMP_ESTIMATE_USEFUL_BYTES:
3339 return 0x5A;
3340 case rocksdb::Tickers::READ_AMP_TOTAL_READ_BYTES:
3341 return 0x5B;
3342 case rocksdb::Tickers::NUMBER_RATE_LIMITER_DRAINS:
3343 return 0x5C;
3344 case rocksdb::Tickers::NUMBER_ITER_SKIP:
3345 return 0x5D;
3346 case rocksdb::Tickers::NUMBER_MULTIGET_KEYS_FOUND:
3347 return 0x5E;
3348 case rocksdb::Tickers::TICKER_ENUM_MAX:
3349 return 0x5F;
3350
3351 default:
3352 // undefined/default
3353 return 0x0;
3354 }
3355 }
3356
3357 // Returns the equivalent C++ rocksdb::Tickers enum for the
3358 // provided Java org.rocksdb.TickerType
3359 static rocksdb::Tickers toCppTickers(jbyte jticker_type) {
3360 switch(jticker_type) {
3361 case 0x0:
3362 return rocksdb::Tickers::BLOCK_CACHE_MISS;
3363 case 0x1:
3364 return rocksdb::Tickers::BLOCK_CACHE_HIT;
3365 case 0x2:
3366 return rocksdb::Tickers::BLOCK_CACHE_ADD;
3367 case 0x3:
3368 return rocksdb::Tickers::BLOCK_CACHE_ADD_FAILURES;
3369 case 0x4:
3370 return rocksdb::Tickers::BLOCK_CACHE_INDEX_MISS;
3371 case 0x5:
3372 return rocksdb::Tickers::BLOCK_CACHE_INDEX_HIT;
3373 case 0x6:
3374 return rocksdb::Tickers::BLOCK_CACHE_INDEX_ADD;
3375 case 0x7:
3376 return rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_INSERT;
3377 case 0x8:
3378 return rocksdb::Tickers::BLOCK_CACHE_INDEX_BYTES_EVICT;
3379 case 0x9:
3380 return rocksdb::Tickers::BLOCK_CACHE_FILTER_MISS;
3381 case 0xA:
3382 return rocksdb::Tickers::BLOCK_CACHE_FILTER_HIT;
3383 case 0xB:
3384 return rocksdb::Tickers::BLOCK_CACHE_FILTER_ADD;
3385 case 0xC:
3386 return rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_INSERT;
3387 case 0xD:
3388 return rocksdb::Tickers::BLOCK_CACHE_FILTER_BYTES_EVICT;
3389 case 0xE:
3390 return rocksdb::Tickers::BLOCK_CACHE_DATA_MISS;
3391 case 0xF:
3392 return rocksdb::Tickers::BLOCK_CACHE_DATA_HIT;
3393 case 0x10:
3394 return rocksdb::Tickers::BLOCK_CACHE_DATA_ADD;
3395 case 0x11:
3396 return rocksdb::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT;
3397 case 0x12:
3398 return rocksdb::Tickers::BLOCK_CACHE_BYTES_READ;
3399 case 0x13:
3400 return rocksdb::Tickers::BLOCK_CACHE_BYTES_WRITE;
3401 case 0x14:
3402 return rocksdb::Tickers::BLOOM_FILTER_USEFUL;
3403 case 0x15:
3404 return rocksdb::Tickers::PERSISTENT_CACHE_HIT;
3405 case 0x16:
3406 return rocksdb::Tickers::PERSISTENT_CACHE_MISS;
3407 case 0x17:
3408 return rocksdb::Tickers::SIM_BLOCK_CACHE_HIT;
3409 case 0x18:
3410 return rocksdb::Tickers::SIM_BLOCK_CACHE_MISS;
3411 case 0x19:
3412 return rocksdb::Tickers::MEMTABLE_HIT;
3413 case 0x1A:
3414 return rocksdb::Tickers::MEMTABLE_MISS;
3415 case 0x1B:
3416 return rocksdb::Tickers::GET_HIT_L0;
3417 case 0x1C:
3418 return rocksdb::Tickers::GET_HIT_L1;
3419 case 0x1D:
3420 return rocksdb::Tickers::GET_HIT_L2_AND_UP;
3421 case 0x1E:
3422 return rocksdb::Tickers::COMPACTION_KEY_DROP_NEWER_ENTRY;
3423 case 0x1F:
3424 return rocksdb::Tickers::COMPACTION_KEY_DROP_OBSOLETE;
3425 case 0x20:
3426 return rocksdb::Tickers::COMPACTION_KEY_DROP_RANGE_DEL;
3427 case 0x21:
3428 return rocksdb::Tickers::COMPACTION_KEY_DROP_USER;
3429 case 0x22:
3430 return rocksdb::Tickers::COMPACTION_RANGE_DEL_DROP_OBSOLETE;
3431 case 0x23:
3432 return rocksdb::Tickers::NUMBER_KEYS_WRITTEN;
3433 case 0x24:
3434 return rocksdb::Tickers::NUMBER_KEYS_READ;
3435 case 0x25:
3436 return rocksdb::Tickers::NUMBER_KEYS_UPDATED;
3437 case 0x26:
3438 return rocksdb::Tickers::BYTES_WRITTEN;
3439 case 0x27:
3440 return rocksdb::Tickers::BYTES_READ;
3441 case 0x28:
3442 return rocksdb::Tickers::NUMBER_DB_SEEK;
3443 case 0x29:
3444 return rocksdb::Tickers::NUMBER_DB_NEXT;
3445 case 0x2A:
3446 return rocksdb::Tickers::NUMBER_DB_PREV;
3447 case 0x2B:
3448 return rocksdb::Tickers::NUMBER_DB_SEEK_FOUND;
3449 case 0x2C:
3450 return rocksdb::Tickers::NUMBER_DB_NEXT_FOUND;
3451 case 0x2D:
3452 return rocksdb::Tickers::NUMBER_DB_PREV_FOUND;
3453 case 0x2E:
3454 return rocksdb::Tickers::ITER_BYTES_READ;
3455 case 0x2F:
3456 return rocksdb::Tickers::NO_FILE_CLOSES;
3457 case 0x30:
3458 return rocksdb::Tickers::NO_FILE_OPENS;
3459 case 0x31:
3460 return rocksdb::Tickers::NO_FILE_ERRORS;
3461 case 0x32:
3462 return rocksdb::Tickers::STALL_L0_SLOWDOWN_MICROS;
3463 case 0x33:
3464 return rocksdb::Tickers::STALL_MEMTABLE_COMPACTION_MICROS;
3465 case 0x34:
3466 return rocksdb::Tickers::STALL_L0_NUM_FILES_MICROS;
3467 case 0x35:
3468 return rocksdb::Tickers::STALL_MICROS;
3469 case 0x36:
3470 return rocksdb::Tickers::DB_MUTEX_WAIT_MICROS;
3471 case 0x37:
3472 return rocksdb::Tickers::RATE_LIMIT_DELAY_MILLIS;
3473 case 0x38:
3474 return rocksdb::Tickers::NO_ITERATORS;
3475 case 0x39:
3476 return rocksdb::Tickers::NUMBER_MULTIGET_CALLS;
3477 case 0x3A:
3478 return rocksdb::Tickers::NUMBER_MULTIGET_KEYS_READ;
3479 case 0x3B:
3480 return rocksdb::Tickers::NUMBER_MULTIGET_BYTES_READ;
3481 case 0x3C:
3482 return rocksdb::Tickers::NUMBER_FILTERED_DELETES;
3483 case 0x3D:
3484 return rocksdb::Tickers::NUMBER_MERGE_FAILURES;
3485 case 0x3E:
3486 return rocksdb::Tickers::BLOOM_FILTER_PREFIX_CHECKED;
3487 case 0x3F:
3488 return rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL;
3489 case 0x40:
3490 return rocksdb::Tickers::NUMBER_OF_RESEEKS_IN_ITERATION;
3491 case 0x41:
3492 return rocksdb::Tickers::GET_UPDATES_SINCE_CALLS;
3493 case 0x42:
3494 return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_MISS;
3495 case 0x43:
3496 return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_HIT;
3497 case 0x44:
3498 return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD;
3499 case 0x45:
3500 return rocksdb::Tickers::BLOCK_CACHE_COMPRESSED_ADD_FAILURES;
3501 case 0x46:
3502 return rocksdb::Tickers::WAL_FILE_SYNCED;
3503 case 0x47:
3504 return rocksdb::Tickers::WAL_FILE_BYTES;
3505 case 0x48:
3506 return rocksdb::Tickers::WRITE_DONE_BY_SELF;
3507 case 0x49:
3508 return rocksdb::Tickers::WRITE_DONE_BY_OTHER;
3509 case 0x4A:
3510 return rocksdb::Tickers::WRITE_TIMEDOUT;
3511 case 0x4B:
3512 return rocksdb::Tickers::WRITE_WITH_WAL;
3513 case 0x4C:
3514 return rocksdb::Tickers::COMPACT_READ_BYTES;
3515 case 0x4D:
3516 return rocksdb::Tickers::COMPACT_WRITE_BYTES;
3517 case 0x4E:
3518 return rocksdb::Tickers::FLUSH_WRITE_BYTES;
3519 case 0x4F:
3520 return rocksdb::Tickers::NUMBER_DIRECT_LOAD_TABLE_PROPERTIES;
3521 case 0x50:
3522 return rocksdb::Tickers::NUMBER_SUPERVERSION_ACQUIRES;
3523 case 0x51:
3524 return rocksdb::Tickers::NUMBER_SUPERVERSION_RELEASES;
3525 case 0x52:
3526 return rocksdb::Tickers::NUMBER_SUPERVERSION_CLEANUPS;
3527 case 0x53:
3528 return rocksdb::Tickers::NUMBER_BLOCK_COMPRESSED;
3529 case 0x54:
3530 return rocksdb::Tickers::NUMBER_BLOCK_DECOMPRESSED;
3531 case 0x55:
3532 return rocksdb::Tickers::NUMBER_BLOCK_NOT_COMPRESSED;
3533 case 0x56:
3534 return rocksdb::Tickers::MERGE_OPERATION_TOTAL_TIME;
3535 case 0x57:
3536 return rocksdb::Tickers::FILTER_OPERATION_TOTAL_TIME;
3537 case 0x58:
3538 return rocksdb::Tickers::ROW_CACHE_HIT;
3539 case 0x59:
3540 return rocksdb::Tickers::ROW_CACHE_MISS;
3541 case 0x5A:
3542 return rocksdb::Tickers::READ_AMP_ESTIMATE_USEFUL_BYTES;
3543 case 0x5B:
3544 return rocksdb::Tickers::READ_AMP_TOTAL_READ_BYTES;
3545 case 0x5C:
3546 return rocksdb::Tickers::NUMBER_RATE_LIMITER_DRAINS;
3547 case 0x5D:
3548 return rocksdb::Tickers::NUMBER_ITER_SKIP;
3549 case 0x5E:
3550 return rocksdb::Tickers::NUMBER_MULTIGET_KEYS_FOUND;
3551 case 0x5F:
3552 return rocksdb::Tickers::TICKER_ENUM_MAX;
3553
3554 default:
3555 // undefined/default
3556 return rocksdb::Tickers::BLOCK_CACHE_MISS;
3557 }
3558 }
3559};
3560
3561// The portal class for org.rocksdb.HistogramType
3562class HistogramTypeJni {
3563 public:
3564 // Returns the equivalent org.rocksdb.HistogramType for the provided
3565 // C++ rocksdb::Histograms enum
3566 static jbyte toJavaHistogramsType(
3567 const rocksdb::Histograms& histograms) {
3568 switch(histograms) {
3569 case rocksdb::Histograms::DB_GET:
3570 return 0x0;
3571 case rocksdb::Histograms::DB_WRITE:
3572 return 0x1;
3573 case rocksdb::Histograms::COMPACTION_TIME:
3574 return 0x2;
3575 case rocksdb::Histograms::SUBCOMPACTION_SETUP_TIME:
3576 return 0x3;
3577 case rocksdb::Histograms::TABLE_SYNC_MICROS:
3578 return 0x4;
3579 case rocksdb::Histograms::COMPACTION_OUTFILE_SYNC_MICROS:
3580 return 0x5;
3581 case rocksdb::Histograms::WAL_FILE_SYNC_MICROS:
3582 return 0x6;
3583 case rocksdb::Histograms::MANIFEST_FILE_SYNC_MICROS:
3584 return 0x7;
3585 case rocksdb::Histograms::TABLE_OPEN_IO_MICROS:
3586 return 0x8;
3587 case rocksdb::Histograms::DB_MULTIGET:
3588 return 0x9;
3589 case rocksdb::Histograms::READ_BLOCK_COMPACTION_MICROS:
3590 return 0xA;
3591 case rocksdb::Histograms::READ_BLOCK_GET_MICROS:
3592 return 0xB;
3593 case rocksdb::Histograms::WRITE_RAW_BLOCK_MICROS:
3594 return 0xC;
3595 case rocksdb::Histograms::STALL_L0_SLOWDOWN_COUNT:
3596 return 0xD;
3597 case rocksdb::Histograms::STALL_MEMTABLE_COMPACTION_COUNT:
3598 return 0xE;
3599 case rocksdb::Histograms::STALL_L0_NUM_FILES_COUNT:
3600 return 0xF;
3601 case rocksdb::Histograms::HARD_RATE_LIMIT_DELAY_COUNT:
3602 return 0x10;
3603 case rocksdb::Histograms::SOFT_RATE_LIMIT_DELAY_COUNT:
3604 return 0x11;
3605 case rocksdb::Histograms::NUM_FILES_IN_SINGLE_COMPACTION:
3606 return 0x12;
3607 case rocksdb::Histograms::DB_SEEK:
3608 return 0x13;
3609 case rocksdb::Histograms::WRITE_STALL:
3610 return 0x14;
3611 case rocksdb::Histograms::SST_READ_MICROS:
3612 return 0x15;
3613 case rocksdb::Histograms::NUM_SUBCOMPACTIONS_SCHEDULED:
3614 return 0x16;
3615 case rocksdb::Histograms::BYTES_PER_READ:
3616 return 0x17;
3617 case rocksdb::Histograms::BYTES_PER_WRITE:
3618 return 0x18;
3619 case rocksdb::Histograms::BYTES_PER_MULTIGET:
3620 return 0x19;
3621 case rocksdb::Histograms::BYTES_COMPRESSED:
3622 return 0x1A;
3623 case rocksdb::Histograms::BYTES_DECOMPRESSED:
3624 return 0x1B;
3625 case rocksdb::Histograms::COMPRESSION_TIMES_NANOS:
3626 return 0x1C;
3627 case rocksdb::Histograms::DECOMPRESSION_TIMES_NANOS:
3628 return 0x1D;
3629 case rocksdb::Histograms::READ_NUM_MERGE_OPERANDS:
3630 return 0x1E;
3631 case rocksdb::Histograms::FLUSH_TIME:
3632 return 0x1F;
3633 case rocksdb::Histograms::HISTOGRAM_ENUM_MAX:
3634 return 0x20;
3635
3636 default:
3637 // undefined/default
3638 return 0x0;
3639 }
3640 }
3641
3642 // Returns the equivalent C++ rocksdb::Histograms enum for the
3643 // provided Java org.rocksdb.HistogramsType
3644 static rocksdb::Histograms toCppHistograms(jbyte jhistograms_type) {
3645 switch(jhistograms_type) {
3646 case 0x0:
3647 return rocksdb::Histograms::DB_GET;
3648 case 0x1:
3649 return rocksdb::Histograms::DB_WRITE;
3650 case 0x2:
3651 return rocksdb::Histograms::COMPACTION_TIME;
3652 case 0x3:
3653 return rocksdb::Histograms::SUBCOMPACTION_SETUP_TIME;
3654 case 0x4:
3655 return rocksdb::Histograms::TABLE_SYNC_MICROS;
3656 case 0x5:
3657 return rocksdb::Histograms::COMPACTION_OUTFILE_SYNC_MICROS;
3658 case 0x6:
3659 return rocksdb::Histograms::WAL_FILE_SYNC_MICROS;
3660 case 0x7:
3661 return rocksdb::Histograms::MANIFEST_FILE_SYNC_MICROS;
3662 case 0x8:
3663 return rocksdb::Histograms::TABLE_OPEN_IO_MICROS;
3664 case 0x9:
3665 return rocksdb::Histograms::DB_MULTIGET;
3666 case 0xA:
3667 return rocksdb::Histograms::READ_BLOCK_COMPACTION_MICROS;
3668 case 0xB:
3669 return rocksdb::Histograms::READ_BLOCK_GET_MICROS;
3670 case 0xC:
3671 return rocksdb::Histograms::WRITE_RAW_BLOCK_MICROS;
3672 case 0xD:
3673 return rocksdb::Histograms::STALL_L0_SLOWDOWN_COUNT;
3674 case 0xE:
3675 return rocksdb::Histograms::STALL_MEMTABLE_COMPACTION_COUNT;
3676 case 0xF:
3677 return rocksdb::Histograms::STALL_L0_NUM_FILES_COUNT;
3678 case 0x10:
3679 return rocksdb::Histograms::HARD_RATE_LIMIT_DELAY_COUNT;
3680 case 0x11:
3681 return rocksdb::Histograms::SOFT_RATE_LIMIT_DELAY_COUNT;
3682 case 0x12:
3683 return rocksdb::Histograms::NUM_FILES_IN_SINGLE_COMPACTION;
3684 case 0x13:
3685 return rocksdb::Histograms::DB_SEEK;
3686 case 0x14:
3687 return rocksdb::Histograms::WRITE_STALL;
3688 case 0x15:
3689 return rocksdb::Histograms::SST_READ_MICROS;
3690 case 0x16:
3691 return rocksdb::Histograms::NUM_SUBCOMPACTIONS_SCHEDULED;
3692 case 0x17:
3693 return rocksdb::Histograms::BYTES_PER_READ;
3694 case 0x18:
3695 return rocksdb::Histograms::BYTES_PER_WRITE;
3696 case 0x19:
3697 return rocksdb::Histograms::BYTES_PER_MULTIGET;
3698 case 0x1A:
3699 return rocksdb::Histograms::BYTES_COMPRESSED;
3700 case 0x1B:
3701 return rocksdb::Histograms::BYTES_DECOMPRESSED;
3702 case 0x1C:
3703 return rocksdb::Histograms::COMPRESSION_TIMES_NANOS;
3704 case 0x1D:
3705 return rocksdb::Histograms::DECOMPRESSION_TIMES_NANOS;
3706 case 0x1E:
3707 return rocksdb::Histograms::READ_NUM_MERGE_OPERANDS;
3708 case 0x1F:
3709 return rocksdb::Histograms::FLUSH_TIME;
3710 case 0x20:
3711 return rocksdb::Histograms::HISTOGRAM_ENUM_MAX;
3712
3713 default:
3714 // undefined/default
3715 return rocksdb::Histograms::DB_GET;
3716 }
3717 }
3718};
3719
3720// The portal class for org.rocksdb.StatsLevel
3721class StatsLevelJni {
3722 public:
3723 // Returns the equivalent org.rocksdb.StatsLevel for the provided
3724 // C++ rocksdb::StatsLevel enum
3725 static jbyte toJavaStatsLevel(
3726 const rocksdb::StatsLevel& stats_level) {
3727 switch(stats_level) {
3728 case rocksdb::StatsLevel::kExceptDetailedTimers:
3729 return 0x0;
3730 case rocksdb::StatsLevel::kExceptTimeForMutex:
3731 return 0x1;
3732 case rocksdb::StatsLevel::kAll:
3733 return 0x2;
3734
3735 default:
3736 // undefined/default
3737 return 0x0;
3738 }
3739 }
3740
3741 // Returns the equivalent C++ rocksdb::StatsLevel enum for the
3742 // provided Java org.rocksdb.StatsLevel
3743 static rocksdb::StatsLevel toCppStatsLevel(jbyte jstats_level) {
3744 switch(jstats_level) {
3745 case 0x0:
3746 return rocksdb::StatsLevel::kExceptDetailedTimers;
3747 case 0x1:
3748 return rocksdb::StatsLevel::kExceptTimeForMutex;
3749 case 0x2:
3750 return rocksdb::StatsLevel::kAll;
3751
3752 default:
3753 // undefined/default
3754 return rocksdb::StatsLevel::kExceptDetailedTimers;
3755 }
7c673cae
FG
3756 }
3757};
3758
11fdf7f2
TL
3759// The portal class for org.rocksdb.RateLimiterMode
3760class RateLimiterModeJni {
7c673cae 3761 public:
11fdf7f2
TL
3762 // Returns the equivalent org.rocksdb.RateLimiterMode for the provided
3763 // C++ rocksdb::RateLimiter::Mode enum
3764 static jbyte toJavaRateLimiterMode(
3765 const rocksdb::RateLimiter::Mode& rate_limiter_mode) {
3766 switch(rate_limiter_mode) {
3767 case rocksdb::RateLimiter::Mode::kReadsOnly:
3768 return 0x0;
3769 case rocksdb::RateLimiter::Mode::kWritesOnly:
3770 return 0x1;
3771 case rocksdb::RateLimiter::Mode::kAllIo:
3772 return 0x2;
7c673cae 3773
11fdf7f2
TL
3774 default:
3775 // undefined/default
3776 return 0x1;
7c673cae 3777 }
11fdf7f2 3778 }
7c673cae 3779
11fdf7f2
TL
3780 // Returns the equivalent C++ rocksdb::RateLimiter::Mode enum for the
3781 // provided Java org.rocksdb.RateLimiterMode
3782 static rocksdb::RateLimiter::Mode toCppRateLimiterMode(jbyte jrate_limiter_mode) {
3783 switch(jrate_limiter_mode) {
3784 case 0x0:
3785 return rocksdb::RateLimiter::Mode::kReadsOnly;
3786 case 0x1:
3787 return rocksdb::RateLimiter::Mode::kWritesOnly;
3788 case 0x2:
3789 return rocksdb::RateLimiter::Mode::kAllIo;
7c673cae 3790
11fdf7f2
TL
3791 default:
3792 // undefined/default
3793 return rocksdb::RateLimiter::Mode::kWritesOnly;
7c673cae 3794 }
11fdf7f2
TL
3795 }
3796};
7c673cae 3797
11fdf7f2
TL
3798// The portal class for org.rocksdb.Transaction
3799class TransactionJni : public JavaClass {
3800 public:
7c673cae 3801 /**
11fdf7f2 3802 * Get the Java Class org.rocksdb.Transaction
7c673cae
FG
3803 *
3804 * @param env A pointer to the Java environment
3805 *
3806 * @return The Java Class or nullptr if one of the
3807 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3808 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3809 */
3810 static jclass getJClass(JNIEnv* env) {
11fdf7f2
TL
3811 return JavaClass::getJClass(env,
3812 "org/rocksdb/Transaction");
7c673cae
FG
3813 }
3814
3815 /**
11fdf7f2 3816 * Create a new Java org.rocksdb.Transaction.WaitingTransactions object
7c673cae
FG
3817 *
3818 * @param env A pointer to the Java environment
11fdf7f2
TL
3819 * @param jtransaction A Java org.rocksdb.Transaction object
3820 * @param column_family_id The id of the column family
3821 * @param key The key
3822 * @param transaction_ids The transaction ids
7c673cae 3823 *
11fdf7f2
TL
3824 * @return A reference to a Java
3825 * org.rocksdb.Transaction.WaitingTransactions object,
3826 * or nullptr if an an exception occurs
7c673cae 3827 */
11fdf7f2
TL
3828 static jobject newWaitingTransactions(JNIEnv* env, jobject jtransaction,
3829 const uint32_t column_family_id, const std::string &key,
3830 const std::vector<TransactionID> &transaction_ids) {
7c673cae
FG
3831 jclass jclazz = getJClass(env);
3832 if(jclazz == nullptr) {
3833 // exception occurred accessing class
3834 return nullptr;
3835 }
3836
11fdf7f2
TL
3837 jmethodID mid = env->GetMethodID(
3838 jclazz, "newWaitingTransactions", "(JLjava/lang/String;[J)Lorg/rocksdb/Transaction$WaitingTransactions;");
3839 if(mid == nullptr) {
3840 // exception thrown: NoSuchMethodException or OutOfMemoryError
7c673cae 3841 return nullptr;
11fdf7f2
TL
3842 }
3843
3844 jstring jkey = env->NewStringUTF(key.c_str());
3845 if(jkey == nullptr) {
3846 // exception thrown: OutOfMemoryError
7c673cae
FG
3847 return nullptr;
3848 }
3849
11fdf7f2
TL
3850 const size_t len = transaction_ids.size();
3851 jlongArray jtransaction_ids = env->NewLongArray(static_cast<jsize>(len));
3852 if(jtransaction_ids == nullptr) {
3853 // exception thrown: OutOfMemoryError
3854 env->DeleteLocalRef(jkey);
3855 return nullptr;
3856 }
3857
3858 jlong *body = env->GetLongArrayElements(jtransaction_ids, nullptr);
3859 if(body == nullptr) {
3860 // exception thrown: OutOfMemoryError
3861 env->DeleteLocalRef(jkey);
3862 env->DeleteLocalRef(jtransaction_ids);
3863 return nullptr;
3864 }
3865 for(size_t i = 0; i < len; ++i) {
3866 body[i] = static_cast<jlong>(transaction_ids[i]);
3867 }
3868 env->ReleaseLongArrayElements(jtransaction_ids, body, 0);
3869
3870 jobject jwaiting_transactions = env->CallObjectMethod(jtransaction,
3871 mid, static_cast<jlong>(column_family_id), jkey, jtransaction_ids);
3872 if(env->ExceptionCheck()) {
3873 // exception thrown: InstantiationException or OutOfMemoryError
3874 env->DeleteLocalRef(jkey);
3875 env->DeleteLocalRef(jtransaction_ids);
3876 return nullptr;
3877 }
3878
3879 return jwaiting_transactions;
7c673cae
FG
3880 }
3881};
3882
11fdf7f2
TL
3883// The portal class for org.rocksdb.TransactionDB
3884class TransactionDBJni : public JavaClass {
7c673cae 3885 public:
11fdf7f2
TL
3886 /**
3887 * Get the Java Class org.rocksdb.TransactionDB
3888 *
3889 * @param env A pointer to the Java environment
3890 *
3891 * @return The Java Class or nullptr if one of the
3892 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3893 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3894 */
3895 static jclass getJClass(JNIEnv* env) {
3896 return JavaClass::getJClass(env,
3897 "org/rocksdb/TransactionDB");
3898 }
3899
7c673cae 3900 /**
11fdf7f2 3901 * Create a new Java org.rocksdb.TransactionDB.DeadlockInfo object
7c673cae
FG
3902 *
3903 * @param env A pointer to the Java environment
11fdf7f2
TL
3904 * @param jtransaction A Java org.rocksdb.Transaction object
3905 * @param column_family_id The id of the column family
3906 * @param key The key
3907 * @param transaction_ids The transaction ids
7c673cae 3908 *
11fdf7f2
TL
3909 * @return A reference to a Java
3910 * org.rocksdb.Transaction.WaitingTransactions object,
3911 * or nullptr if an an exception occurs
7c673cae 3912 */
11fdf7f2
TL
3913 static jobject newDeadlockInfo(JNIEnv* env, jobject jtransaction_db,
3914 const rocksdb::TransactionID transaction_id,
3915 const uint32_t column_family_id, const std::string &waiting_key,
3916 const bool exclusive) {
3917 jclass jclazz = getJClass(env);
3918 if(jclazz == nullptr) {
3919 // exception occurred accessing class
3920 return nullptr;
7c673cae
FG
3921 }
3922
11fdf7f2
TL
3923 jmethodID mid = env->GetMethodID(
3924 jclazz, "newDeadlockInfo", "(JJLjava/lang/String;Z)Lorg/rocksdb/TransactionDB$DeadlockInfo;");
3925 if(mid == nullptr) {
3926 // exception thrown: NoSuchMethodException or OutOfMemoryError
3927 return nullptr;
7c673cae
FG
3928 }
3929
11fdf7f2
TL
3930 jstring jwaiting_key = env->NewStringUTF(waiting_key.c_str());
3931 if(jwaiting_key == nullptr) {
3932 // exception thrown: OutOfMemoryError
3933 return nullptr;
7c673cae
FG
3934 }
3935
11fdf7f2
TL
3936 // resolve the column family id to a ColumnFamilyHandle
3937 jobject jdeadlock_info = env->CallObjectMethod(jtransaction_db,
3938 mid, transaction_id, static_cast<jlong>(column_family_id),
3939 jwaiting_key, exclusive);
3940 if(env->ExceptionCheck()) {
3941 // exception thrown: InstantiationException or OutOfMemoryError
3942 env->DeleteLocalRef(jwaiting_key);
3943 return nullptr;
7c673cae
FG
3944 }
3945
11fdf7f2
TL
3946 return jdeadlock_info;
3947 }
3948};
7c673cae 3949
11fdf7f2
TL
3950// The portal class for org.rocksdb.TxnDBWritePolicy
3951class TxnDBWritePolicyJni {
3952 public:
3953 // Returns the equivalent org.rocksdb.TxnDBWritePolicy for the provided
3954 // C++ rocksdb::TxnDBWritePolicy enum
3955 static jbyte toJavaTxnDBWritePolicy(
3956 const rocksdb::TxnDBWritePolicy& txndb_write_policy) {
3957 switch(txndb_write_policy) {
3958 case rocksdb::TxnDBWritePolicy::WRITE_COMMITTED:
3959 return 0x0;
3960 case rocksdb::TxnDBWritePolicy::WRITE_PREPARED:
3961 return 0x1;
3962 case rocksdb::TxnDBWritePolicy::WRITE_UNPREPARED:
3963 return 0x2;
3964 default:
3965 return 0x7F; // undefined
3966 }
3967 }
3968
3969 // Returns the equivalent C++ rocksdb::TxnDBWritePolicy enum for the
3970 // provided Java org.rocksdb.TxnDBWritePolicy
3971 static rocksdb::TxnDBWritePolicy toCppTxnDBWritePolicy(
3972 jbyte jtxndb_write_policy) {
3973 switch(jtxndb_write_policy) {
3974 case 0x0:
3975 return rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
3976 case 0x1:
3977 return rocksdb::TxnDBWritePolicy::WRITE_PREPARED;
3978 case 0x2:
3979 return rocksdb::TxnDBWritePolicy::WRITE_UNPREPARED;
3980 default:
3981 // undefined/default
3982 return rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
3983 }
3984 }
3985};
7c673cae 3986
11fdf7f2
TL
3987// The portal class for org.rocksdb.TransactionDB.KeyLockInfo
3988class KeyLockInfoJni : public JavaClass {
3989 public:
7c673cae 3990 /**
11fdf7f2 3991 * Get the Java Class org.rocksdb.TransactionDB.KeyLockInfo
7c673cae
FG
3992 *
3993 * @param env A pointer to the Java environment
3994 *
3995 * @return The Java Class or nullptr if one of the
3996 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3997 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3998 */
3999 static jclass getJClass(JNIEnv* env) {
11fdf7f2
TL
4000 return JavaClass::getJClass(env,
4001 "org/rocksdb/TransactionDB$KeyLockInfo");
7c673cae
FG
4002 }
4003
4004 /**
11fdf7f2
TL
4005 * Create a new Java org.rocksdb.TransactionDB.KeyLockInfo object
4006 * with the same properties as the provided C++ rocksdb::KeyLockInfo object
7c673cae
FG
4007 *
4008 * @param env A pointer to the Java environment
11fdf7f2 4009 * @param key_lock_info The rocksdb::KeyLockInfo object
7c673cae 4010 *
11fdf7f2
TL
4011 * @return A reference to a Java
4012 * org.rocksdb.TransactionDB.KeyLockInfo object,
4013 * or nullptr if an an exception occurs
7c673cae 4014 */
11fdf7f2
TL
4015 static jobject construct(JNIEnv* env,
4016 const rocksdb::KeyLockInfo& key_lock_info) {
7c673cae
FG
4017 jclass jclazz = getJClass(env);
4018 if(jclazz == nullptr) {
4019 // exception occurred accessing class
4020 return nullptr;
4021 }
4022
11fdf7f2
TL
4023 jmethodID mid = env->GetMethodID(
4024 jclazz, "<init>", "(Ljava/lang/String;[JZ)V");
4025 if (mid == nullptr) {
4026 // exception thrown: NoSuchMethodException or OutOfMemoryError
7c673cae 4027 return nullptr;
11fdf7f2
TL
4028 }
4029
4030 jstring jkey = env->NewStringUTF(key_lock_info.key.c_str());
4031 if (jkey == nullptr) {
4032 // exception thrown: OutOfMemoryError
7c673cae
FG
4033 return nullptr;
4034 }
4035
11fdf7f2
TL
4036 const jsize jtransaction_ids_len = static_cast<jsize>(key_lock_info.ids.size());
4037 jlongArray jtransactions_ids = env->NewLongArray(jtransaction_ids_len);
4038 if (jtransactions_ids == nullptr) {
4039 // exception thrown: OutOfMemoryError
4040 env->DeleteLocalRef(jkey);
4041 return nullptr;
4042 }
4043
4044 const jobject jkey_lock_info = env->NewObject(jclazz, mid,
4045 jkey, jtransactions_ids, key_lock_info.exclusive);
4046 if(jkey_lock_info == nullptr) {
4047 // exception thrown: InstantiationException or OutOfMemoryError
4048 env->DeleteLocalRef(jtransactions_ids);
4049 env->DeleteLocalRef(jkey);
4050 return nullptr;
4051 }
4052
4053 return jkey_lock_info;
7c673cae
FG
4054 }
4055};
4056
11fdf7f2
TL
4057// The portal class for org.rocksdb.TransactionDB.DeadlockInfo
4058class DeadlockInfoJni : public JavaClass {
7c673cae
FG
4059 public:
4060 /**
11fdf7f2 4061 * Get the Java Class org.rocksdb.TransactionDB.DeadlockInfo
7c673cae
FG
4062 *
4063 * @param env A pointer to the Java environment
4064 *
4065 * @return The Java Class or nullptr if one of the
4066 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4067 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4068 */
11fdf7f2
TL
4069 static jclass getJClass(JNIEnv* env) {
4070 return JavaClass::getJClass(env,"org/rocksdb/TransactionDB$DeadlockInfo");
7c673cae 4071 }
11fdf7f2
TL
4072};
4073
4074// The portal class for org.rocksdb.TransactionDB.DeadlockPath
4075class DeadlockPathJni : public JavaClass {
4076 public:
7c673cae 4077 /**
11fdf7f2 4078 * Get the Java Class org.rocksdb.TransactionDB.DeadlockPath
7c673cae
FG
4079 *
4080 * @param env A pointer to the Java environment
4081 *
4082 * @return The Java Class or nullptr if one of the
4083 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4084 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4085 */
4086 static jclass getJClass(JNIEnv* env) {
4087 return JavaClass::getJClass(env,
11fdf7f2 4088 "org/rocksdb/TransactionDB$DeadlockPath");
7c673cae
FG
4089 }
4090
4091 /**
11fdf7f2 4092 * Create a new Java org.rocksdb.TransactionDB.DeadlockPath object
7c673cae
FG
4093 *
4094 * @param env A pointer to the Java environment
7c673cae
FG
4095 *
4096 * @return A reference to a Java
11fdf7f2 4097 * org.rocksdb.TransactionDB.DeadlockPath object,
7c673cae
FG
4098 * or nullptr if an an exception occurs
4099 */
4100 static jobject construct(JNIEnv* env,
11fdf7f2 4101 const jobjectArray jdeadlock_infos, const bool limit_exceeded) {
7c673cae
FG
4102 jclass jclazz = getJClass(env);
4103 if(jclazz == nullptr) {
4104 // exception occurred accessing class
4105 return nullptr;
4106 }
4107
4108 jmethodID mid = env->GetMethodID(
11fdf7f2
TL
4109 jclazz, "<init>", "([LDeadlockInfo;Z)V");
4110 if (mid == nullptr) {
7c673cae
FG
4111 // exception thrown: NoSuchMethodException or OutOfMemoryError
4112 return nullptr;
4113 }
4114
11fdf7f2
TL
4115 const jobject jdeadlock_path = env->NewObject(jclazz, mid,
4116 jdeadlock_infos, limit_exceeded);
4117 if(jdeadlock_path == nullptr) {
7c673cae
FG
4118 // exception thrown: InstantiationException or OutOfMemoryError
4119 return nullptr;
4120 }
4121
11fdf7f2 4122 return jdeadlock_path;
7c673cae
FG
4123 }
4124};
4125
4126// various utility functions for working with RocksDB and JNI
4127class JniUtil {
4128 public:
4129 /**
4130 * Obtains a reference to the JNIEnv from
4131 * the JVM
4132 *
4133 * If the current thread is not attached to the JavaVM
4134 * then it will be attached so as to retrieve the JNIEnv
4135 *
4136 * If a thread is attached, it must later be manually
4137 * released by calling JavaVM::DetachCurrentThread.
4138 * This can be handled by always matching calls to this
4139 * function with calls to {@link JniUtil::releaseJniEnv(JavaVM*, jboolean)}
4140 *
4141 * @param jvm (IN) A pointer to the JavaVM instance
4142 * @param attached (OUT) A pointer to a boolean which
4143 * will be set to JNI_TRUE if we had to attach the thread
4144 *
4145 * @return A pointer to the JNIEnv or nullptr if a fatal error
4146 * occurs and the JNIEnv cannot be retrieved
4147 */
4148 static JNIEnv* getJniEnv(JavaVM* jvm, jboolean* attached) {
4149 assert(jvm != nullptr);
4150
4151 JNIEnv *env;
4152 const jint env_rs = jvm->GetEnv(reinterpret_cast<void**>(&env),
4153 JNI_VERSION_1_2);
4154
4155 if(env_rs == JNI_OK) {
4156 // current thread is already attached, return the JNIEnv
4157 *attached = JNI_FALSE;
4158 return env;
4159 } else if(env_rs == JNI_EDETACHED) {
4160 // current thread is not attached, attempt to attach
4161 const jint rs_attach = jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);
4162 if(rs_attach == JNI_OK) {
4163 *attached = JNI_TRUE;
4164 return env;
4165 } else {
4166 // error, could not attach the thread
4167 std::cerr << "JniUtil::getJinEnv - Fatal: could not attach current thread to JVM!" << std::endl;
4168 return nullptr;
4169 }
4170 } else if(env_rs == JNI_EVERSION) {
4171 // error, JDK does not support JNI_VERSION_1_2+
4172 std::cerr << "JniUtil::getJinEnv - Fatal: JDK does not support JNI_VERSION_1_2" << std::endl;
4173 return nullptr;
4174 } else {
4175 std::cerr << "JniUtil::getJinEnv - Fatal: Unknown error: env_rs=" << env_rs << std::endl;
4176 return nullptr;
4177 }
4178 }
4179
4180 /**
4181 * Counterpart to {@link JniUtil::getJniEnv(JavaVM*, jboolean*)}
4182 *
4183 * Detachess the current thread from the JVM if it was previously
4184 * attached
4185 *
4186 * @param jvm (IN) A pointer to the JavaVM instance
4187 * @param attached (IN) JNI_TRUE if we previously had to attach the thread
4188 * to the JavaVM to get the JNIEnv
4189 */
4190 static void releaseJniEnv(JavaVM* jvm, jboolean& attached) {
4191 assert(jvm != nullptr);
4192 if(attached == JNI_TRUE) {
4193 const jint rs_detach = jvm->DetachCurrentThread();
4194 assert(rs_detach == JNI_OK);
4195 if(rs_detach != JNI_OK) {
4196 std::cerr << "JniUtil::getJinEnv - Warn: Unable to detach current thread from JVM!" << std::endl;
4197 }
4198 }
4199 }
4200
4201 /**
4202 * Copies a Java String[] to a C++ std::vector<std::string>
4203 *
4204 * @param env (IN) A pointer to the java environment
4205 * @param jss (IN) The Java String array to copy
4206 * @param has_exception (OUT) will be set to JNI_TRUE
4207 * if an OutOfMemoryError or ArrayIndexOutOfBoundsException
4208 * exception occurs
4209 *
4210 * @return A std::vector<std:string> containing copies of the Java strings
4211 */
4212 static std::vector<std::string> copyStrings(JNIEnv* env,
4213 jobjectArray jss, jboolean* has_exception) {
4214 return rocksdb::JniUtil::copyStrings(env, jss,
4215 env->GetArrayLength(jss), has_exception);
4216 }
4217
4218 /**
4219 * Copies a Java String[] to a C++ std::vector<std::string>
4220 *
4221 * @param env (IN) A pointer to the java environment
4222 * @param jss (IN) The Java String array to copy
4223 * @param jss_len (IN) The length of the Java String array to copy
4224 * @param has_exception (OUT) will be set to JNI_TRUE
4225 * if an OutOfMemoryError or ArrayIndexOutOfBoundsException
4226 * exception occurs
4227 *
4228 * @return A std::vector<std:string> containing copies of the Java strings
4229 */
4230 static std::vector<std::string> copyStrings(JNIEnv* env,
4231 jobjectArray jss, const jsize jss_len, jboolean* has_exception) {
4232 std::vector<std::string> strs;
4233 for (jsize i = 0; i < jss_len; i++) {
4234 jobject js = env->GetObjectArrayElement(jss, i);
4235 if(env->ExceptionCheck()) {
4236 // exception thrown: ArrayIndexOutOfBoundsException
4237 *has_exception = JNI_TRUE;
4238 return strs;
4239 }
4240
4241 jstring jstr = static_cast<jstring>(js);
4242 const char* str = env->GetStringUTFChars(jstr, nullptr);
4243 if(str == nullptr) {
4244 // exception thrown: OutOfMemoryError
4245 env->DeleteLocalRef(js);
4246 *has_exception = JNI_TRUE;
4247 return strs;
4248 }
4249
4250 strs.push_back(std::string(str));
4251
4252 env->ReleaseStringUTFChars(jstr, str);
4253 env->DeleteLocalRef(js);
4254 }
4255
4256 *has_exception = JNI_FALSE;
11fdf7f2
TL
4257 return strs;
4258 }
4259
4260 /**
4261 * Copies a jstring to a C-style null-terminated byte string
4262 * and releases the original jstring
4263 *
4264 * The jstring is copied as UTF-8
4265 *
4266 * If an exception occurs, then JNIEnv::ExceptionCheck()
4267 * will have been called
4268 *
4269 * @param env (IN) A pointer to the java environment
4270 * @param js (IN) The java string to copy
4271 * @param has_exception (OUT) will be set to JNI_TRUE
4272 * if an OutOfMemoryError exception occurs
4273 *
4274 * @return A pointer to the copied string, or a
4275 * nullptr if has_exception == JNI_TRUE
4276 */
4277 static std::unique_ptr<char[]> copyString(JNIEnv* env, jstring js,
4278 jboolean* has_exception) {
4279 const char *utf = env->GetStringUTFChars(js, nullptr);
4280 if(utf == nullptr) {
4281 // exception thrown: OutOfMemoryError
4282 env->ExceptionCheck();
4283 *has_exception = JNI_TRUE;
4284 return nullptr;
4285 } else if(env->ExceptionCheck()) {
4286 // exception thrown
4287 env->ReleaseStringUTFChars(js, utf);
4288 *has_exception = JNI_TRUE;
4289 return nullptr;
4290 }
4291
4292 const jsize utf_len = env->GetStringUTFLength(js);
4293 std::unique_ptr<char[]> str(new char[utf_len + 1]); // Note: + 1 is needed for the c_str null terminator
4294 std::strcpy(str.get(), utf);
4295 env->ReleaseStringUTFChars(js, utf);
4296 *has_exception = JNI_FALSE;
4297 return str;
7c673cae
FG
4298 }
4299
4300 /**
4301 * Copies a jstring to a std::string
4302 * and releases the original jstring
4303 *
4304 * If an exception occurs, then JNIEnv::ExceptionCheck()
4305 * will have been called
4306 *
4307 * @param env (IN) A pointer to the java environment
4308 * @param js (IN) The java string to copy
4309 * @param has_exception (OUT) will be set to JNI_TRUE
4310 * if an OutOfMemoryError exception occurs
4311 *
4312 * @return A std:string copy of the jstring, or an
4313 * empty std::string if has_exception == JNI_TRUE
4314 */
11fdf7f2
TL
4315 static std::string copyStdString(JNIEnv* env, jstring js,
4316 jboolean* has_exception) {
7c673cae
FG
4317 const char *utf = env->GetStringUTFChars(js, nullptr);
4318 if(utf == nullptr) {
4319 // exception thrown: OutOfMemoryError
4320 env->ExceptionCheck();
4321 *has_exception = JNI_TRUE;
4322 return std::string();
4323 } else if(env->ExceptionCheck()) {
4324 // exception thrown
4325 env->ReleaseStringUTFChars(js, utf);
4326 *has_exception = JNI_TRUE;
4327 return std::string();
4328 }
4329
4330 std::string name(utf);
4331 env->ReleaseStringUTFChars(js, utf);
4332 *has_exception = JNI_FALSE;
4333 return name;
4334 }
4335
4336 /**
4337 * Copies bytes from a std::string to a jByteArray
4338 *
4339 * @param env A pointer to the java environment
4340 * @param bytes The bytes to copy
4341 *
4342 * @return the Java byte[] or nullptr if an exception occurs
11fdf7f2
TL
4343 *
4344 * @throws RocksDBException thrown
4345 * if memory size to copy exceeds general java specific array size limitation.
7c673cae
FG
4346 */
4347 static jbyteArray copyBytes(JNIEnv* env, std::string bytes) {
11fdf7f2 4348 return createJavaByteArrayWithSizeCheck(env, bytes.c_str(), bytes.size());
7c673cae
FG
4349 }
4350
4351 /**
4352 * Given a Java byte[][] which is an array of java.lang.Strings
4353 * where each String is a byte[], the passed function `string_fn`
4354 * will be called on each String, the result is the collected by
4355 * calling the passed function `collector_fn`
4356 *
4357 * @param env (IN) A pointer to the java environment
4358 * @param jbyte_strings (IN) A Java array of Strings expressed as bytes
4359 * @param string_fn (IN) A transform function to call for each String
4360 * @param collector_fn (IN) A collector which is called for the result
4361 * of each `string_fn`
4362 * @param has_exception (OUT) will be set to JNI_TRUE
4363 * if an ArrayIndexOutOfBoundsException or OutOfMemoryError
4364 * exception occurs
4365 */
4366 template <typename T> static void byteStrings(JNIEnv* env,
4367 jobjectArray jbyte_strings,
4368 std::function<T(const char*, const size_t)> string_fn,
4369 std::function<void(size_t, T)> collector_fn,
4370 jboolean *has_exception) {
4371 const jsize jlen = env->GetArrayLength(jbyte_strings);
4372
4373 for(jsize i = 0; i < jlen; i++) {
4374 jobject jbyte_string_obj = env->GetObjectArrayElement(jbyte_strings, i);
4375 if(env->ExceptionCheck()) {
4376 // exception thrown: ArrayIndexOutOfBoundsException
4377 *has_exception = JNI_TRUE; // signal error
4378 return;
4379 }
4380
4381 jbyteArray jbyte_string_ary =
4382 reinterpret_cast<jbyteArray>(jbyte_string_obj);
4383 T result = byteString(env, jbyte_string_ary, string_fn, has_exception);
4384
4385 env->DeleteLocalRef(jbyte_string_obj);
4386
4387 if(*has_exception == JNI_TRUE) {
4388 // exception thrown: OutOfMemoryError
4389 return;
4390 }
4391
4392 collector_fn(i, result);
4393 }
4394
4395 *has_exception = JNI_FALSE;
4396 }
4397
4398 /**
4399 * Given a Java String which is expressed as a Java Byte Array byte[],
4400 * the passed function `string_fn` will be called on the String
4401 * and the result returned
4402 *
4403 * @param env (IN) A pointer to the java environment
4404 * @param jbyte_string_ary (IN) A Java String expressed in bytes
4405 * @param string_fn (IN) A transform function to call on the String
4406 * @param has_exception (OUT) will be set to JNI_TRUE
4407 * if an OutOfMemoryError exception occurs
4408 */
4409 template <typename T> static T byteString(JNIEnv* env,
4410 jbyteArray jbyte_string_ary,
4411 std::function<T(const char*, const size_t)> string_fn,
4412 jboolean* has_exception) {
4413 const jsize jbyte_string_len = env->GetArrayLength(jbyte_string_ary);
11fdf7f2
TL
4414 return byteString<T>(env, jbyte_string_ary, jbyte_string_len, string_fn,
4415 has_exception);
4416 }
4417
4418 /**
4419 * Given a Java String which is expressed as a Java Byte Array byte[],
4420 * the passed function `string_fn` will be called on the String
4421 * and the result returned
4422 *
4423 * @param env (IN) A pointer to the java environment
4424 * @param jbyte_string_ary (IN) A Java String expressed in bytes
4425 * @param jbyte_string_len (IN) The length of the Java String
4426 * expressed in bytes
4427 * @param string_fn (IN) A transform function to call on the String
4428 * @param has_exception (OUT) will be set to JNI_TRUE
4429 * if an OutOfMemoryError exception occurs
4430 */
4431 template <typename T> static T byteString(JNIEnv* env,
4432 jbyteArray jbyte_string_ary, const jsize jbyte_string_len,
4433 std::function<T(const char*, const size_t)> string_fn,
4434 jboolean* has_exception) {
7c673cae
FG
4435 jbyte* jbyte_string =
4436 env->GetByteArrayElements(jbyte_string_ary, nullptr);
4437 if(jbyte_string == nullptr) {
4438 // exception thrown: OutOfMemoryError
4439 *has_exception = JNI_TRUE;
4440 return nullptr; // signal error
4441 }
4442
4443 T result =
4444 string_fn(reinterpret_cast<char *>(jbyte_string), jbyte_string_len);
4445
4446 env->ReleaseByteArrayElements(jbyte_string_ary, jbyte_string, JNI_ABORT);
4447
4448 *has_exception = JNI_FALSE;
4449 return result;
4450 }
4451
4452 /**
4453 * Converts a std::vector<string> to a Java byte[][] where each Java String
4454 * is expressed as a Java Byte Array byte[].
4455 *
4456 * @param env A pointer to the java environment
4457 * @param strings A vector of Strings
4458 *
4459 * @return A Java array of Strings expressed as bytes
4460 */
4461 static jobjectArray stringsBytes(JNIEnv* env, std::vector<std::string> strings) {
4462 jclass jcls_ba = ByteJni::getArrayJClass(env);
4463 if(jcls_ba == nullptr) {
4464 // exception occurred
4465 return nullptr;
4466 }
4467
4468 const jsize len = static_cast<jsize>(strings.size());
4469
4470 jobjectArray jbyte_strings = env->NewObjectArray(len, jcls_ba, nullptr);
4471 if(jbyte_strings == nullptr) {
4472 // exception thrown: OutOfMemoryError
4473 return nullptr;
4474 }
4475
4476 for (jsize i = 0; i < len; i++) {
4477 std::string *str = &strings[i];
4478 const jsize str_len = static_cast<jsize>(str->size());
4479
4480 jbyteArray jbyte_string_ary = env->NewByteArray(str_len);
4481 if(jbyte_string_ary == nullptr) {
4482 // exception thrown: OutOfMemoryError
4483 env->DeleteLocalRef(jbyte_strings);
4484 return nullptr;
4485 }
4486
4487 env->SetByteArrayRegion(
4488 jbyte_string_ary, 0, str_len,
4489 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(str->c_str())));
4490 if(env->ExceptionCheck()) {
4491 // exception thrown: ArrayIndexOutOfBoundsException
4492 env->DeleteLocalRef(jbyte_string_ary);
4493 env->DeleteLocalRef(jbyte_strings);
4494 return nullptr;
4495 }
4496
4497 env->SetObjectArrayElement(jbyte_strings, i, jbyte_string_ary);
4498 if(env->ExceptionCheck()) {
4499 // exception thrown: ArrayIndexOutOfBoundsException
4500 // or ArrayStoreException
4501 env->DeleteLocalRef(jbyte_string_ary);
4502 env->DeleteLocalRef(jbyte_strings);
4503 return nullptr;
4504 }
4505
4506 env->DeleteLocalRef(jbyte_string_ary);
4507 }
4508
4509 return jbyte_strings;
4510 }
11fdf7f2
TL
4511
4512 /**
4513 * Copies bytes to a new jByteArray with the check of java array size limitation.
4514 *
4515 * @param bytes pointer to memory to copy to a new jByteArray
4516 * @param size number of bytes to copy
4517 *
4518 * @return the Java byte[] or nullptr if an exception occurs
4519 *
4520 * @throws RocksDBException thrown
4521 * if memory size to copy exceeds general java array size limitation to avoid overflow.
4522 */
4523 static jbyteArray createJavaByteArrayWithSizeCheck(JNIEnv* env, const char* bytes, const size_t size) {
4524 // Limitation for java array size is vm specific
4525 // In general it cannot exceed Integer.MAX_VALUE (2^31 - 1)
4526 // Current HotSpot VM limitation for array size is Integer.MAX_VALUE - 5 (2^31 - 1 - 5)
4527 // It means that the next call to env->NewByteArray can still end with
4528 // OutOfMemoryError("Requested array size exceeds VM limit") coming from VM
4529 static const size_t MAX_JARRAY_SIZE = (static_cast<size_t>(1)) << 31;
4530 if(size > MAX_JARRAY_SIZE) {
4531 rocksdb::RocksDBExceptionJni::ThrowNew(env, "Requested array size exceeds VM limit");
4532 return nullptr;
4533 }
4534
4535 const jsize jlen = static_cast<jsize>(size);
4536 jbyteArray jbytes = env->NewByteArray(jlen);
4537 if(jbytes == nullptr) {
4538 // exception thrown: OutOfMemoryError
4539 return nullptr;
4540 }
4541
4542 env->SetByteArrayRegion(jbytes, 0, jlen,
4543 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(bytes)));
4544 if(env->ExceptionCheck()) {
4545 // exception thrown: ArrayIndexOutOfBoundsException
4546 env->DeleteLocalRef(jbytes);
4547 return nullptr;
4548 }
4549
4550 return jbytes;
4551 }
4552
4553 /**
4554 * Copies bytes from a rocksdb::Slice to a jByteArray
4555 *
4556 * @param env A pointer to the java environment
4557 * @param bytes The bytes to copy
4558 *
4559 * @return the Java byte[] or nullptr if an exception occurs
4560 *
4561 * @throws RocksDBException thrown
4562 * if memory size to copy exceeds general java specific array size limitation.
4563 */
4564 static jbyteArray copyBytes(JNIEnv* env, const Slice& bytes) {
4565 return createJavaByteArrayWithSizeCheck(env, bytes.data(), bytes.size());
4566 }
7c673cae
FG
4567
4568 /*
4569 * Helper for operations on a key and value
4570 * for example WriteBatch->Put
4571 *
11fdf7f2 4572 * TODO(AR) could be used for RocksDB->Put etc.
7c673cae 4573 */
11fdf7f2
TL
4574 static std::unique_ptr<rocksdb::Status> kv_op(
4575 std::function<rocksdb::Status(rocksdb::Slice, rocksdb::Slice)> op,
4576 JNIEnv* env, jobject /*jobj*/,
7c673cae 4577 jbyteArray jkey, jint jkey_len,
11fdf7f2 4578 jbyteArray jvalue, jint jvalue_len) {
7c673cae
FG
4579 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
4580 if(env->ExceptionCheck()) {
4581 // exception thrown: OutOfMemoryError
11fdf7f2 4582 return nullptr;
7c673cae
FG
4583 }
4584
11fdf7f2 4585 jbyte* value = env->GetByteArrayElements(jvalue, nullptr);
7c673cae
FG
4586 if(env->ExceptionCheck()) {
4587 // exception thrown: OutOfMemoryError
4588 if(key != nullptr) {
4589 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
4590 }
11fdf7f2 4591 return nullptr;
7c673cae
FG
4592 }
4593
4594 rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
4595 rocksdb::Slice value_slice(reinterpret_cast<char*>(value),
11fdf7f2 4596 jvalue_len);
7c673cae 4597
11fdf7f2 4598 auto status = op(key_slice, value_slice);
7c673cae
FG
4599
4600 if(value != nullptr) {
11fdf7f2 4601 env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
7c673cae
FG
4602 }
4603 if(key != nullptr) {
4604 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
4605 }
11fdf7f2
TL
4606
4607 return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(status));
7c673cae
FG
4608 }
4609
4610 /*
4611 * Helper for operations on a key
4612 * for example WriteBatch->Delete
4613 *
11fdf7f2 4614 * TODO(AR) could be used for RocksDB->Delete etc.
7c673cae 4615 */
11fdf7f2
TL
4616 static std::unique_ptr<rocksdb::Status> k_op(
4617 std::function<rocksdb::Status(rocksdb::Slice)> op,
4618 JNIEnv* env, jobject /*jobj*/,
7c673cae
FG
4619 jbyteArray jkey, jint jkey_len) {
4620 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
4621 if(env->ExceptionCheck()) {
4622 // exception thrown: OutOfMemoryError
11fdf7f2 4623 return nullptr;
7c673cae
FG
4624 }
4625
4626 rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
4627
11fdf7f2 4628 auto status = op(key_slice);
7c673cae
FG
4629
4630 if(key != nullptr) {
4631 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
4632 }
11fdf7f2
TL
4633
4634 return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(status));
7c673cae
FG
4635 }
4636
4637 /*
4638 * Helper for operations on a value
4639 * for example WriteBatchWithIndex->GetFromBatch
4640 */
4641 static jbyteArray v_op(
4642 std::function<rocksdb::Status(rocksdb::Slice, std::string*)> op,
4643 JNIEnv* env, jbyteArray jkey, jint jkey_len) {
4644 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
4645 if(env->ExceptionCheck()) {
4646 // exception thrown: OutOfMemoryError
4647 return nullptr;
4648 }
4649
4650 rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
4651
4652 std::string value;
4653 rocksdb::Status s = op(key_slice, &value);
4654
4655 if(key != nullptr) {
4656 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
4657 }
4658
4659 if (s.IsNotFound()) {
4660 return nullptr;
4661 }
4662
4663 if (s.ok()) {
4664 jbyteArray jret_value =
4665 env->NewByteArray(static_cast<jsize>(value.size()));
4666 if(jret_value == nullptr) {
4667 // exception thrown: OutOfMemoryError
4668 return nullptr;
4669 }
4670
4671 env->SetByteArrayRegion(jret_value, 0, static_cast<jsize>(value.size()),
4672 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.c_str())));
4673 if(env->ExceptionCheck()) {
4674 // exception thrown: ArrayIndexOutOfBoundsException
4675 if(jret_value != nullptr) {
4676 env->DeleteLocalRef(jret_value);
4677 }
4678 return nullptr;
4679 }
4680
4681 return jret_value;
4682 }
4683
4684 rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
4685 return nullptr;
4686 }
4687};
4688
11fdf7f2
TL
4689class ColumnFamilyDescriptorJni : public JavaClass {
4690 public:
4691 /**
4692 * Get the Java Class org.rocksdb.ColumnFamilyDescriptor
4693 *
4694 * @param env A pointer to the Java environment
4695 *
4696 * @return The Java Class or nullptr if one of the
4697 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4698 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4699 */
4700 static jclass getJClass(JNIEnv* env) {
4701 return JavaClass::getJClass(env, "org/rocksdb/ColumnFamilyDescriptor");
4702 }
4703
4704 /**
4705 * Create a new Java org.rocksdb.ColumnFamilyDescriptor object with the same
4706 * properties as the provided C++ rocksdb::ColumnFamilyDescriptor object
4707 *
4708 * @param env A pointer to the Java environment
4709 * @param cfd A pointer to rocksdb::ColumnFamilyDescriptor object
4710 *
4711 * @return A reference to a Java org.rocksdb.ColumnFamilyDescriptor object, or
4712 * nullptr if an an exception occurs
4713 */
4714 static jobject construct(JNIEnv* env, ColumnFamilyDescriptor* cfd) {
4715 jbyteArray jcf_name = JniUtil::copyBytes(env, cfd->name);
4716 jobject cfopts = ColumnFamilyOptionsJni::construct(env, &(cfd->options));
4717
4718 jclass jclazz = getJClass(env);
4719 if (jclazz == nullptr) {
4720 // exception occurred accessing class
4721 return nullptr;
4722 }
4723
4724 jmethodID mid = env->GetMethodID(jclazz, "<init>",
4725 "([BLorg/rocksdb/ColumnFamilyOptions;)V");
4726 if (mid == nullptr) {
4727 // exception thrown: NoSuchMethodException or OutOfMemoryError
4728 env->DeleteLocalRef(jcf_name);
4729 return nullptr;
4730 }
4731
4732 jobject jcfd = env->NewObject(jclazz, mid, jcf_name, cfopts);
4733 if (env->ExceptionCheck()) {
4734 env->DeleteLocalRef(jcf_name);
4735 return nullptr;
4736 }
4737
4738 return jcfd;
4739 }
4740
4741 /**
4742 * Get the Java Method: ColumnFamilyDescriptor#columnFamilyName
4743 *
4744 * @param env A pointer to the Java environment
4745 *
4746 * @return The Java Method ID or nullptr if the class or method id could not
4747 * be retieved
4748 */
4749 static jmethodID getColumnFamilyNameMethod(JNIEnv* env) {
4750 jclass jclazz = getJClass(env);
4751 if (jclazz == nullptr) {
4752 // exception occurred accessing class
4753 return nullptr;
4754 }
4755
4756 static jmethodID mid = env->GetMethodID(jclazz, "columnFamilyName", "()[B");
4757 assert(mid != nullptr);
4758 return mid;
4759 }
4760
4761 /**
4762 * Get the Java Method: ColumnFamilyDescriptor#columnFamilyOptions
4763 *
4764 * @param env A pointer to the Java environment
4765 *
4766 * @return The Java Method ID or nullptr if the class or method id could not
4767 * be retieved
4768 */
4769 static jmethodID getColumnFamilyOptionsMethod(JNIEnv* env) {
4770 jclass jclazz = getJClass(env);
4771 if (jclazz == nullptr) {
4772 // exception occurred accessing class
4773 return nullptr;
4774 }
4775
4776 static jmethodID mid = env->GetMethodID(
4777 jclazz, "columnFamilyOptions", "()Lorg/rocksdb/ColumnFamilyOptions;");
4778 assert(mid != nullptr);
4779 return mid;
4780 }
4781};
4782
4783class MapJni : public JavaClass {
4784 public:
4785 /**
4786 * Get the Java Class java.util.Map
4787 *
4788 * @param env A pointer to the Java environment
4789 *
4790 * @return The Java Class or nullptr if one of the
4791 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4792 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4793 */
4794 static jclass getClass(JNIEnv* env) {
4795 return JavaClass::getJClass(env, "java/util/Map");
4796 }
4797
4798 /**
4799 * Get the Java Method: Map#put
4800 *
4801 * @param env A pointer to the Java environment
4802 *
4803 * @return The Java Method ID or nullptr if the class or method id could not
4804 * be retieved
4805 */
4806 static jmethodID getMapPutMethodId(JNIEnv* env) {
4807 jclass jlist_clazz = getClass(env);
4808 if(jlist_clazz == nullptr) {
4809 // exception occurred accessing class
4810 return nullptr;
4811 }
4812
4813 static jmethodID mid =
4814 env->GetMethodID(jlist_clazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
4815 assert(mid != nullptr);
4816 return mid;
4817 }
4818};
4819
4820class HashMapJni : public JavaClass {
4821 public:
4822 /**
4823 * Get the Java Class java.util.HashMap
4824 *
4825 * @param env A pointer to the Java environment
4826 *
4827 * @return The Java Class or nullptr if one of the
4828 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4829 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4830 */
4831 static jclass getJClass(JNIEnv* env) {
4832 return JavaClass::getJClass(env, "java/util/HashMap");
4833 }
4834
4835 /**
4836 * Create a new Java java.util.HashMap object.
4837 *
4838 * @param env A pointer to the Java environment
4839 *
4840 * @return A reference to a Java java.util.HashMap object, or
4841 * nullptr if an an exception occurs
4842 */
4843 static jobject construct(JNIEnv* env, const uint32_t initial_capacity = 16) {
4844 jclass jclazz = getJClass(env);
4845 if (jclazz == nullptr) {
4846 // exception occurred accessing class
4847 return nullptr;
4848 }
4849
4850 jmethodID mid = env->GetMethodID(jclazz, "<init>", "(I)V");
4851 if (mid == nullptr) {
4852 // exception thrown: NoSuchMethodException or OutOfMemoryError
4853 return nullptr;
4854 }
4855
4856 jobject jhash_map = env->NewObject(jclazz, mid, static_cast<jint>(initial_capacity));
4857 if (env->ExceptionCheck()) {
4858 return nullptr;
4859 }
4860
4861 return jhash_map;
4862 }
4863
4864 /**
4865 * A function which maps a std::pair<K,V> to a std::pair<jobject, jobject>
4866 *
4867 * @return Either a pointer to a std::pair<jobject, jobject>, or nullptr
4868 * if an error occurs during the mapping
4869 */
4870 template <typename K, typename V>
4871 using FnMapKV = std::function<std::unique_ptr<std::pair<jobject, jobject>> (const std::pair<K, V>&)>;
4872
4873 // template <class I, typename K, typename V, typename K1, typename V1, typename std::enable_if<std::is_same<typename std::iterator_traits<I>::value_type, std::pair<const K,V>>::value, int32_t>::type = 0>
4874 // static void putAll(JNIEnv* env, const jobject jhash_map, I iterator, const FnMapKV<const K,V,K1,V1> &fn_map_kv) {
4875 /**
4876 * Returns true if it succeeds, false if an error occurs
4877 */
4878 template<class iterator_type, typename K, typename V>
4879 static bool putAll(JNIEnv* env, const jobject jhash_map, iterator_type iterator, iterator_type end, const FnMapKV<K, V> &fn_map_kv) {
4880 const jmethodID jmid_put = rocksdb::MapJni::getMapPutMethodId(env);
4881 if (jmid_put == nullptr) {
4882 return false;
4883 }
4884
4885 for (auto it = iterator; it != end; ++it) {
4886 const std::unique_ptr<std::pair<jobject, jobject>> result = fn_map_kv(*it);
4887 if (result == nullptr) {
4888 // an error occurred during fn_map_kv
4889 return false;
4890 }
4891 env->CallObjectMethod(jhash_map, jmid_put, result->first, result->second);
4892 if (env->ExceptionCheck()) {
4893 // exception occurred
4894 env->DeleteLocalRef(result->second);
4895 env->DeleteLocalRef(result->first);
4896 return false;
4897 }
4898
4899 // release local references
4900 env->DeleteLocalRef(result->second);
4901 env->DeleteLocalRef(result->first);
4902 }
4903
4904 return true;
4905 }
4906};
4907
4908class LongJni : public JavaClass {
4909 public:
4910 /**
4911 * Get the Java Class java.lang.Long
4912 *
4913 * @param env A pointer to the Java environment
4914 *
4915 * @return The Java Class or nullptr if one of the
4916 * ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4917 * OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4918 */
4919 static jclass getJClass(JNIEnv* env) {
4920 return JavaClass::getJClass(env, "java/lang/Long");
4921 }
4922
4923 static jobject valueOf(JNIEnv* env, jlong jprimitive_long) {
4924 jclass jclazz = getJClass(env);
4925 if (jclazz == nullptr) {
4926 // exception occurred accessing class
4927 return nullptr;
4928 }
4929
4930 jmethodID mid =
4931 env->GetStaticMethodID(jclazz, "valueOf", "(J)Ljava/lang/Long;");
4932 if (mid == nullptr) {
4933 // exception thrown: NoSuchMethodException or OutOfMemoryError
4934 return nullptr;
4935 }
4936
4937 const jobject jlong_obj =
4938 env->CallStaticObjectMethod(jclazz, mid, jprimitive_long);
4939 if (env->ExceptionCheck()) {
4940 // exception occurred
4941 return nullptr;
4942 }
4943
4944 return jlong_obj;
4945 }
4946};
7c673cae
FG
4947} // namespace rocksdb
4948#endif // JAVA_ROCKSJNI_PORTAL_H_