1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 // This file is designed for caching those frequently used IDs and provide
7 // efficient portal (i.e, a set of static functions) to access java code
8 // from c++.
9 
10 #ifndef JAVA_ROCKSJNI_PORTAL_H_
11 #define JAVA_ROCKSJNI_PORTAL_H_
12 
13 #include <jni.h>
14 
15 #include <algorithm>
16 #include <cstring>
17 #include <functional>
18 #include <iostream>
19 #include <iterator>
20 #include <limits>
21 #include <memory>
22 #include <set>
23 #include <string>
24 #include <type_traits>
25 #include <vector>
26 
27 #include "rocksdb/convenience.h"
28 #include "rocksdb/db.h"
29 #include "rocksdb/filter_policy.h"
30 #include "rocksdb/rate_limiter.h"
31 #include "rocksdb/status.h"
32 #include "rocksdb/table.h"
33 #include "rocksdb/utilities/backupable_db.h"
34 #include "rocksdb/utilities/memory_util.h"
35 #include "rocksdb/utilities/transaction_db.h"
36 #include "rocksdb/utilities/write_batch_with_index.h"
37 #include "rocksjni/compaction_filter_factory_jnicallback.h"
38 #include "rocksjni/comparatorjnicallback.h"
39 #include "rocksjni/event_listener_jnicallback.h"
40 #include "rocksjni/loggerjnicallback.h"
41 #include "rocksjni/table_filter_jnicallback.h"
42 #include "rocksjni/trace_writer_jnicallback.h"
43 #include "rocksjni/transaction_notifier_jnicallback.h"
44 #include "rocksjni/wal_filter_jnicallback.h"
45 #include "rocksjni/writebatchhandlerjnicallback.h"
46 
47 // Remove macro on windows
48 #ifdef DELETE
49 #undef DELETE
50 #endif
51 
52 namespace ROCKSDB_NAMESPACE {
53 
54 class JavaClass {
55  public:
56   /**
57    * Gets and initializes a Java Class
58    *
59    * @param env A pointer to the Java environment
60    * @param jclazz_name The fully qualified JNI name of the Java Class
61    *     e.g. "java/lang/String"
62    *
63    * @return The Java Class or nullptr if one of the
64    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
65    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
66    */
getJClass(JNIEnv * env,const char * jclazz_name)67   static jclass getJClass(JNIEnv* env, const char* jclazz_name) {
68     jclass jclazz = env->FindClass(jclazz_name);
69     assert(jclazz != nullptr);
70     return jclazz;
71   }
72 };
73 
74 // Native class template
75 template<class PTR, class DERIVED> class RocksDBNativeClass : public JavaClass {
76 };
77 
78 // Native class template for sub-classes of RocksMutableObject
79 template<class PTR, class DERIVED> class NativeRocksMutableObject
80     : public RocksDBNativeClass<PTR, DERIVED> {
81  public:
82 
83   /**
84    * Gets the Java Method ID for the
85    * RocksMutableObject#setNativeHandle(long, boolean) method
86    *
87    * @param env A pointer to the Java environment
88    * @return The Java Method ID or nullptr the RocksMutableObject class cannot
89    *     be accessed, or if one of the NoSuchMethodError,
90    *     ExceptionInInitializerError or OutOfMemoryError exceptions is thrown
91    */
getSetNativeHandleMethod(JNIEnv * env)92   static jmethodID getSetNativeHandleMethod(JNIEnv* env) {
93     static jclass jclazz = DERIVED::getJClass(env);
94     if(jclazz == nullptr) {
95       return nullptr;
96     }
97 
98     static jmethodID mid = env->GetMethodID(
99         jclazz, "setNativeHandle", "(JZ)V");
100     assert(mid != nullptr);
101     return mid;
102   }
103 
104   /**
105    * Sets the C++ object pointer handle in the Java object
106    *
107    * @param env A pointer to the Java environment
108    * @param jobj The Java object on which to set the pointer handle
109    * @param ptr The C++ object pointer
110    * @param java_owns_handle JNI_TRUE if ownership of the C++ object is
111    *     managed by the Java object
112    *
113    * @return true if a Java exception is pending, false otherwise
114    */
setHandle(JNIEnv * env,jobject jobj,PTR ptr,jboolean java_owns_handle)115   static bool setHandle(JNIEnv* env, jobject jobj, PTR ptr,
116       jboolean java_owns_handle) {
117     assert(jobj != nullptr);
118     static jmethodID mid = getSetNativeHandleMethod(env);
119     if(mid == nullptr) {
120       return true;  // signal exception
121     }
122 
123     env->CallVoidMethod(jobj, mid, reinterpret_cast<jlong>(ptr), java_owns_handle);
124     if(env->ExceptionCheck()) {
125       return true;  // signal exception
126     }
127 
128     return false;
129   }
130 };
131 
132 // Java Exception template
133 template<class DERIVED> class JavaException : public JavaClass {
134  public:
135   /**
136    * Create and throw a java exception with the provided message
137    *
138    * @param env A pointer to the Java environment
139    * @param msg The message for the exception
140    *
141    * @return true if an exception was thrown, false otherwise
142    */
ThrowNew(JNIEnv * env,const std::string & msg)143   static bool ThrowNew(JNIEnv* env, const std::string& msg) {
144     jclass jclazz = DERIVED::getJClass(env);
145     if(jclazz == nullptr) {
146       // exception occurred accessing class
147       std::cerr << "JavaException::ThrowNew - Error: unexpected exception!" << std::endl;
148       return env->ExceptionCheck();
149     }
150 
151     const jint rs = env->ThrowNew(jclazz, msg.c_str());
152     if(rs != JNI_OK) {
153       // exception could not be thrown
154       std::cerr << "JavaException::ThrowNew - Fatal: could not throw exception!" << std::endl;
155       return env->ExceptionCheck();
156     }
157 
158     return true;
159   }
160 };
161 
162 // The portal class for java.lang.IllegalArgumentException
163 class IllegalArgumentExceptionJni :
164     public JavaException<IllegalArgumentExceptionJni> {
165  public:
166   /**
167    * Get the Java Class java.lang.IllegalArgumentException
168    *
169    * @param env A pointer to the Java environment
170    *
171    * @return The Java Class or nullptr if one of the
172    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
173    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
174    */
getJClass(JNIEnv * env)175   static jclass getJClass(JNIEnv* env) {
176     return JavaException::getJClass(env, "java/lang/IllegalArgumentException");
177   }
178 
179   /**
180    * Create and throw a Java IllegalArgumentException with the provided status
181    *
182    * If s.ok() == true, then this function will not throw any exception.
183    *
184    * @param env A pointer to the Java environment
185    * @param s The status for the exception
186    *
187    * @return true if an exception was thrown, false otherwise
188    */
ThrowNew(JNIEnv * env,const Status & s)189   static bool ThrowNew(JNIEnv* env, const Status& s) {
190     assert(!s.ok());
191     if (s.ok()) {
192       return false;
193     }
194 
195     // get the IllegalArgumentException class
196     jclass jclazz = getJClass(env);
197     if(jclazz == nullptr) {
198       // exception occurred accessing class
199       std::cerr << "IllegalArgumentExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
200       return env->ExceptionCheck();
201     }
202 
203     return JavaException::ThrowNew(env, s.ToString());
204   }
205 };
206 
207 // The portal class for org.rocksdb.Status.Code
208 class CodeJni : public JavaClass {
209  public:
210   /**
211    * Get the Java Class org.rocksdb.Status.Code
212    *
213    * @param env A pointer to the Java environment
214    *
215    * @return The Java Class or nullptr if one of the
216    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
217    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
218    */
getJClass(JNIEnv * env)219   static jclass getJClass(JNIEnv* env) {
220     return JavaClass::getJClass(env, "org/rocksdb/Status$Code");
221   }
222 
223   /**
224    * Get the Java Method: Status.Code#getValue
225    *
226    * @param env A pointer to the Java environment
227    *
228    * @return The Java Method ID or nullptr if the class or method id could not
229    *     be retrieved
230    */
getValueMethod(JNIEnv * env)231   static jmethodID getValueMethod(JNIEnv* env) {
232     jclass jclazz = getJClass(env);
233     if(jclazz == nullptr) {
234       // exception occurred accessing class
235       return nullptr;
236     }
237 
238     static jmethodID mid =
239         env->GetMethodID(jclazz, "getValue", "()b");
240     assert(mid != nullptr);
241     return mid;
242   }
243 };
244 
245 // The portal class for org.rocksdb.Status.SubCode
246 class SubCodeJni : public JavaClass {
247  public:
248   /**
249    * Get the Java Class org.rocksdb.Status.SubCode
250    *
251    * @param env A pointer to the Java environment
252    *
253    * @return The Java Class or nullptr if one of the
254    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
255    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
256    */
getJClass(JNIEnv * env)257   static jclass getJClass(JNIEnv* env) {
258     return JavaClass::getJClass(env, "org/rocksdb/Status$SubCode");
259   }
260 
261   /**
262    * Get the Java Method: Status.SubCode#getValue
263    *
264    * @param env A pointer to the Java environment
265    *
266    * @return The Java Method ID or nullptr if the class or method id could not
267    *     be retrieved
268    */
getValueMethod(JNIEnv * env)269   static jmethodID getValueMethod(JNIEnv* env) {
270     jclass jclazz = getJClass(env);
271     if(jclazz == nullptr) {
272       // exception occurred accessing class
273       return nullptr;
274     }
275 
276     static jmethodID mid =
277         env->GetMethodID(jclazz, "getValue", "()b");
278     assert(mid != nullptr);
279     return mid;
280   }
281 
toCppSubCode(const jbyte jsub_code)282   static ROCKSDB_NAMESPACE::Status::SubCode toCppSubCode(
283       const jbyte jsub_code) {
284     switch (jsub_code) {
285       case 0x0:
286         return ROCKSDB_NAMESPACE::Status::SubCode::kNone;
287       case 0x1:
288         return ROCKSDB_NAMESPACE::Status::SubCode::kMutexTimeout;
289       case 0x2:
290         return ROCKSDB_NAMESPACE::Status::SubCode::kLockTimeout;
291       case 0x3:
292         return ROCKSDB_NAMESPACE::Status::SubCode::kLockLimit;
293       case 0x4:
294         return ROCKSDB_NAMESPACE::Status::SubCode::kNoSpace;
295       case 0x5:
296         return ROCKSDB_NAMESPACE::Status::SubCode::kDeadlock;
297       case 0x6:
298         return ROCKSDB_NAMESPACE::Status::SubCode::kStaleFile;
299       case 0x7:
300         return ROCKSDB_NAMESPACE::Status::SubCode::kMemoryLimit;
301 
302       case 0x7F:
303       default:
304         return ROCKSDB_NAMESPACE::Status::SubCode::kNone;
305     }
306   }
307 };
308 
309 // The portal class for org.rocksdb.Status
310 class StatusJni
311     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::Status*, StatusJni> {
312  public:
313   /**
314    * Get the Java Class org.rocksdb.Status
315    *
316    * @param env A pointer to the Java environment
317    *
318    * @return The Java Class or nullptr if one of the
319    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
320    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
321    */
getJClass(JNIEnv * env)322   static jclass getJClass(JNIEnv* env) {
323     return RocksDBNativeClass::getJClass(env, "org/rocksdb/Status");
324   }
325 
326   /**
327    * Get the Java Method: Status#getCode
328    *
329    * @param env A pointer to the Java environment
330    *
331    * @return The Java Method ID or nullptr if the class or method id could not
332    *     be retrieved
333    */
getCodeMethod(JNIEnv * env)334   static jmethodID getCodeMethod(JNIEnv* env) {
335     jclass jclazz = getJClass(env);
336     if(jclazz == nullptr) {
337       // exception occurred accessing class
338       return nullptr;
339     }
340 
341     static jmethodID mid =
342         env->GetMethodID(jclazz, "getCode", "()Lorg/rocksdb/Status$Code;");
343     assert(mid != nullptr);
344     return mid;
345   }
346 
347   /**
348    * Get the Java Method: Status#getSubCode
349    *
350    * @param env A pointer to the Java environment
351    *
352    * @return The Java Method ID or nullptr if the class or method id could not
353    *     be retrieved
354    */
getSubCodeMethod(JNIEnv * env)355   static jmethodID getSubCodeMethod(JNIEnv* env) {
356     jclass jclazz = getJClass(env);
357     if(jclazz == nullptr) {
358       // exception occurred accessing class
359       return nullptr;
360     }
361 
362     static jmethodID mid =
363         env->GetMethodID(jclazz, "getSubCode", "()Lorg/rocksdb/Status$SubCode;");
364     assert(mid != nullptr);
365     return mid;
366   }
367 
368   /**
369    * Get the Java Method: Status#getState
370    *
371    * @param env A pointer to the Java environment
372    *
373    * @return The Java Method ID or nullptr if the class or method id could not
374    *     be retrieved
375    */
getStateMethod(JNIEnv * env)376   static jmethodID getStateMethod(JNIEnv* env) {
377     jclass jclazz = getJClass(env);
378     if(jclazz == nullptr) {
379       // exception occurred accessing class
380       return nullptr;
381     }
382 
383     static jmethodID mid =
384         env->GetMethodID(jclazz, "getState", "()Ljava/lang/String;");
385     assert(mid != nullptr);
386     return mid;
387   }
388 
389   /**
390    * Create a new Java org.rocksdb.Status object with the same properties as
391    * the provided C++ ROCKSDB_NAMESPACE::Status object
392    *
393    * @param env A pointer to the Java environment
394    * @param status The ROCKSDB_NAMESPACE::Status object
395    *
396    * @return A reference to a Java org.rocksdb.Status object, or nullptr
397    *     if an an exception occurs
398    */
construct(JNIEnv * env,const Status & status)399   static jobject construct(JNIEnv* env, const Status& status) {
400     jclass jclazz = getJClass(env);
401     if(jclazz == nullptr) {
402       // exception occurred accessing class
403       return nullptr;
404     }
405 
406     jmethodID mid =
407         env->GetMethodID(jclazz, "<init>", "(BBLjava/lang/String;)V");
408     if(mid == nullptr) {
409       // exception thrown: NoSuchMethodException or OutOfMemoryError
410       return nullptr;
411     }
412 
413     // convert the Status state for Java
414     jstring jstate = nullptr;
415     if (status.getState() != nullptr) {
416       const char* const state = status.getState();
417       jstate = env->NewStringUTF(state);
418       if(env->ExceptionCheck()) {
419         if(jstate != nullptr) {
420           env->DeleteLocalRef(jstate);
421         }
422         return nullptr;
423       }
424     }
425 
426     jobject jstatus =
427         env->NewObject(jclazz, mid, toJavaStatusCode(status.code()),
428             toJavaStatusSubCode(status.subcode()), jstate);
429     if(env->ExceptionCheck()) {
430       // exception occurred
431       if(jstate != nullptr) {
432         env->DeleteLocalRef(jstate);
433       }
434       return nullptr;
435     }
436 
437     if(jstate != nullptr) {
438       env->DeleteLocalRef(jstate);
439     }
440 
441     return jstatus;
442   }
443 
construct(JNIEnv * env,const Status * status)444   static jobject construct(JNIEnv* env, const Status* status) {
445     return construct(env, *status);
446   }
447 
448   // Returns the equivalent org.rocksdb.Status.Code for the provided
449   // C++ ROCKSDB_NAMESPACE::Status::Code enum
toJavaStatusCode(const ROCKSDB_NAMESPACE::Status::Code & code)450   static jbyte toJavaStatusCode(const ROCKSDB_NAMESPACE::Status::Code& code) {
451     switch (code) {
452       case ROCKSDB_NAMESPACE::Status::Code::kOk:
453         return 0x0;
454       case ROCKSDB_NAMESPACE::Status::Code::kNotFound:
455         return 0x1;
456       case ROCKSDB_NAMESPACE::Status::Code::kCorruption:
457         return 0x2;
458       case ROCKSDB_NAMESPACE::Status::Code::kNotSupported:
459         return 0x3;
460       case ROCKSDB_NAMESPACE::Status::Code::kInvalidArgument:
461         return 0x4;
462       case ROCKSDB_NAMESPACE::Status::Code::kIOError:
463         return 0x5;
464       case ROCKSDB_NAMESPACE::Status::Code::kMergeInProgress:
465         return 0x6;
466       case ROCKSDB_NAMESPACE::Status::Code::kIncomplete:
467         return 0x7;
468       case ROCKSDB_NAMESPACE::Status::Code::kShutdownInProgress:
469         return 0x8;
470       case ROCKSDB_NAMESPACE::Status::Code::kTimedOut:
471         return 0x9;
472       case ROCKSDB_NAMESPACE::Status::Code::kAborted:
473         return 0xA;
474       case ROCKSDB_NAMESPACE::Status::Code::kBusy:
475         return 0xB;
476       case ROCKSDB_NAMESPACE::Status::Code::kExpired:
477         return 0xC;
478       case ROCKSDB_NAMESPACE::Status::Code::kTryAgain:
479         return 0xD;
480       case ROCKSDB_NAMESPACE::Status::Code::kColumnFamilyDropped:
481         return 0xE;
482       default:
483         return 0x7F;  // undefined
484     }
485   }
486 
487   // Returns the equivalent org.rocksdb.Status.SubCode for the provided
488   // C++ ROCKSDB_NAMESPACE::Status::SubCode enum
toJavaStatusSubCode(const ROCKSDB_NAMESPACE::Status::SubCode & subCode)489   static jbyte toJavaStatusSubCode(
490       const ROCKSDB_NAMESPACE::Status::SubCode& subCode) {
491     switch (subCode) {
492       case ROCKSDB_NAMESPACE::Status::SubCode::kNone:
493         return 0x0;
494       case ROCKSDB_NAMESPACE::Status::SubCode::kMutexTimeout:
495         return 0x1;
496       case ROCKSDB_NAMESPACE::Status::SubCode::kLockTimeout:
497         return 0x2;
498       case ROCKSDB_NAMESPACE::Status::SubCode::kLockLimit:
499         return 0x3;
500       case ROCKSDB_NAMESPACE::Status::SubCode::kNoSpace:
501         return 0x4;
502       case ROCKSDB_NAMESPACE::Status::SubCode::kDeadlock:
503         return 0x5;
504       case ROCKSDB_NAMESPACE::Status::SubCode::kStaleFile:
505         return 0x6;
506       case ROCKSDB_NAMESPACE::Status::SubCode::kMemoryLimit:
507         return 0x7;
508       default:
509         return 0x7F;  // undefined
510     }
511   }
512 
toCppStatus(const jbyte jcode_value,const jbyte jsub_code_value)513   static std::unique_ptr<ROCKSDB_NAMESPACE::Status> toCppStatus(
514       const jbyte jcode_value, const jbyte jsub_code_value) {
515     std::unique_ptr<ROCKSDB_NAMESPACE::Status> status;
516     switch (jcode_value) {
517       case 0x0:
518         //Ok
519         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
520             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::OK()));
521         break;
522       case 0x1:
523         //NotFound
524         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
525             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::NotFound(
526                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
527         break;
528       case 0x2:
529         //Corruption
530         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
531             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::Corruption(
532                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
533         break;
534       case 0x3:
535         //NotSupported
536         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
537             new ROCKSDB_NAMESPACE::Status(
538                 ROCKSDB_NAMESPACE::Status::NotSupported(
539                     ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(
540                         jsub_code_value))));
541         break;
542       case 0x4:
543         //InvalidArgument
544         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
545             new ROCKSDB_NAMESPACE::Status(
546                 ROCKSDB_NAMESPACE::Status::InvalidArgument(
547                     ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(
548                         jsub_code_value))));
549         break;
550       case 0x5:
551         //IOError
552         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
553             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::IOError(
554                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
555         break;
556       case 0x6:
557         //MergeInProgress
558         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
559             new ROCKSDB_NAMESPACE::Status(
560                 ROCKSDB_NAMESPACE::Status::MergeInProgress(
561                     ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(
562                         jsub_code_value))));
563         break;
564       case 0x7:
565         //Incomplete
566         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
567             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::Incomplete(
568                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
569         break;
570       case 0x8:
571         //ShutdownInProgress
572         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
573             new ROCKSDB_NAMESPACE::Status(
574                 ROCKSDB_NAMESPACE::Status::ShutdownInProgress(
575                     ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(
576                         jsub_code_value))));
577         break;
578       case 0x9:
579         //TimedOut
580         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
581             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::TimedOut(
582                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
583         break;
584       case 0xA:
585         //Aborted
586         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
587             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::Aborted(
588                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
589         break;
590       case 0xB:
591         //Busy
592         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
593             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::Busy(
594                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
595         break;
596       case 0xC:
597         //Expired
598         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
599             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::Expired(
600                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
601         break;
602       case 0xD:
603         //TryAgain
604         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
605             new ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Status::TryAgain(
606                 ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(jsub_code_value))));
607         break;
608       case 0xE:
609         // ColumnFamilyDropped
610         status = std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
611             new ROCKSDB_NAMESPACE::Status(
612                 ROCKSDB_NAMESPACE::Status::ColumnFamilyDropped(
613                     ROCKSDB_NAMESPACE::SubCodeJni::toCppSubCode(
614                         jsub_code_value))));
615         break;
616       case 0x7F:
617       default:
618         return nullptr;
619     }
620     return status;
621   }
622 
623   // Returns the equivalent ROCKSDB_NAMESPACE::Status for the Java
624   // org.rocksdb.Status
toCppStatus(JNIEnv * env,const jobject jstatus)625   static std::unique_ptr<ROCKSDB_NAMESPACE::Status> toCppStatus(
626       JNIEnv* env, const jobject jstatus) {
627     jmethodID mid_code = getCodeMethod(env);
628     if (mid_code == nullptr) {
629       // exception occurred
630       return nullptr;
631     }
632     jobject jcode = env->CallObjectMethod(jstatus, mid_code);
633     if (env->ExceptionCheck()) {
634       // exception occurred
635       return nullptr;
636     }
637 
638     jmethodID mid_code_value = ROCKSDB_NAMESPACE::CodeJni::getValueMethod(env);
639     if (mid_code_value == nullptr) {
640       // exception occurred
641       return nullptr;
642     }
643     jbyte jcode_value = env->CallByteMethod(jcode, mid_code_value);
644     if (env->ExceptionCheck()) {
645       // exception occurred
646       if (jcode != nullptr) {
647         env->DeleteLocalRef(jcode);
648       }
649       return nullptr;
650     }
651 
652     jmethodID mid_subCode = getSubCodeMethod(env);
653     if (mid_subCode == nullptr) {
654       // exception occurred
655       return nullptr;
656     }
657     jobject jsubCode = env->CallObjectMethod(jstatus, mid_subCode);
658     if (env->ExceptionCheck()) {
659       // exception occurred
660       if (jcode != nullptr) {
661         env->DeleteLocalRef(jcode);
662       }
663       return nullptr;
664     }
665 
666     jbyte jsub_code_value = 0x0;  // None
667     if (jsubCode != nullptr) {
668       jmethodID mid_subCode_value =
669           ROCKSDB_NAMESPACE::SubCodeJni::getValueMethod(env);
670       if (mid_subCode_value == nullptr) {
671         // exception occurred
672         return nullptr;
673       }
674       jsub_code_value = env->CallByteMethod(jsubCode, mid_subCode_value);
675       if (env->ExceptionCheck()) {
676         // exception occurred
677         if (jcode != nullptr) {
678           env->DeleteLocalRef(jcode);
679         }
680         return nullptr;
681       }
682     }
683 
684     jmethodID mid_state = getStateMethod(env);
685     if (mid_state == nullptr) {
686       // exception occurred
687       return nullptr;
688     }
689     jobject jstate = env->CallObjectMethod(jstatus, mid_state);
690     if (env->ExceptionCheck()) {
691       // exception occurred
692       if (jsubCode != nullptr) {
693         env->DeleteLocalRef(jsubCode);
694       }
695       if (jcode != nullptr) {
696         env->DeleteLocalRef(jcode);
697       }
698       return nullptr;
699     }
700 
701     std::unique_ptr<ROCKSDB_NAMESPACE::Status> status =
702         toCppStatus(jcode_value, jsub_code_value);
703 
704     // delete all local refs
705     if (jstate != nullptr) {
706       env->DeleteLocalRef(jstate);
707     }
708     if (jsubCode != nullptr) {
709       env->DeleteLocalRef(jsubCode);
710     }
711     if (jcode != nullptr) {
712       env->DeleteLocalRef(jcode);
713     }
714 
715     return status;
716   }
717 };
718 
719 // The portal class for org.rocksdb.RocksDBException
720 class RocksDBExceptionJni :
721     public JavaException<RocksDBExceptionJni> {
722  public:
723   /**
724    * Get the Java Class org.rocksdb.RocksDBException
725    *
726    * @param env A pointer to the Java environment
727    *
728    * @return The Java Class or nullptr if one of the
729    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
730    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
731    */
getJClass(JNIEnv * env)732   static jclass getJClass(JNIEnv* env) {
733     return JavaException::getJClass(env, "org/rocksdb/RocksDBException");
734   }
735 
736   /**
737    * Create and throw a Java RocksDBException with the provided message
738    *
739    * @param env A pointer to the Java environment
740    * @param msg The message for the exception
741    *
742    * @return true if an exception was thrown, false otherwise
743    */
ThrowNew(JNIEnv * env,const std::string & msg)744   static bool ThrowNew(JNIEnv* env, const std::string& msg) {
745     return JavaException::ThrowNew(env, msg);
746   }
747 
748   /**
749    * Create and throw a Java RocksDBException with the provided status
750    *
751    * If s->ok() == true, then this function will not throw any exception.
752    *
753    * @param env A pointer to the Java environment
754    * @param s The status for the exception
755    *
756    * @return true if an exception was thrown, false otherwise
757    */
ThrowNew(JNIEnv * env,std::unique_ptr<Status> & s)758   static bool ThrowNew(JNIEnv* env, std::unique_ptr<Status>& s) {
759     return ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, *(s.get()));
760   }
761 
762   /**
763    * Create and throw a Java RocksDBException with the provided status
764    *
765    * If s.ok() == true, then this function will not throw any exception.
766    *
767    * @param env A pointer to the Java environment
768    * @param s The status for the exception
769    *
770    * @return true if an exception was thrown, false otherwise
771    */
ThrowNew(JNIEnv * env,const Status & s)772   static bool ThrowNew(JNIEnv* env, const Status& s) {
773     if (s.ok()) {
774       return false;
775     }
776 
777     // get the RocksDBException class
778     jclass jclazz = getJClass(env);
779     if(jclazz == nullptr) {
780       // exception occurred accessing class
781       std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
782       return env->ExceptionCheck();
783     }
784 
785     // get the constructor of org.rocksdb.RocksDBException
786     jmethodID mid =
787         env->GetMethodID(jclazz, "<init>", "(Lorg/rocksdb/Status;)V");
788     if(mid == nullptr) {
789       // exception thrown: NoSuchMethodException or OutOfMemoryError
790       std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
791       return env->ExceptionCheck();
792     }
793 
794     // get the Java status object
795     jobject jstatus = StatusJni::construct(env, s);
796     if(jstatus == nullptr) {
797       // exception occcurred
798       std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
799       return env->ExceptionCheck();
800     }
801 
802     // construct the RocksDBException
803     jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jstatus));
804     if(env->ExceptionCheck()) {
805       if(jstatus != nullptr) {
806         env->DeleteLocalRef(jstatus);
807       }
808       if(rocksdb_exception != nullptr) {
809         env->DeleteLocalRef(rocksdb_exception);
810       }
811       std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
812       return true;
813     }
814 
815     // throw the RocksDBException
816     const jint rs = env->Throw(rocksdb_exception);
817     if(rs != JNI_OK) {
818       // exception could not be thrown
819       std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
820       if(jstatus != nullptr) {
821         env->DeleteLocalRef(jstatus);
822       }
823       if(rocksdb_exception != nullptr) {
824         env->DeleteLocalRef(rocksdb_exception);
825       }
826       return env->ExceptionCheck();
827     }
828 
829     if(jstatus != nullptr) {
830       env->DeleteLocalRef(jstatus);
831     }
832     if(rocksdb_exception != nullptr) {
833       env->DeleteLocalRef(rocksdb_exception);
834     }
835 
836     return true;
837   }
838 
839   /**
840    * Create and throw a Java RocksDBException with the provided message
841    * and status
842    *
843    * If s.ok() == true, then this function will not throw any exception.
844    *
845    * @param env A pointer to the Java environment
846    * @param msg The message for the exception
847    * @param s The status for the exception
848    *
849    * @return true if an exception was thrown, false otherwise
850    */
ThrowNew(JNIEnv * env,const std::string & msg,const Status & s)851   static bool ThrowNew(JNIEnv* env, const std::string& msg, const Status& s) {
852     assert(!s.ok());
853     if (s.ok()) {
854       return false;
855     }
856 
857     // get the RocksDBException class
858     jclass jclazz = getJClass(env);
859     if(jclazz == nullptr) {
860       // exception occurred accessing class
861       std::cerr << "RocksDBExceptionJni::ThrowNew/class - Error: unexpected exception!" << std::endl;
862       return env->ExceptionCheck();
863     }
864 
865     // get the constructor of org.rocksdb.RocksDBException
866     jmethodID mid =
867         env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;Lorg/rocksdb/Status;)V");
868     if(mid == nullptr) {
869       // exception thrown: NoSuchMethodException or OutOfMemoryError
870       std::cerr << "RocksDBExceptionJni::ThrowNew/cstr - Error: unexpected exception!" << std::endl;
871       return env->ExceptionCheck();
872     }
873 
874     jstring jmsg = env->NewStringUTF(msg.c_str());
875     if(jmsg == nullptr) {
876       // exception thrown: OutOfMemoryError
877       std::cerr << "RocksDBExceptionJni::ThrowNew/msg - Error: unexpected exception!" << std::endl;
878       return env->ExceptionCheck();
879     }
880 
881     // get the Java status object
882     jobject jstatus = StatusJni::construct(env, s);
883     if(jstatus == nullptr) {
884       // exception occcurred
885       std::cerr << "RocksDBExceptionJni::ThrowNew/StatusJni - Error: unexpected exception!" << std::endl;
886       if(jmsg != nullptr) {
887         env->DeleteLocalRef(jmsg);
888       }
889       return env->ExceptionCheck();
890     }
891 
892     // construct the RocksDBException
893     jthrowable rocksdb_exception = reinterpret_cast<jthrowable>(env->NewObject(jclazz, mid, jmsg, jstatus));
894     if(env->ExceptionCheck()) {
895       if(jstatus != nullptr) {
896         env->DeleteLocalRef(jstatus);
897       }
898       if(jmsg != nullptr) {
899         env->DeleteLocalRef(jmsg);
900       }
901       if(rocksdb_exception != nullptr) {
902         env->DeleteLocalRef(rocksdb_exception);
903       }
904       std::cerr << "RocksDBExceptionJni::ThrowNew/NewObject - Error: unexpected exception!" << std::endl;
905       return true;
906     }
907 
908     // throw the RocksDBException
909     const jint rs = env->Throw(rocksdb_exception);
910     if(rs != JNI_OK) {
911       // exception could not be thrown
912       std::cerr << "RocksDBExceptionJni::ThrowNew - Fatal: could not throw exception!" << std::endl;
913       if(jstatus != nullptr) {
914         env->DeleteLocalRef(jstatus);
915       }
916       if(jmsg != nullptr) {
917         env->DeleteLocalRef(jmsg);
918       }
919       if(rocksdb_exception != nullptr) {
920         env->DeleteLocalRef(rocksdb_exception);
921       }
922       return env->ExceptionCheck();
923     }
924 
925     if(jstatus != nullptr) {
926       env->DeleteLocalRef(jstatus);
927     }
928     if(jmsg != nullptr) {
929       env->DeleteLocalRef(jmsg);
930     }
931     if(rocksdb_exception != nullptr) {
932       env->DeleteLocalRef(rocksdb_exception);
933     }
934 
935     return true;
936   }
937 
938   /**
939    * Get the Java Method: RocksDBException#getStatus
940    *
941    * @param env A pointer to the Java environment
942    *
943    * @return The Java Method ID or nullptr if the class or method id could not
944    *     be retrieved
945    */
getStatusMethod(JNIEnv * env)946   static jmethodID getStatusMethod(JNIEnv* env) {
947     jclass jclazz = getJClass(env);
948     if(jclazz == nullptr) {
949       // exception occurred accessing class
950       return nullptr;
951     }
952 
953     static jmethodID mid =
954         env->GetMethodID(jclazz, "getStatus", "()Lorg/rocksdb/Status;");
955     assert(mid != nullptr);
956     return mid;
957   }
958 
toCppStatus(JNIEnv * env,jthrowable jrocksdb_exception)959   static std::unique_ptr<ROCKSDB_NAMESPACE::Status> toCppStatus(
960       JNIEnv* env, jthrowable jrocksdb_exception) {
961     if(!env->IsInstanceOf(jrocksdb_exception, getJClass(env))) {
962       // not an instance of RocksDBException
963       return nullptr;
964     }
965 
966     // get the java status object
967     jmethodID mid = getStatusMethod(env);
968     if(mid == nullptr) {
969       // exception occurred accessing class or method
970       return nullptr;
971     }
972 
973     jobject jstatus = env->CallObjectMethod(jrocksdb_exception, mid);
974     if(env->ExceptionCheck()) {
975       // exception occurred
976       return nullptr;
977     }
978 
979     if(jstatus == nullptr) {
980       return nullptr;   // no status available
981     }
982 
983     return ROCKSDB_NAMESPACE::StatusJni::toCppStatus(env, jstatus);
984   }
985 };
986 
987 // The portal class for java.util.List
988 class ListJni : public JavaClass {
989  public:
990   /**
991    * Get the Java Class java.util.List
992    *
993    * @param env A pointer to the Java environment
994    *
995    * @return The Java Class or nullptr if one of the
996    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
997    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
998    */
getListClass(JNIEnv * env)999   static jclass getListClass(JNIEnv* env) {
1000     return JavaClass::getJClass(env, "java/util/List");
1001   }
1002 
1003   /**
1004    * Get the Java Class java.util.ArrayList
1005    *
1006    * @param env A pointer to the Java environment
1007    *
1008    * @return The Java Class or nullptr if one of the
1009    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1010    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1011    */
getArrayListClass(JNIEnv * env)1012   static jclass getArrayListClass(JNIEnv* env) {
1013     return JavaClass::getJClass(env, "java/util/ArrayList");
1014   }
1015 
1016   /**
1017    * Get the Java Class java.util.Iterator
1018    *
1019    * @param env A pointer to the Java environment
1020    *
1021    * @return The Java Class or nullptr if one of the
1022    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1023    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1024    */
getIteratorClass(JNIEnv * env)1025   static jclass getIteratorClass(JNIEnv* env) {
1026     return JavaClass::getJClass(env, "java/util/Iterator");
1027   }
1028 
1029   /**
1030    * Get the Java Method: List#iterator
1031    *
1032    * @param env A pointer to the Java environment
1033    *
1034    * @return The Java Method ID or nullptr if the class or method id could not
1035    *     be retrieved
1036    */
getIteratorMethod(JNIEnv * env)1037   static jmethodID getIteratorMethod(JNIEnv* env) {
1038     jclass jlist_clazz = getListClass(env);
1039     if(jlist_clazz == nullptr) {
1040       // exception occurred accessing class
1041       return nullptr;
1042     }
1043 
1044     static jmethodID mid =
1045         env->GetMethodID(jlist_clazz, "iterator", "()Ljava/util/Iterator;");
1046     assert(mid != nullptr);
1047     return mid;
1048   }
1049 
1050   /**
1051    * Get the Java Method: Iterator#hasNext
1052    *
1053    * @param env A pointer to the Java environment
1054    *
1055    * @return The Java Method ID or nullptr if the class or method id could not
1056    *     be retrieved
1057    */
getHasNextMethod(JNIEnv * env)1058   static jmethodID getHasNextMethod(JNIEnv* env) {
1059     jclass jiterator_clazz = getIteratorClass(env);
1060     if(jiterator_clazz == nullptr) {
1061       // exception occurred accessing class
1062       return nullptr;
1063     }
1064 
1065     static jmethodID mid = env->GetMethodID(jiterator_clazz, "hasNext", "()Z");
1066     assert(mid != nullptr);
1067     return mid;
1068   }
1069 
1070   /**
1071    * Get the Java Method: Iterator#next
1072    *
1073    * @param env A pointer to the Java environment
1074    *
1075    * @return The Java Method ID or nullptr if the class or method id could not
1076    *     be retrieved
1077    */
getNextMethod(JNIEnv * env)1078   static jmethodID getNextMethod(JNIEnv* env) {
1079     jclass jiterator_clazz = getIteratorClass(env);
1080     if(jiterator_clazz == nullptr) {
1081       // exception occurred accessing class
1082       return nullptr;
1083     }
1084 
1085     static jmethodID mid =
1086         env->GetMethodID(jiterator_clazz, "next", "()Ljava/lang/Object;");
1087     assert(mid != nullptr);
1088     return mid;
1089   }
1090 
1091   /**
1092    * Get the Java Method: ArrayList constructor
1093    *
1094    * @param env A pointer to the Java environment
1095    *
1096    * @return The Java Method ID or nullptr if the class or method id could not
1097    *     be retrieved
1098    */
getArrayListConstructorMethodId(JNIEnv * env)1099   static jmethodID getArrayListConstructorMethodId(JNIEnv* env) {
1100     jclass jarray_list_clazz = getArrayListClass(env);
1101     if(jarray_list_clazz == nullptr) {
1102       // exception occurred accessing class
1103       return nullptr;
1104     }
1105     static jmethodID mid =
1106         env->GetMethodID(jarray_list_clazz, "<init>", "(I)V");
1107     assert(mid != nullptr);
1108     return mid;
1109   }
1110 
1111   /**
1112    * Get the Java Method: List#add
1113    *
1114    * @param env A pointer to the Java environment
1115    *
1116    * @return The Java Method ID or nullptr if the class or method id could not
1117    *     be retrieved
1118    */
getListAddMethodId(JNIEnv * env)1119   static jmethodID getListAddMethodId(JNIEnv* env) {
1120     jclass jlist_clazz = getListClass(env);
1121     if(jlist_clazz == nullptr) {
1122       // exception occurred accessing class
1123       return nullptr;
1124     }
1125 
1126     static jmethodID mid =
1127         env->GetMethodID(jlist_clazz, "add", "(Ljava/lang/Object;)Z");
1128     assert(mid != nullptr);
1129     return mid;
1130   }
1131 };
1132 
1133 // The portal class for java.lang.Byte
1134 class ByteJni : public JavaClass {
1135  public:
1136   /**
1137    * Get the Java Class java.lang.Byte
1138    *
1139    * @param env A pointer to the Java environment
1140    *
1141    * @return The Java Class or nullptr if one of the
1142    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1143    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1144    */
getJClass(JNIEnv * env)1145   static jclass getJClass(JNIEnv* env) {
1146     return JavaClass::getJClass(env, "java/lang/Byte");
1147   }
1148 
1149   /**
1150    * Get the Java Class byte[]
1151    *
1152    * @param env A pointer to the Java environment
1153    *
1154    * @return The Java Class or nullptr if one of the
1155    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1156    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1157    */
getArrayJClass(JNIEnv * env)1158   static jclass getArrayJClass(JNIEnv* env) {
1159     return JavaClass::getJClass(env, "[B");
1160   }
1161 
1162   /**
1163    * Creates a new 2-dimensional Java Byte Array byte[][]
1164    *
1165    * @param env A pointer to the Java environment
1166    * @param len The size of the first dimension
1167    *
1168    * @return A reference to the Java byte[][] or nullptr if an exception occurs
1169    */
new2dByteArray(JNIEnv * env,const jsize len)1170   static jobjectArray new2dByteArray(JNIEnv* env, const jsize len) {
1171     jclass clazz = getArrayJClass(env);
1172     if(clazz == nullptr) {
1173       // exception occurred accessing class
1174       return nullptr;
1175     }
1176 
1177     return env->NewObjectArray(len, clazz, nullptr);
1178   }
1179 
1180   /**
1181    * Get the Java Method: Byte#byteValue
1182    *
1183    * @param env A pointer to the Java environment
1184    *
1185    * @return The Java Method ID or nullptr if the class or method id could not
1186    *     be retrieved
1187    */
getByteValueMethod(JNIEnv * env)1188   static jmethodID getByteValueMethod(JNIEnv* env) {
1189     jclass clazz = getJClass(env);
1190     if(clazz == nullptr) {
1191       // exception occurred accessing class
1192       return nullptr;
1193     }
1194 
1195     static jmethodID mid = env->GetMethodID(clazz, "byteValue", "()B");
1196     assert(mid != nullptr);
1197     return mid;
1198   }
1199 
1200   /**
1201    * Calls the Java Method: Byte#valueOf, returning a constructed Byte jobject
1202    *
1203    * @param env A pointer to the Java environment
1204    *
1205    * @return A constructing Byte object or nullptr if the class or method id could not
1206    *     be retrieved, or an exception occurred
1207    */
valueOf(JNIEnv * env,jbyte jprimitive_byte)1208   static jobject valueOf(JNIEnv* env, jbyte jprimitive_byte) {
1209     jclass clazz = getJClass(env);
1210     if (clazz == nullptr) {
1211       // exception occurred accessing class
1212       return nullptr;
1213     }
1214 
1215     static jmethodID mid =
1216         env->GetStaticMethodID(clazz, "valueOf", "(B)Ljava/lang/Byte;");
1217     if (mid == nullptr) {
1218       // exception thrown: NoSuchMethodException or OutOfMemoryError
1219       return nullptr;
1220     }
1221 
1222     const jobject jbyte_obj =
1223         env->CallStaticObjectMethod(clazz, mid, jprimitive_byte);
1224     if (env->ExceptionCheck()) {
1225       // exception occurred
1226       return nullptr;
1227     }
1228 
1229     return jbyte_obj;
1230   }
1231 
1232 };
1233 
1234 // The portal class for java.nio.ByteBuffer
1235 class ByteBufferJni : public JavaClass {
1236  public:
1237   /**
1238    * Get the Java Class java.nio.ByteBuffer
1239    *
1240    * @param env A pointer to the Java environment
1241    *
1242    * @return The Java Class or nullptr if one of the
1243    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1244    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1245    */
getJClass(JNIEnv * env)1246   static jclass getJClass(JNIEnv* env) {
1247     return JavaClass::getJClass(env, "java/nio/ByteBuffer");
1248   }
1249 
1250   /**
1251    * Get the Java Method: ByteBuffer#allocate
1252    *
1253    * @param env A pointer to the Java environment
1254    * @param jbytebuffer_clazz if you have a reference to a ByteBuffer class, or
1255    * nullptr
1256    *
1257    * @return The Java Method ID or nullptr if the class or method id could not
1258    *     be retrieved
1259    */
1260   static jmethodID getAllocateMethodId(JNIEnv* env,
1261       jclass jbytebuffer_clazz = nullptr) {
1262     const jclass jclazz =
getJClass(env)1263         jbytebuffer_clazz == nullptr ? getJClass(env) : jbytebuffer_clazz;
1264     if (jclazz == nullptr) {
1265       // exception occurred accessing class
1266       return nullptr;
1267     }
1268 
1269     static jmethodID mid = env->GetStaticMethodID(
1270         jclazz, "allocate", "(I)Ljava/nio/ByteBuffer;");
1271     assert(mid != nullptr);
1272     return mid;
1273   }
1274 
1275   /**
1276    * Get the Java Method: ByteBuffer#array
1277    *
1278    * @param env A pointer to the Java environment
1279    *
1280    * @return The Java Method ID or nullptr if the class or method id could not
1281    *     be retrieved
1282    */
1283   static jmethodID getArrayMethodId(JNIEnv* env,
1284       jclass jbytebuffer_clazz = nullptr) {
1285     const jclass jclazz =
getJClass(env)1286         jbytebuffer_clazz == nullptr ? getJClass(env) : jbytebuffer_clazz;
1287     if(jclazz == nullptr) {
1288       // exception occurred accessing class
1289       return nullptr;
1290     }
1291 
1292     static jmethodID mid = env->GetMethodID(jclazz, "array", "()[B");
1293     assert(mid != nullptr);
1294     return mid;
1295   }
1296 
1297   static jobject construct(
1298       JNIEnv* env, const bool direct, const size_t capacity,
1299       jclass jbytebuffer_clazz = nullptr) {
1300     return constructWith(env, direct, nullptr, capacity, jbytebuffer_clazz);
1301   }
1302 
1303   static jobject constructWith(JNIEnv* env, const bool direct, const char* buf,
1304                                const size_t capacity,
1305                                jclass jbytebuffer_clazz = nullptr) {
1306     if (direct) {
1307       bool allocated = false;
1308       if (buf == nullptr) {
1309         buf = new char[capacity];
1310         allocated = true;
1311       }
1312       jobject jbuf = env->NewDirectByteBuffer(const_cast<char*>(buf), static_cast<jlong>(capacity));
1313       if (jbuf == nullptr) {
1314         // exception occurred
1315         if (allocated) {
1316           delete[] static_cast<const char*>(buf);
1317         }
1318         return nullptr;
1319       }
1320       return jbuf;
1321     } else {
1322       const jclass jclazz =
getJClass(env)1323         jbytebuffer_clazz == nullptr ? getJClass(env) : jbytebuffer_clazz;
1324       if (jclazz == nullptr) {
1325         // exception occurred accessing class
1326         return nullptr;
1327       }
1328       const jmethodID jmid_allocate = getAllocateMethodId(env, jbytebuffer_clazz);
1329       if (jmid_allocate == nullptr) {
1330         // exception occurred accessing class, or NoSuchMethodException or OutOfMemoryError
1331         return nullptr;
1332       }
1333       const jobject jbuf = env->CallStaticObjectMethod(
1334           jclazz, jmid_allocate, static_cast<jint>(capacity));
1335       if (env->ExceptionCheck()) {
1336         // exception occurred
1337         return nullptr;
1338       }
1339 
1340       // set buffer data?
1341       if (buf != nullptr) {
1342         jbyteArray jarray = array(env, jbuf, jbytebuffer_clazz);
1343         if (jarray == nullptr) {
1344           // exception occurred
1345           env->DeleteLocalRef(jbuf);
1346           return nullptr;
1347         }
1348 
1349         jboolean is_copy = JNI_FALSE;
1350         jbyte* ja = reinterpret_cast<jbyte*>(
1351             env->GetPrimitiveArrayCritical(jarray, &is_copy));
1352         if (ja == nullptr) {
1353           // exception occurred
1354            env->DeleteLocalRef(jarray);
1355            env->DeleteLocalRef(jbuf);
1356            return nullptr;
1357         }
1358 
1359         memcpy(ja, const_cast<char*>(buf), capacity);
1360 
1361         env->ReleasePrimitiveArrayCritical(jarray, ja, 0);
1362 
1363         env->DeleteLocalRef(jarray);
1364       }
1365 
1366       return jbuf;
1367     }
1368   }
1369 
1370   static jbyteArray array(JNIEnv* env, const jobject& jbyte_buffer,
1371       jclass jbytebuffer_clazz = nullptr) {
1372     const jmethodID mid = getArrayMethodId(env, jbytebuffer_clazz);
1373     if (mid == nullptr) {
1374       // exception occurred accessing class, or NoSuchMethodException or OutOfMemoryError
1375       return nullptr;
1376     }
1377     const jobject jarray = env->CallObjectMethod(jbyte_buffer, mid);
1378     if (env->ExceptionCheck()) {
1379       // exception occurred
1380       return nullptr;
1381     }
1382     return static_cast<jbyteArray>(jarray);
1383   }
1384 };
1385 
1386 // The portal class for java.lang.Integer
1387 class IntegerJni : public JavaClass {
1388  public:
1389   /**
1390    * Get the Java Class java.lang.Integer
1391    *
1392    * @param env A pointer to the Java environment
1393    *
1394    * @return The Java Class or nullptr if one of the
1395    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1396    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1397    */
getJClass(JNIEnv * env)1398   static jclass getJClass(JNIEnv* env) {
1399     return JavaClass::getJClass(env, "java/lang/Integer");
1400   }
1401 
valueOf(JNIEnv * env,jint jprimitive_int)1402   static jobject valueOf(JNIEnv* env, jint jprimitive_int) {
1403     jclass jclazz = getJClass(env);
1404     if (jclazz == nullptr) {
1405       // exception occurred accessing class
1406       return nullptr;
1407     }
1408 
1409     jmethodID mid =
1410         env->GetStaticMethodID(jclazz, "valueOf", "(I)Ljava/lang/Integer;");
1411     if (mid == nullptr) {
1412       // exception thrown: NoSuchMethodException or OutOfMemoryError
1413       return nullptr;
1414     }
1415 
1416     const jobject jinteger_obj =
1417         env->CallStaticObjectMethod(jclazz, mid, jprimitive_int);
1418     if (env->ExceptionCheck()) {
1419       // exception occurred
1420       return nullptr;
1421     }
1422 
1423     return jinteger_obj;
1424   }
1425 };
1426 
1427 // The portal class for java.lang.Long
1428 class LongJni : public JavaClass {
1429  public:
1430   /**
1431    * Get the Java Class java.lang.Long
1432    *
1433    * @param env A pointer to the Java environment
1434    *
1435    * @return The Java Class or nullptr if one of the
1436    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1437    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1438    */
getJClass(JNIEnv * env)1439   static jclass getJClass(JNIEnv* env) {
1440     return JavaClass::getJClass(env, "java/lang/Long");
1441   }
1442 
valueOf(JNIEnv * env,jlong jprimitive_long)1443   static jobject valueOf(JNIEnv* env, jlong jprimitive_long) {
1444     jclass jclazz = getJClass(env);
1445     if (jclazz == nullptr) {
1446       // exception occurred accessing class
1447       return nullptr;
1448     }
1449 
1450     jmethodID mid =
1451         env->GetStaticMethodID(jclazz, "valueOf", "(J)Ljava/lang/Long;");
1452     if (mid == nullptr) {
1453       // exception thrown: NoSuchMethodException or OutOfMemoryError
1454       return nullptr;
1455     }
1456 
1457     const jobject jlong_obj =
1458         env->CallStaticObjectMethod(jclazz, mid, jprimitive_long);
1459     if (env->ExceptionCheck()) {
1460       // exception occurred
1461       return nullptr;
1462     }
1463 
1464     return jlong_obj;
1465   }
1466 };
1467 
1468 // The portal class for java.lang.StringBuilder
1469 class StringBuilderJni : public JavaClass {
1470   public:
1471   /**
1472    * Get the Java Class java.lang.StringBuilder
1473    *
1474    * @param env A pointer to the Java environment
1475    *
1476    * @return The Java Class or nullptr if one of the
1477    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
1478    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
1479    */
getJClass(JNIEnv * env)1480   static jclass getJClass(JNIEnv* env) {
1481     return JavaClass::getJClass(env, "java/lang/StringBuilder");
1482   }
1483 
1484   /**
1485    * Get the Java Method: StringBuilder#append
1486    *
1487    * @param env A pointer to the Java environment
1488    *
1489    * @return The Java Method ID or nullptr if the class or method id could not
1490    *     be retrieved
1491    */
getListAddMethodId(JNIEnv * env)1492   static jmethodID getListAddMethodId(JNIEnv* env) {
1493     jclass jclazz = getJClass(env);
1494     if(jclazz == nullptr) {
1495       // exception occurred accessing class
1496       return nullptr;
1497     }
1498 
1499     static jmethodID mid =
1500         env->GetMethodID(jclazz, "append",
1501             "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
1502     assert(mid != nullptr);
1503     return mid;
1504   }
1505 
1506   /**
1507    * Appends a C-style string to a StringBuilder
1508    *
1509    * @param env A pointer to the Java environment
1510    * @param jstring_builder Reference to a java.lang.StringBuilder
1511    * @param c_str A C-style string to append to the StringBuilder
1512    *
1513    * @return A reference to the updated StringBuilder, or a nullptr if
1514    *     an exception occurs
1515    */
append(JNIEnv * env,jobject jstring_builder,const char * c_str)1516   static jobject append(JNIEnv* env, jobject jstring_builder,
1517       const char* c_str) {
1518     jmethodID mid = getListAddMethodId(env);
1519     if(mid == nullptr) {
1520       // exception occurred accessing class or method
1521       return nullptr;
1522     }
1523 
1524     jstring new_value_str = env->NewStringUTF(c_str);
1525     if(new_value_str == nullptr) {
1526       // exception thrown: OutOfMemoryError
1527       return nullptr;
1528     }
1529 
1530     jobject jresult_string_builder =
1531         env->CallObjectMethod(jstring_builder, mid, new_value_str);
1532     if(env->ExceptionCheck()) {
1533       // exception occurred
1534       env->DeleteLocalRef(new_value_str);
1535       return nullptr;
1536     }
1537 
1538     return jresult_string_builder;
1539   }
1540 };
1541 
1542 // various utility functions for working with RocksDB and JNI
1543 class JniUtil {
1544  public:
1545     /**
1546      * Detect if jlong overflows size_t
1547      *
1548      * @param jvalue the jlong value
1549      *
1550      * @return
1551      */
check_if_jlong_fits_size_t(const jlong & jvalue)1552     inline static Status check_if_jlong_fits_size_t(const jlong& jvalue) {
1553       Status s = Status::OK();
1554       if (static_cast<uint64_t>(jvalue) > std::numeric_limits<size_t>::max()) {
1555         s = Status::InvalidArgument(Slice("jlong overflows 32 bit value."));
1556       }
1557       return s;
1558     }
1559 
1560     /**
1561      * Obtains a reference to the JNIEnv from
1562      * the JVM
1563      *
1564      * If the current thread is not attached to the JavaVM
1565      * then it will be attached so as to retrieve the JNIEnv
1566      *
1567      * If a thread is attached, it must later be manually
1568      * released by calling JavaVM::DetachCurrentThread.
1569      * This can be handled by always matching calls to this
1570      * function with calls to {@link JniUtil::releaseJniEnv(JavaVM*, jboolean)}
1571      *
1572      * @param jvm (IN) A pointer to the JavaVM instance
1573      * @param attached (OUT) A pointer to a boolean which
1574      *     will be set to JNI_TRUE if we had to attach the thread
1575      *
1576      * @return A pointer to the JNIEnv or nullptr if a fatal error
1577      *     occurs and the JNIEnv cannot be retrieved
1578      */
getJniEnv(JavaVM * jvm,jboolean * attached)1579     static JNIEnv* getJniEnv(JavaVM* jvm, jboolean* attached) {
1580       assert(jvm != nullptr);
1581 
1582       JNIEnv *env;
1583       const jint env_rs = jvm->GetEnv(reinterpret_cast<void**>(&env),
1584           JNI_VERSION_1_6);
1585 
1586       if(env_rs == JNI_OK) {
1587         // current thread is already attached, return the JNIEnv
1588         *attached = JNI_FALSE;
1589         return env;
1590       } else if(env_rs == JNI_EDETACHED) {
1591         // current thread is not attached, attempt to attach
1592         const jint rs_attach = jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL);
1593         if(rs_attach == JNI_OK) {
1594           *attached = JNI_TRUE;
1595           return env;
1596         } else {
1597           // error, could not attach the thread
1598           std::cerr << "JniUtil::getJniEnv - Fatal: could not attach current thread to JVM!" << std::endl;
1599           return nullptr;
1600         }
1601       } else if(env_rs == JNI_EVERSION) {
1602         // error, JDK does not support JNI_VERSION_1_6+
1603         std::cerr << "JniUtil::getJniEnv - Fatal: JDK does not support JNI_VERSION_1_6" << std::endl;
1604         return nullptr;
1605       } else {
1606         std::cerr << "JniUtil::getJniEnv - Fatal: Unknown error: env_rs=" << env_rs << std::endl;
1607         return nullptr;
1608       }
1609     }
1610 
1611     /**
1612      * Counterpart to {@link JniUtil::getJniEnv(JavaVM*, jboolean*)}
1613      *
1614      * Detachess the current thread from the JVM if it was previously
1615      * attached
1616      *
1617      * @param jvm (IN) A pointer to the JavaVM instance
1618      * @param attached (IN) JNI_TRUE if we previously had to attach the thread
1619      *     to the JavaVM to get the JNIEnv
1620      */
releaseJniEnv(JavaVM * jvm,jboolean & attached)1621     static void releaseJniEnv(JavaVM* jvm, jboolean& attached) {
1622       assert(jvm != nullptr);
1623       if(attached == JNI_TRUE) {
1624         const jint rs_detach = jvm->DetachCurrentThread();
1625         assert(rs_detach == JNI_OK);
1626         if(rs_detach != JNI_OK) {
1627           std::cerr << "JniUtil::getJniEnv - Warn: Unable to detach current thread from JVM!" << std::endl;
1628         }
1629       }
1630     }
1631 
1632     /**
1633      * Copies a Java String[] to a C++ std::vector<std::string>
1634      *
1635      * @param env (IN) A pointer to the java environment
1636      * @param jss (IN) The Java String array to copy
1637      * @param has_exception (OUT) will be set to JNI_TRUE
1638      *     if an OutOfMemoryError or ArrayIndexOutOfBoundsException
1639      *     exception occurs
1640      *
1641      * @return A std::vector<std:string> containing copies of the Java strings
1642      */
copyStrings(JNIEnv * env,jobjectArray jss,jboolean * has_exception)1643     static std::vector<std::string> copyStrings(JNIEnv* env,
1644         jobjectArray jss, jboolean* has_exception) {
1645       return ROCKSDB_NAMESPACE::JniUtil::copyStrings(
1646           env, jss, env->GetArrayLength(jss), has_exception);
1647     }
1648 
1649     /**
1650      * Copies a Java String[] to a C++ std::vector<std::string>
1651      *
1652      * @param env (IN) A pointer to the java environment
1653      * @param jss (IN) The Java String array to copy
1654      * @param jss_len (IN) The length of the Java String array to copy
1655      * @param has_exception (OUT) will be set to JNI_TRUE
1656      *     if an OutOfMemoryError or ArrayIndexOutOfBoundsException
1657      *     exception occurs
1658      *
1659      * @return A std::vector<std:string> containing copies of the Java strings
1660      */
copyStrings(JNIEnv * env,jobjectArray jss,const jsize jss_len,jboolean * has_exception)1661     static std::vector<std::string> copyStrings(JNIEnv* env,
1662         jobjectArray jss, const jsize jss_len, jboolean* has_exception) {
1663       std::vector<std::string> strs;
1664       strs.reserve(jss_len);
1665       for (jsize i = 0; i < jss_len; i++) {
1666         jobject js = env->GetObjectArrayElement(jss, i);
1667         if(env->ExceptionCheck()) {
1668           // exception thrown: ArrayIndexOutOfBoundsException
1669           *has_exception = JNI_TRUE;
1670           return strs;
1671         }
1672 
1673         jstring jstr = static_cast<jstring>(js);
1674         const char* str = env->GetStringUTFChars(jstr, nullptr);
1675         if(str == nullptr) {
1676           // exception thrown: OutOfMemoryError
1677           env->DeleteLocalRef(js);
1678           *has_exception = JNI_TRUE;
1679           return strs;
1680         }
1681 
1682         strs.push_back(std::string(str));
1683 
1684         env->ReleaseStringUTFChars(jstr, str);
1685         env->DeleteLocalRef(js);
1686       }
1687 
1688       *has_exception = JNI_FALSE;
1689       return strs;
1690     }
1691 
1692     /**
1693      * Copies a jstring to a C-style null-terminated byte string
1694      * and releases the original jstring
1695      *
1696      * The jstring is copied as UTF-8
1697      *
1698      * If an exception occurs, then JNIEnv::ExceptionCheck()
1699      * will have been called
1700      *
1701      * @param env (IN) A pointer to the java environment
1702      * @param js (IN) The java string to copy
1703      * @param has_exception (OUT) will be set to JNI_TRUE
1704      *     if an OutOfMemoryError exception occurs
1705      *
1706      * @return A pointer to the copied string, or a
1707      *     nullptr if has_exception == JNI_TRUE
1708      */
copyString(JNIEnv * env,jstring js,jboolean * has_exception)1709     static std::unique_ptr<char[]> copyString(JNIEnv* env, jstring js,
1710         jboolean* has_exception) {
1711       const char *utf = env->GetStringUTFChars(js, nullptr);
1712       if(utf == nullptr) {
1713         // exception thrown: OutOfMemoryError
1714         env->ExceptionCheck();
1715         *has_exception = JNI_TRUE;
1716         return nullptr;
1717       } else if(env->ExceptionCheck()) {
1718         // exception thrown
1719         env->ReleaseStringUTFChars(js, utf);
1720         *has_exception = JNI_TRUE;
1721         return nullptr;
1722       }
1723 
1724       const jsize utf_len = env->GetStringUTFLength(js);
1725       std::unique_ptr<char[]> str(new char[utf_len + 1]);  // Note: + 1 is needed for the c_str null terminator
1726       std::strcpy(str.get(), utf);
1727       env->ReleaseStringUTFChars(js, utf);
1728       *has_exception = JNI_FALSE;
1729       return str;
1730     }
1731 
1732     /**
1733      * Copies a jstring to a std::string
1734      * and releases the original jstring
1735      *
1736      * If an exception occurs, then JNIEnv::ExceptionCheck()
1737      * will have been called
1738      *
1739      * @param env (IN) A pointer to the java environment
1740      * @param js (IN) The java string to copy
1741      * @param has_exception (OUT) will be set to JNI_TRUE
1742      *     if an OutOfMemoryError exception occurs
1743      *
1744      * @return A std:string copy of the jstring, or an
1745      *     empty std::string if has_exception == JNI_TRUE
1746      */
copyStdString(JNIEnv * env,jstring js,jboolean * has_exception)1747     static std::string copyStdString(JNIEnv* env, jstring js,
1748       jboolean* has_exception) {
1749       const char *utf = env->GetStringUTFChars(js, nullptr);
1750       if(utf == nullptr) {
1751         // exception thrown: OutOfMemoryError
1752         env->ExceptionCheck();
1753         *has_exception = JNI_TRUE;
1754         return std::string();
1755       } else if(env->ExceptionCheck()) {
1756         // exception thrown
1757         env->ReleaseStringUTFChars(js, utf);
1758         *has_exception = JNI_TRUE;
1759         return std::string();
1760       }
1761 
1762       std::string name(utf);
1763       env->ReleaseStringUTFChars(js, utf);
1764       *has_exception = JNI_FALSE;
1765       return name;
1766     }
1767 
1768     /**
1769      * Copies bytes from a std::string to a jByteArray
1770      *
1771      * @param env A pointer to the java environment
1772      * @param bytes The bytes to copy
1773      *
1774      * @return the Java byte[], or nullptr if an exception occurs
1775      *
1776      * @throws RocksDBException thrown
1777      *   if memory size to copy exceeds general java specific array size limitation.
1778      */
copyBytes(JNIEnv * env,std::string bytes)1779     static jbyteArray copyBytes(JNIEnv* env, std::string bytes) {
1780       return createJavaByteArrayWithSizeCheck(env, bytes.c_str(), bytes.size());
1781     }
1782 
1783     /**
1784      * Given a Java byte[][] which is an array of java.lang.Strings
1785      * where each String is a byte[], the passed function `string_fn`
1786      * will be called on each String, the result is the collected by
1787      * calling the passed function `collector_fn`
1788      *
1789      * @param env (IN) A pointer to the java environment
1790      * @param jbyte_strings (IN) A Java array of Strings expressed as bytes
1791      * @param string_fn (IN) A transform function to call for each String
1792      * @param collector_fn (IN) A collector which is called for the result
1793      *     of each `string_fn`
1794      * @param has_exception (OUT) will be set to JNI_TRUE
1795      *     if an ArrayIndexOutOfBoundsException or OutOfMemoryError
1796      *     exception occurs
1797      */
byteStrings(JNIEnv * env,jobjectArray jbyte_strings,std::function<T (const char *,const size_t)> string_fn,std::function<void (size_t,T)> collector_fn,jboolean * has_exception)1798     template <typename T> static void byteStrings(JNIEnv* env,
1799         jobjectArray jbyte_strings,
1800         std::function<T(const char*, const size_t)> string_fn,
1801         std::function<void(size_t, T)> collector_fn,
1802         jboolean *has_exception) {
1803       const jsize jlen = env->GetArrayLength(jbyte_strings);
1804 
1805       for(jsize i = 0; i < jlen; i++) {
1806         jobject jbyte_string_obj = env->GetObjectArrayElement(jbyte_strings, i);
1807         if(env->ExceptionCheck()) {
1808           // exception thrown: ArrayIndexOutOfBoundsException
1809           *has_exception = JNI_TRUE;  // signal error
1810           return;
1811         }
1812 
1813         jbyteArray jbyte_string_ary =
1814             reinterpret_cast<jbyteArray>(jbyte_string_obj);
1815         T result = byteString(env, jbyte_string_ary, string_fn, has_exception);
1816 
1817         env->DeleteLocalRef(jbyte_string_obj);
1818 
1819         if(*has_exception == JNI_TRUE) {
1820           // exception thrown: OutOfMemoryError
1821           return;
1822         }
1823 
1824         collector_fn(i, result);
1825       }
1826 
1827       *has_exception = JNI_FALSE;
1828     }
1829 
1830     /**
1831      * Given a Java String which is expressed as a Java Byte Array byte[],
1832      * the passed function `string_fn` will be called on the String
1833      * and the result returned
1834      *
1835      * @param env (IN) A pointer to the java environment
1836      * @param jbyte_string_ary (IN) A Java String expressed in bytes
1837      * @param string_fn (IN) A transform function to call on the String
1838      * @param has_exception (OUT) will be set to JNI_TRUE
1839      *     if an OutOfMemoryError exception occurs
1840      */
byteString(JNIEnv * env,jbyteArray jbyte_string_ary,std::function<T (const char *,const size_t)> string_fn,jboolean * has_exception)1841     template <typename T> static T byteString(JNIEnv* env,
1842         jbyteArray jbyte_string_ary,
1843         std::function<T(const char*, const size_t)> string_fn,
1844         jboolean* has_exception) {
1845       const jsize jbyte_string_len = env->GetArrayLength(jbyte_string_ary);
1846       return byteString<T>(env, jbyte_string_ary, jbyte_string_len, string_fn,
1847           has_exception);
1848     }
1849 
1850     /**
1851      * Given a Java String which is expressed as a Java Byte Array byte[],
1852      * the passed function `string_fn` will be called on the String
1853      * and the result returned
1854      *
1855      * @param env (IN) A pointer to the java environment
1856      * @param jbyte_string_ary (IN) A Java String expressed in bytes
1857      * @param jbyte_string_len (IN) The length of the Java String
1858      *     expressed in bytes
1859      * @param string_fn (IN) A transform function to call on the String
1860      * @param has_exception (OUT) will be set to JNI_TRUE
1861      *     if an OutOfMemoryError exception occurs
1862      */
byteString(JNIEnv * env,jbyteArray jbyte_string_ary,const jsize jbyte_string_len,std::function<T (const char *,const size_t)> string_fn,jboolean * has_exception)1863     template <typename T> static T byteString(JNIEnv* env,
1864         jbyteArray jbyte_string_ary, const jsize jbyte_string_len,
1865         std::function<T(const char*, const size_t)> string_fn,
1866         jboolean* has_exception) {
1867       jbyte* jbyte_string =
1868           env->GetByteArrayElements(jbyte_string_ary, nullptr);
1869       if(jbyte_string == nullptr) {
1870         // exception thrown: OutOfMemoryError
1871         *has_exception = JNI_TRUE;
1872         return nullptr;  // signal error
1873       }
1874 
1875       T result =
1876           string_fn(reinterpret_cast<char *>(jbyte_string), jbyte_string_len);
1877 
1878       env->ReleaseByteArrayElements(jbyte_string_ary, jbyte_string, JNI_ABORT);
1879 
1880       *has_exception = JNI_FALSE;
1881       return result;
1882     }
1883 
1884     /**
1885      * Converts a std::vector<string> to a Java byte[][] where each Java String
1886      * is expressed as a Java Byte Array byte[].
1887      *
1888      * @param env A pointer to the java environment
1889      * @param strings A vector of Strings
1890      *
1891      * @return A Java array of Strings expressed as bytes,
1892      *     or nullptr if an exception is thrown
1893      */
stringsBytes(JNIEnv * env,std::vector<std::string> strings)1894     static jobjectArray stringsBytes(JNIEnv* env, std::vector<std::string> strings) {
1895       jclass jcls_ba = ByteJni::getArrayJClass(env);
1896       if(jcls_ba == nullptr) {
1897         // exception occurred
1898         return nullptr;
1899       }
1900 
1901       const jsize len = static_cast<jsize>(strings.size());
1902 
1903       jobjectArray jbyte_strings = env->NewObjectArray(len, jcls_ba, nullptr);
1904       if(jbyte_strings == nullptr) {
1905         // exception thrown: OutOfMemoryError
1906         return nullptr;
1907       }
1908 
1909       for (jsize i = 0; i < len; i++) {
1910         std::string *str = &strings[i];
1911         const jsize str_len = static_cast<jsize>(str->size());
1912 
1913         jbyteArray jbyte_string_ary = env->NewByteArray(str_len);
1914         if(jbyte_string_ary == nullptr) {
1915           // exception thrown: OutOfMemoryError
1916           env->DeleteLocalRef(jbyte_strings);
1917           return nullptr;
1918         }
1919 
1920         env->SetByteArrayRegion(
1921           jbyte_string_ary, 0, str_len,
1922           const_cast<jbyte*>(reinterpret_cast<const jbyte*>(str->c_str())));
1923         if(env->ExceptionCheck()) {
1924           // exception thrown: ArrayIndexOutOfBoundsException
1925           env->DeleteLocalRef(jbyte_string_ary);
1926           env->DeleteLocalRef(jbyte_strings);
1927           return nullptr;
1928         }
1929 
1930         env->SetObjectArrayElement(jbyte_strings, i, jbyte_string_ary);
1931         if(env->ExceptionCheck()) {
1932           // exception thrown: ArrayIndexOutOfBoundsException
1933           // or ArrayStoreException
1934           env->DeleteLocalRef(jbyte_string_ary);
1935           env->DeleteLocalRef(jbyte_strings);
1936           return nullptr;
1937         }
1938 
1939         env->DeleteLocalRef(jbyte_string_ary);
1940       }
1941 
1942       return jbyte_strings;
1943     }
1944 
1945      /**
1946      * Converts a std::vector<std::string> to a Java String[].
1947      *
1948      * @param env A pointer to the java environment
1949      * @param strings A vector of Strings
1950      *
1951      * @return A Java array of Strings,
1952      *     or nullptr if an exception is thrown
1953      */
toJavaStrings(JNIEnv * env,const std::vector<std::string> * strings)1954     static jobjectArray toJavaStrings(JNIEnv* env,
1955         const std::vector<std::string>* strings) {
1956       jclass jcls_str = env->FindClass("java/lang/String");
1957       if(jcls_str == nullptr) {
1958         // exception occurred
1959         return nullptr;
1960       }
1961 
1962       const jsize len = static_cast<jsize>(strings->size());
1963 
1964       jobjectArray jstrings = env->NewObjectArray(len, jcls_str, nullptr);
1965       if(jstrings == nullptr) {
1966         // exception thrown: OutOfMemoryError
1967         return nullptr;
1968       }
1969 
1970       for (jsize i = 0; i < len; i++) {
1971         const std::string *str = &((*strings)[i]);
1972         jstring js = ROCKSDB_NAMESPACE::JniUtil::toJavaString(env, str);
1973         if (js == nullptr) {
1974           env->DeleteLocalRef(jstrings);
1975           return nullptr;
1976         }
1977 
1978         env->SetObjectArrayElement(jstrings, i, js);
1979         if(env->ExceptionCheck()) {
1980           // exception thrown: ArrayIndexOutOfBoundsException
1981           // or ArrayStoreException
1982           env->DeleteLocalRef(js);
1983           env->DeleteLocalRef(jstrings);
1984           return nullptr;
1985         }
1986       }
1987 
1988       return jstrings;
1989     }
1990 
1991     /**
1992      * Creates a Java UTF String from a C++ std::string
1993      *
1994      * @param env A pointer to the java environment
1995      * @param string the C++ std::string
1996      * @param treat_empty_as_null true if empty strings should be treated as null
1997      *
1998      * @return the Java UTF string, or nullptr if the provided string
1999      *     is null (or empty and treat_empty_as_null is set), or if an
2000      *     exception occurs allocating the Java String.
2001      */
2002     static jstring toJavaString(JNIEnv* env, const std::string* string,
2003         const bool treat_empty_as_null = false) {
2004       if (string == nullptr) {
2005         return nullptr;
2006       }
2007 
2008       if (treat_empty_as_null && string->empty()) {
2009         return nullptr;
2010       }
2011 
2012       return env->NewStringUTF(string->c_str());
2013     }
2014 
2015     /**
2016       * Copies bytes to a new jByteArray with the check of java array size limitation.
2017       *
2018       * @param bytes pointer to memory to copy to a new jByteArray
2019       * @param size number of bytes to copy
2020       *
2021       * @return the Java byte[], or nullptr if an exception occurs
2022       *
2023       * @throws RocksDBException thrown
2024       *   if memory size to copy exceeds general java array size limitation to avoid overflow.
2025       */
createJavaByteArrayWithSizeCheck(JNIEnv * env,const char * bytes,const size_t size)2026     static jbyteArray createJavaByteArrayWithSizeCheck(JNIEnv* env, const char* bytes, const size_t size) {
2027       // Limitation for java array size is vm specific
2028       // In general it cannot exceed Integer.MAX_VALUE (2^31 - 1)
2029       // Current HotSpot VM limitation for array size is Integer.MAX_VALUE - 5 (2^31 - 1 - 5)
2030       // It means that the next call to env->NewByteArray can still end with
2031       // OutOfMemoryError("Requested array size exceeds VM limit") coming from VM
2032       static const size_t MAX_JARRAY_SIZE = (static_cast<size_t>(1)) << 31;
2033       if(size > MAX_JARRAY_SIZE) {
2034         ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2035             env, "Requested array size exceeds VM limit");
2036         return nullptr;
2037       }
2038 
2039       const jsize jlen = static_cast<jsize>(size);
2040       jbyteArray jbytes = env->NewByteArray(jlen);
2041       if(jbytes == nullptr) {
2042         // exception thrown: OutOfMemoryError
2043         return nullptr;
2044       }
2045 
2046       env->SetByteArrayRegion(jbytes, 0, jlen,
2047         const_cast<jbyte*>(reinterpret_cast<const jbyte*>(bytes)));
2048       if(env->ExceptionCheck()) {
2049         // exception thrown: ArrayIndexOutOfBoundsException
2050         env->DeleteLocalRef(jbytes);
2051         return nullptr;
2052       }
2053 
2054       return jbytes;
2055     }
2056 
2057     /**
2058      * Copies bytes from a ROCKSDB_NAMESPACE::Slice to a jByteArray
2059      *
2060      * @param env A pointer to the java environment
2061      * @param bytes The bytes to copy
2062      *
2063      * @return the Java byte[] or nullptr if an exception occurs
2064      *
2065      * @throws RocksDBException thrown
2066      *   if memory size to copy exceeds general java specific array size
2067      * limitation.
2068      */
copyBytes(JNIEnv * env,const Slice & bytes)2069     static jbyteArray copyBytes(JNIEnv* env, const Slice& bytes) {
2070       return createJavaByteArrayWithSizeCheck(env, bytes.data(), bytes.size());
2071     }
2072 
2073     /*
2074      * Helper for operations on a key and value
2075      * for example WriteBatch->Put
2076      *
2077      * TODO(AR) could be used for RocksDB->Put etc.
2078      */
kv_op(std::function<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Slice,ROCKSDB_NAMESPACE::Slice)> op,JNIEnv * env,jobject,jbyteArray jkey,jint jkey_len,jbyteArray jvalue,jint jvalue_len)2079     static std::unique_ptr<ROCKSDB_NAMESPACE::Status> kv_op(
2080         std::function<ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Slice,
2081                                                 ROCKSDB_NAMESPACE::Slice)>
2082             op,
2083         JNIEnv* env, jobject /*jobj*/, jbyteArray jkey, jint jkey_len,
2084         jbyteArray jvalue, jint jvalue_len) {
2085       jbyte* key = env->GetByteArrayElements(jkey, nullptr);
2086       if(env->ExceptionCheck()) {
2087         // exception thrown: OutOfMemoryError
2088         return nullptr;
2089       }
2090 
2091       jbyte* value = env->GetByteArrayElements(jvalue, nullptr);
2092       if(env->ExceptionCheck()) {
2093         // exception thrown: OutOfMemoryError
2094         if(key != nullptr) {
2095           env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2096         }
2097         return nullptr;
2098       }
2099 
2100       ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
2101                                          jkey_len);
2102       ROCKSDB_NAMESPACE::Slice value_slice(reinterpret_cast<char*>(value),
2103                                            jvalue_len);
2104 
2105       auto status = op(key_slice, value_slice);
2106 
2107       if(value != nullptr) {
2108         env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
2109       }
2110       if(key != nullptr) {
2111         env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2112       }
2113 
2114       return std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
2115           new ROCKSDB_NAMESPACE::Status(status));
2116     }
2117 
2118     /*
2119      * Helper for operations on a key
2120      * for example WriteBatch->Delete
2121      *
2122      * TODO(AR) could be used for RocksDB->Delete etc.
2123      */
k_op(std::function<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Slice)> op,JNIEnv * env,jobject,jbyteArray jkey,jint jkey_len)2124     static std::unique_ptr<ROCKSDB_NAMESPACE::Status> k_op(
2125         std::function<ROCKSDB_NAMESPACE::Status(ROCKSDB_NAMESPACE::Slice)> op,
2126         JNIEnv* env, jobject /*jobj*/, jbyteArray jkey, jint jkey_len) {
2127       jbyte* key = env->GetByteArrayElements(jkey, nullptr);
2128       if(env->ExceptionCheck()) {
2129         // exception thrown: OutOfMemoryError
2130         return nullptr;
2131       }
2132 
2133       ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
2134                                          jkey_len);
2135 
2136       auto status = op(key_slice);
2137 
2138       if(key != nullptr) {
2139         env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2140       }
2141 
2142       return std::unique_ptr<ROCKSDB_NAMESPACE::Status>(
2143           new ROCKSDB_NAMESPACE::Status(status));
2144     }
2145 
2146     /*
2147      * Helper for operations on a value
2148      * for example WriteBatchWithIndex->GetFromBatch
2149      */
v_op(std::function<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Slice,std::string *)> op,JNIEnv * env,jbyteArray jkey,jint jkey_len)2150     static jbyteArray v_op(std::function<ROCKSDB_NAMESPACE::Status(
2151                                ROCKSDB_NAMESPACE::Slice, std::string*)>
2152                                op,
2153                            JNIEnv* env, jbyteArray jkey, jint jkey_len) {
2154       jbyte* key = env->GetByteArrayElements(jkey, nullptr);
2155       if(env->ExceptionCheck()) {
2156         // exception thrown: OutOfMemoryError
2157         return nullptr;
2158       }
2159 
2160       ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
2161                                          jkey_len);
2162 
2163       std::string value;
2164       ROCKSDB_NAMESPACE::Status s = op(key_slice, &value);
2165 
2166       if(key != nullptr) {
2167         env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
2168       }
2169 
2170       if (s.IsNotFound()) {
2171         return nullptr;
2172       }
2173 
2174       if (s.ok()) {
2175         jbyteArray jret_value =
2176             env->NewByteArray(static_cast<jsize>(value.size()));
2177         if(jret_value == nullptr) {
2178           // exception thrown: OutOfMemoryError
2179           return nullptr;
2180         }
2181 
2182         env->SetByteArrayRegion(jret_value, 0, static_cast<jsize>(value.size()),
2183                                 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.c_str())));
2184         if(env->ExceptionCheck()) {
2185           // exception thrown: ArrayIndexOutOfBoundsException
2186           if(jret_value != nullptr) {
2187             env->DeleteLocalRef(jret_value);
2188           }
2189           return nullptr;
2190         }
2191 
2192         return jret_value;
2193       }
2194 
2195       ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
2196       return nullptr;
2197     }
2198 
2199     /**
2200      * Creates a vector<T*> of C++ pointers from
2201      *     a Java array of C++ pointer addresses.
2202      *
2203      * @param env (IN) A pointer to the java environment
2204      * @param pointers (IN) A Java array of C++ pointer addresses
2205      * @param has_exception (OUT) will be set to JNI_TRUE
2206      *     if an ArrayIndexOutOfBoundsException or OutOfMemoryError
2207      *     exception occurs.
2208      *
2209      * @return A vector of C++ pointers.
2210      */
fromJPointers(JNIEnv * env,jlongArray jptrs,jboolean * has_exception)2211     template<typename T> static std::vector<T*> fromJPointers(
2212         JNIEnv* env, jlongArray jptrs, jboolean *has_exception) {
2213       const jsize jptrs_len = env->GetArrayLength(jptrs);
2214       std::vector<T*> ptrs;
2215       jlong* jptr = env->GetLongArrayElements(jptrs, nullptr);
2216       if (jptr == nullptr) {
2217         // exception thrown: OutOfMemoryError
2218         *has_exception = JNI_TRUE;
2219         return ptrs;
2220       }
2221       ptrs.reserve(jptrs_len);
2222       for (jsize i = 0; i < jptrs_len; i++) {
2223         ptrs.push_back(reinterpret_cast<T*>(jptr[i]));
2224       }
2225       env->ReleaseLongArrayElements(jptrs, jptr, JNI_ABORT);
2226       return ptrs;
2227     }
2228 
2229     /**
2230      * Creates a Java array of C++ pointer addresses
2231      *     from a vector of C++ pointers.
2232      *
2233      * @param env (IN) A pointer to the java environment
2234      * @param pointers (IN) A vector of C++ pointers
2235      * @param has_exception (OUT) will be set to JNI_TRUE
2236      *     if an ArrayIndexOutOfBoundsException or OutOfMemoryError
2237      *     exception occurs
2238      *
2239      * @return Java array of C++ pointer addresses.
2240      */
toJPointers(JNIEnv * env,const std::vector<T * > & pointers,jboolean * has_exception)2241     template<typename T> static jlongArray toJPointers(JNIEnv* env,
2242         const std::vector<T*> &pointers,
2243         jboolean *has_exception) {
2244       const jsize len = static_cast<jsize>(pointers.size());
2245       std::unique_ptr<jlong[]> results(new jlong[len]);
2246       std::transform(pointers.begin(), pointers.end(), results.get(), [](T* pointer) -> jlong {
2247         return reinterpret_cast<jlong>(pointer);
2248       });
2249 
2250       jlongArray jpointers = env->NewLongArray(len);
2251       if (jpointers == nullptr) {
2252         // exception thrown: OutOfMemoryError
2253         *has_exception = JNI_TRUE;
2254         return nullptr;
2255       }
2256 
2257       env->SetLongArrayRegion(jpointers, 0, len, results.get());
2258       if (env->ExceptionCheck()) {
2259         // exception thrown: ArrayIndexOutOfBoundsException
2260         *has_exception = JNI_TRUE;
2261         env->DeleteLocalRef(jpointers);
2262         return nullptr;
2263       }
2264 
2265       *has_exception = JNI_FALSE;
2266 
2267       return jpointers;
2268     }
2269 
2270     /*
2271      * Helper for operations on a key and value
2272      * for example WriteBatch->Put
2273      *
2274      * TODO(AR) could be extended to cover returning ROCKSDB_NAMESPACE::Status
2275      * from `op` and used for RocksDB->Put etc.
2276      */
kv_op_direct(std::function<void (ROCKSDB_NAMESPACE::Slice &,ROCKSDB_NAMESPACE::Slice &)> op,JNIEnv * env,jobject jkey,jint jkey_off,jint jkey_len,jobject jval,jint jval_off,jint jval_len)2277     static void kv_op_direct(std::function<void(ROCKSDB_NAMESPACE::Slice&,
2278                                                 ROCKSDB_NAMESPACE::Slice&)>
2279                                  op,
2280                              JNIEnv* env, jobject jkey, jint jkey_off,
2281                              jint jkey_len, jobject jval, jint jval_off,
2282                              jint jval_len) {
2283       char* key = reinterpret_cast<char*>(env->GetDirectBufferAddress(jkey));
2284       if (key == nullptr ||
2285           env->GetDirectBufferCapacity(jkey) < (jkey_off + jkey_len)) {
2286         ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2287             env, "Invalid key argument");
2288         return;
2289       }
2290 
2291       char* value = reinterpret_cast<char*>(env->GetDirectBufferAddress(jval));
2292       if (value == nullptr ||
2293           env->GetDirectBufferCapacity(jval) < (jval_off + jval_len)) {
2294         ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2295             env, "Invalid value argument");
2296         return;
2297       }
2298 
2299       key += jkey_off;
2300       value += jval_off;
2301 
2302       ROCKSDB_NAMESPACE::Slice key_slice(key, jkey_len);
2303       ROCKSDB_NAMESPACE::Slice value_slice(value, jval_len);
2304 
2305       op(key_slice, value_slice);
2306     }
2307 
2308     /*
2309      * Helper for operations on a key and value
2310      * for example WriteBatch->Delete
2311      *
2312      * TODO(AR) could be extended to cover returning ROCKSDB_NAMESPACE::Status
2313      * from `op` and used for RocksDB->Delete etc.
2314      */
k_op_direct(std::function<void (ROCKSDB_NAMESPACE::Slice &)> op,JNIEnv * env,jobject jkey,jint jkey_off,jint jkey_len)2315     static void k_op_direct(std::function<void(ROCKSDB_NAMESPACE::Slice&)> op,
2316                             JNIEnv* env, jobject jkey, jint jkey_off,
2317                             jint jkey_len) {
2318       char* key = reinterpret_cast<char*>(env->GetDirectBufferAddress(jkey));
2319       if (key == nullptr ||
2320           env->GetDirectBufferCapacity(jkey) < (jkey_off + jkey_len)) {
2321         ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2322             env, "Invalid key argument");
2323         return;
2324       }
2325 
2326       key += jkey_off;
2327 
2328       ROCKSDB_NAMESPACE::Slice key_slice(key, jkey_len);
2329 
2330       return op(key_slice);
2331     }
2332 
2333     template <class T>
copyToDirect(JNIEnv * env,T & source,jobject jtarget,jint jtarget_off,jint jtarget_len)2334     static jint copyToDirect(JNIEnv* env, T& source, jobject jtarget,
2335                              jint jtarget_off, jint jtarget_len) {
2336       char* target =
2337           reinterpret_cast<char*>(env->GetDirectBufferAddress(jtarget));
2338       if (target == nullptr ||
2339           env->GetDirectBufferCapacity(jtarget) < (jtarget_off + jtarget_len)) {
2340         ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
2341             env, "Invalid target argument");
2342         return 0;
2343       }
2344 
2345       target += jtarget_off;
2346 
2347       const jint cvalue_len = static_cast<jint>(source.size());
2348       const jint length = std::min(jtarget_len, cvalue_len);
2349 
2350       memcpy(target, source.data(), length);
2351 
2352       return cvalue_len;
2353     }
2354 };
2355 
2356 class MapJni : public JavaClass {
2357  public:
2358   /**
2359    * Get the Java Class java.util.Map
2360    *
2361    * @param env A pointer to the Java environment
2362    *
2363    * @return The Java Class or nullptr if one of the
2364    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2365    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2366    */
getJClass(JNIEnv * env)2367   static jclass getJClass(JNIEnv* env) {
2368     return JavaClass::getJClass(env, "java/util/Map");
2369   }
2370 
2371   /**
2372    * Get the Java Method: Map#put
2373    *
2374    * @param env A pointer to the Java environment
2375    *
2376    * @return The Java Method ID or nullptr if the class or method id could not
2377    *     be retrieved
2378    */
getMapPutMethodId(JNIEnv * env)2379   static jmethodID getMapPutMethodId(JNIEnv* env) {
2380     jclass jlist_clazz = getJClass(env);
2381     if(jlist_clazz == nullptr) {
2382       // exception occurred accessing class
2383       return nullptr;
2384     }
2385 
2386     static jmethodID mid =
2387         env->GetMethodID(jlist_clazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
2388     assert(mid != nullptr);
2389     return mid;
2390   }
2391 };
2392 
2393 class HashMapJni : public JavaClass {
2394  public:
2395   /**
2396    * Get the Java Class java.util.HashMap
2397    *
2398    * @param env A pointer to the Java environment
2399    *
2400    * @return The Java Class or nullptr if one of the
2401    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2402    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2403    */
getJClass(JNIEnv * env)2404   static jclass getJClass(JNIEnv* env) {
2405     return JavaClass::getJClass(env, "java/util/HashMap");
2406   }
2407 
2408   /**
2409    * Create a new Java java.util.HashMap object.
2410    *
2411    * @param env A pointer to the Java environment
2412    *
2413    * @return A reference to a Java java.util.HashMap object, or
2414    * nullptr if an an exception occurs
2415    */
2416   static jobject construct(JNIEnv* env, const uint32_t initial_capacity = 16) {
2417     jclass jclazz = getJClass(env);
2418     if (jclazz == nullptr) {
2419       // exception occurred accessing class
2420       return nullptr;
2421     }
2422 
2423     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(I)V");
2424     if (mid == nullptr) {
2425       // exception thrown: NoSuchMethodException or OutOfMemoryError
2426       return nullptr;
2427     }
2428 
2429     jobject jhash_map = env->NewObject(jclazz, mid, static_cast<jint>(initial_capacity));
2430     if (env->ExceptionCheck()) {
2431       return nullptr;
2432     }
2433 
2434     return jhash_map;
2435   }
2436 
2437   /**
2438    * A function which maps a std::pair<K,V> to a std::pair<JK, JV>
2439    *
2440    * @return Either a pointer to a std::pair<jobject, jobject>, or nullptr
2441    *     if an error occurs during the mapping
2442    */
2443   template <typename K, typename V, typename JK, typename JV>
2444   using FnMapKV = std::function<std::unique_ptr<std::pair<JK, JV>> (const std::pair<K, V>&)>;
2445 
2446   // 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>
2447   // static void putAll(JNIEnv* env, const jobject jhash_map, I iterator, const FnMapKV<const K,V,K1,V1> &fn_map_kv) {
2448   /**
2449    * Returns true if it succeeds, false if an error occurs
2450    */
2451   template<class iterator_type, typename K, typename V>
putAll(JNIEnv * env,const jobject jhash_map,iterator_type iterator,iterator_type end,const FnMapKV<K,V,jobject,jobject> & fn_map_kv)2452   static bool putAll(JNIEnv* env, const jobject jhash_map, iterator_type iterator, iterator_type end, const FnMapKV<K, V, jobject, jobject> &fn_map_kv) {
2453     const jmethodID jmid_put =
2454         ROCKSDB_NAMESPACE::MapJni::getMapPutMethodId(env);
2455     if (jmid_put == nullptr) {
2456       return false;
2457     }
2458 
2459     for (auto it = iterator; it != end; ++it) {
2460       const std::unique_ptr<std::pair<jobject, jobject>> result = fn_map_kv(*it);
2461       if (result == nullptr) {
2462           // an error occurred during fn_map_kv
2463           return false;
2464       }
2465       env->CallObjectMethod(jhash_map, jmid_put, result->first, result->second);
2466       if (env->ExceptionCheck()) {
2467         // exception occurred
2468         env->DeleteLocalRef(result->second);
2469         env->DeleteLocalRef(result->first);
2470         return false;
2471       }
2472 
2473       // release local references
2474       env->DeleteLocalRef(result->second);
2475       env->DeleteLocalRef(result->first);
2476     }
2477 
2478     return true;
2479   }
2480 
2481   /**
2482    * Creates a java.util.Map<String, String> from a std::map<std::string, std::string>
2483    *
2484    * @param env A pointer to the Java environment
2485    * @param map the Cpp map
2486    *
2487    * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
2488    */
fromCppMap(JNIEnv * env,const std::map<std::string,std::string> * map)2489   static jobject fromCppMap(JNIEnv* env, const std::map<std::string, std::string>* map) {
2490     if (map == nullptr) {
2491       return nullptr;
2492     }
2493 
2494     jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
2495     if (jhash_map == nullptr) {
2496       // exception occurred
2497       return nullptr;
2498     }
2499 
2500     const ROCKSDB_NAMESPACE::HashMapJni::FnMapKV<
2501         const std::string, const std::string, jobject, jobject>
2502         fn_map_kv =
2503             [env](const std::pair<const std::string, const std::string>& kv) {
2504               jstring jkey = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
2505                   env, &(kv.first), false);
2506               if (env->ExceptionCheck()) {
2507                 // an error occurred
2508                 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2509               }
2510 
2511               jstring jvalue = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
2512                   env, &(kv.second), true);
2513               if (env->ExceptionCheck()) {
2514                 // an error occurred
2515                 env->DeleteLocalRef(jkey);
2516                 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2517               }
2518 
2519               return std::unique_ptr<std::pair<jobject, jobject>>(
2520                   new std::pair<jobject, jobject>(
2521                       static_cast<jobject>(jkey),
2522                       static_cast<jobject>(jvalue)));
2523             };
2524 
2525     if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
2526       // exception occurred
2527       return nullptr;
2528     }
2529 
2530     return jhash_map;
2531   }
2532 
2533   /**
2534    * Creates a java.util.Map<String, Long> from a std::map<std::string, uint32_t>
2535    *
2536    * @param env A pointer to the Java environment
2537    * @param map the Cpp map
2538    *
2539    * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
2540    */
fromCppMap(JNIEnv * env,const std::map<std::string,uint32_t> * map)2541   static jobject fromCppMap(JNIEnv* env, const std::map<std::string, uint32_t>* map) {
2542     if (map == nullptr) {
2543       return nullptr;
2544     }
2545 
2546     if (map == nullptr) {
2547       return nullptr;
2548     }
2549 
2550     jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
2551     if (jhash_map == nullptr) {
2552       // exception occurred
2553       return nullptr;
2554     }
2555 
2556     const ROCKSDB_NAMESPACE::HashMapJni::FnMapKV<
2557         const std::string, const uint32_t, jobject, jobject>
2558         fn_map_kv =
2559             [env](const std::pair<const std::string, const uint32_t>& kv) {
2560               jstring jkey = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
2561                   env, &(kv.first), false);
2562               if (env->ExceptionCheck()) {
2563                 // an error occurred
2564                 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2565               }
2566 
2567               jobject jvalue = ROCKSDB_NAMESPACE::IntegerJni::valueOf(
2568                   env, static_cast<jint>(kv.second));
2569               if (env->ExceptionCheck()) {
2570                 // an error occurred
2571                 env->DeleteLocalRef(jkey);
2572                 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2573               }
2574 
2575               return std::unique_ptr<std::pair<jobject, jobject>>(
2576                   new std::pair<jobject, jobject>(static_cast<jobject>(jkey),
2577                                                   jvalue));
2578             };
2579 
2580     if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
2581       // exception occurred
2582       return nullptr;
2583     }
2584 
2585     return jhash_map;
2586   }
2587 
2588   /**
2589    * Creates a java.util.Map<String, Long> from a std::map<std::string, uint64_t>
2590    *
2591    * @param env A pointer to the Java environment
2592    * @param map the Cpp map
2593    *
2594    * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
2595    */
fromCppMap(JNIEnv * env,const std::map<std::string,uint64_t> * map)2596   static jobject fromCppMap(JNIEnv* env, const std::map<std::string, uint64_t>* map) {
2597     if (map == nullptr) {
2598       return nullptr;
2599     }
2600 
2601     jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
2602     if (jhash_map == nullptr) {
2603       // exception occurred
2604       return nullptr;
2605     }
2606 
2607     const ROCKSDB_NAMESPACE::HashMapJni::FnMapKV<
2608         const std::string, const uint64_t, jobject, jobject>
2609         fn_map_kv =
2610             [env](const std::pair<const std::string, const uint64_t>& kv) {
2611               jstring jkey = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
2612                   env, &(kv.first), false);
2613               if (env->ExceptionCheck()) {
2614                 // an error occurred
2615                 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2616               }
2617 
2618               jobject jvalue = ROCKSDB_NAMESPACE::LongJni::valueOf(
2619                   env, static_cast<jlong>(kv.second));
2620               if (env->ExceptionCheck()) {
2621                 // an error occurred
2622                 env->DeleteLocalRef(jkey);
2623                 return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2624               }
2625 
2626               return std::unique_ptr<std::pair<jobject, jobject>>(
2627                   new std::pair<jobject, jobject>(static_cast<jobject>(jkey),
2628                                                   jvalue));
2629             };
2630 
2631     if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
2632       // exception occurred
2633       return nullptr;
2634     }
2635 
2636     return jhash_map;
2637   }
2638 
2639     /**
2640    * Creates a java.util.Map<String, Long> from a std::map<uint32_t, uint64_t>
2641    *
2642    * @param env A pointer to the Java environment
2643    * @param map the Cpp map
2644    *
2645    * @return a reference to the Java java.util.Map object, or nullptr if an exception occcurred
2646    */
fromCppMap(JNIEnv * env,const std::map<uint32_t,uint64_t> * map)2647   static jobject fromCppMap(JNIEnv* env, const std::map<uint32_t, uint64_t>* map) {
2648     if (map == nullptr) {
2649       return nullptr;
2650     }
2651 
2652     jobject jhash_map = construct(env, static_cast<uint32_t>(map->size()));
2653     if (jhash_map == nullptr) {
2654       // exception occurred
2655       return nullptr;
2656     }
2657 
2658     const ROCKSDB_NAMESPACE::HashMapJni::FnMapKV<const uint32_t, const uint64_t,
2659                                                  jobject, jobject>
2660         fn_map_kv = [env](const std::pair<const uint32_t, const uint64_t>& kv) {
2661           jobject jkey = ROCKSDB_NAMESPACE::IntegerJni::valueOf(
2662               env, static_cast<jint>(kv.first));
2663           if (env->ExceptionCheck()) {
2664             // an error occurred
2665             return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2666           }
2667 
2668           jobject jvalue = ROCKSDB_NAMESPACE::LongJni::valueOf(
2669               env, static_cast<jlong>(kv.second));
2670           if (env->ExceptionCheck()) {
2671             // an error occurred
2672             env->DeleteLocalRef(jkey);
2673             return std::unique_ptr<std::pair<jobject, jobject>>(nullptr);
2674           }
2675 
2676           return std::unique_ptr<std::pair<jobject, jobject>>(
2677               new std::pair<jobject, jobject>(static_cast<jobject>(jkey),
2678                                               jvalue));
2679         };
2680 
2681     if (!putAll(env, jhash_map, map->begin(), map->end(), fn_map_kv)) {
2682       // exception occurred
2683       return nullptr;
2684     }
2685 
2686     return jhash_map;
2687   }
2688 };
2689 
2690 // The portal class for org.rocksdb.RocksDB
2691 class RocksDBJni
2692     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::DB*, RocksDBJni> {
2693  public:
2694   /**
2695    * Get the Java Class org.rocksdb.RocksDB
2696    *
2697    * @param env A pointer to the Java environment
2698    *
2699    * @return The Java Class or nullptr if one of the
2700    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2701    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2702    */
getJClass(JNIEnv * env)2703   static jclass getJClass(JNIEnv* env) {
2704     return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksDB");
2705   }
2706 };
2707 
2708 // The portal class for org.rocksdb.Options
2709 class OptionsJni
2710     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::Options*, OptionsJni> {
2711  public:
2712   /**
2713    * Get the Java Class org.rocksdb.Options
2714    *
2715    * @param env A pointer to the Java environment
2716    *
2717    * @return The Java Class or nullptr if one of the
2718    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2719    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2720    */
getJClass(JNIEnv * env)2721   static jclass getJClass(JNIEnv* env) {
2722     return RocksDBNativeClass::getJClass(env, "org/rocksdb/Options");
2723   }
2724 };
2725 
2726 // The portal class for org.rocksdb.DBOptions
2727 class DBOptionsJni
2728     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::DBOptions*, DBOptionsJni> {
2729  public:
2730   /**
2731    * Get the Java Class org.rocksdb.DBOptions
2732    *
2733    * @param env A pointer to the Java environment
2734    *
2735    * @return The Java Class or nullptr if one of the
2736    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2737    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2738    */
getJClass(JNIEnv * env)2739   static jclass getJClass(JNIEnv* env) {
2740     return RocksDBNativeClass::getJClass(env, "org/rocksdb/DBOptions");
2741   }
2742 };
2743 
2744 // The portal class for org.rocksdb.ColumnFamilyOptions
2745 class ColumnFamilyOptionsJni
2746     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::ColumnFamilyOptions*,
2747                                 ColumnFamilyOptionsJni> {
2748  public:
2749   /**
2750    * Get the Java Class org.rocksdb.ColumnFamilyOptions
2751    *
2752    * @param env A pointer to the Java environment
2753    *
2754    * @return The Java Class or nullptr if one of the
2755    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2756    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2757    */
getJClass(JNIEnv * env)2758   static jclass getJClass(JNIEnv* env) {
2759     return RocksDBNativeClass::getJClass(env,
2760                                          "org/rocksdb/ColumnFamilyOptions");
2761   }
2762 
2763   /**
2764    * Create a new Java org.rocksdb.ColumnFamilyOptions object with the same
2765    * properties as the provided C++ ROCKSDB_NAMESPACE::ColumnFamilyOptions
2766    * object
2767    *
2768    * @param env A pointer to the Java environment
2769    * @param cfoptions A pointer to ROCKSDB_NAMESPACE::ColumnFamilyOptions object
2770    *
2771    * @return A reference to a Java org.rocksdb.ColumnFamilyOptions object, or
2772    * nullptr if an an exception occurs
2773    */
construct(JNIEnv * env,const ColumnFamilyOptions * cfoptions)2774   static jobject construct(JNIEnv* env, const ColumnFamilyOptions* cfoptions) {
2775     auto* cfo = new ROCKSDB_NAMESPACE::ColumnFamilyOptions(*cfoptions);
2776     jclass jclazz = getJClass(env);
2777     if(jclazz == nullptr) {
2778       // exception occurred accessing class
2779       return nullptr;
2780     }
2781 
2782     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(J)V");
2783     if (mid == nullptr) {
2784       // exception thrown: NoSuchMethodException or OutOfMemoryError
2785       return nullptr;
2786     }
2787 
2788     jobject jcfd = env->NewObject(jclazz, mid, reinterpret_cast<jlong>(cfo));
2789     if (env->ExceptionCheck()) {
2790       return nullptr;
2791     }
2792 
2793     return jcfd;
2794   }
2795 };
2796 
2797 // The portal class for org.rocksdb.WriteOptions
2798 class WriteOptionsJni
2799     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::WriteOptions*,
2800                                 WriteOptionsJni> {
2801  public:
2802   /**
2803    * Get the Java Class org.rocksdb.WriteOptions
2804    *
2805    * @param env A pointer to the Java environment
2806    *
2807    * @return The Java Class or nullptr if one of the
2808    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2809    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2810    */
getJClass(JNIEnv * env)2811   static jclass getJClass(JNIEnv* env) {
2812     return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteOptions");
2813   }
2814 };
2815 
2816 // The portal class for org.rocksdb.ReadOptions
2817 class ReadOptionsJni
2818     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::ReadOptions*,
2819                                 ReadOptionsJni> {
2820  public:
2821   /**
2822    * Get the Java Class org.rocksdb.ReadOptions
2823    *
2824    * @param env A pointer to the Java environment
2825    *
2826    * @return The Java Class or nullptr if one of the
2827    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2828    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2829    */
getJClass(JNIEnv * env)2830   static jclass getJClass(JNIEnv* env) {
2831     return RocksDBNativeClass::getJClass(env, "org/rocksdb/ReadOptions");
2832   }
2833 };
2834 
2835 // The portal class for org.rocksdb.WriteBatch
2836 class WriteBatchJni
2837     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::WriteBatch*, WriteBatchJni> {
2838  public:
2839   /**
2840    * Get the Java Class org.rocksdb.WriteBatch
2841    *
2842    * @param env A pointer to the Java environment
2843    *
2844    * @return The Java Class or nullptr if one of the
2845    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2846    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2847    */
getJClass(JNIEnv * env)2848   static jclass getJClass(JNIEnv* env) {
2849     return RocksDBNativeClass::getJClass(env, "org/rocksdb/WriteBatch");
2850   }
2851 
2852   /**
2853    * Create a new Java org.rocksdb.WriteBatch object
2854    *
2855    * @param env A pointer to the Java environment
2856    * @param wb A pointer to ROCKSDB_NAMESPACE::WriteBatch object
2857    *
2858    * @return A reference to a Java org.rocksdb.WriteBatch object, or
2859    * nullptr if an an exception occurs
2860    */
construct(JNIEnv * env,const WriteBatch * wb)2861   static jobject construct(JNIEnv* env, const WriteBatch* wb) {
2862     jclass jclazz = getJClass(env);
2863     if(jclazz == nullptr) {
2864       // exception occurred accessing class
2865       return nullptr;
2866     }
2867 
2868     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(J)V");
2869     if (mid == nullptr) {
2870       // exception thrown: NoSuchMethodException or OutOfMemoryError
2871       return nullptr;
2872     }
2873 
2874     jobject jwb = env->NewObject(jclazz, mid, reinterpret_cast<jlong>(wb));
2875     if (env->ExceptionCheck()) {
2876       return nullptr;
2877     }
2878 
2879     return jwb;
2880   }
2881 };
2882 
2883 // The portal class for org.rocksdb.WriteBatch.Handler
2884 class WriteBatchHandlerJni
2885     : public RocksDBNativeClass<
2886           const ROCKSDB_NAMESPACE::WriteBatchHandlerJniCallback*,
2887           WriteBatchHandlerJni> {
2888  public:
2889   /**
2890    * Get the Java Class org.rocksdb.WriteBatch.Handler
2891    *
2892    * @param env A pointer to the Java environment
2893    *
2894    * @return The Java Class or nullptr if one of the
2895    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
2896    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
2897    */
getJClass(JNIEnv * env)2898   static jclass getJClass(JNIEnv* env) {
2899     return RocksDBNativeClass::getJClass(env,
2900         "org/rocksdb/WriteBatch$Handler");
2901   }
2902 
2903   /**
2904    * Get the Java Method: WriteBatch.Handler#put
2905    *
2906    * @param env A pointer to the Java environment
2907    *
2908    * @return The Java Method ID or nullptr if the class or method id could not
2909    *     be retrieved
2910    */
getPutCfMethodId(JNIEnv * env)2911   static jmethodID getPutCfMethodId(JNIEnv* env) {
2912     jclass jclazz = getJClass(env);
2913     if(jclazz == nullptr) {
2914       // exception occurred accessing class
2915       return nullptr;
2916     }
2917 
2918     static jmethodID mid = env->GetMethodID(jclazz, "put", "(I[B[B)V");
2919     assert(mid != nullptr);
2920     return mid;
2921   }
2922 
2923   /**
2924    * Get the Java Method: WriteBatch.Handler#put
2925    *
2926    * @param env A pointer to the Java environment
2927    *
2928    * @return The Java Method ID or nullptr if the class or method id could not
2929    *     be retrieved
2930    */
getPutMethodId(JNIEnv * env)2931   static jmethodID getPutMethodId(JNIEnv* env) {
2932     jclass jclazz = getJClass(env);
2933     if(jclazz == nullptr) {
2934       // exception occurred accessing class
2935       return nullptr;
2936     }
2937 
2938     static jmethodID mid = env->GetMethodID(jclazz, "put", "([B[B)V");
2939     assert(mid != nullptr);
2940     return mid;
2941   }
2942 
2943   /**
2944    * Get the Java Method: WriteBatch.Handler#merge
2945    *
2946    * @param env A pointer to the Java environment
2947    *
2948    * @return The Java Method ID or nullptr if the class or method id could not
2949    *     be retrieved
2950    */
getMergeCfMethodId(JNIEnv * env)2951   static jmethodID getMergeCfMethodId(JNIEnv* env) {
2952     jclass jclazz = getJClass(env);
2953     if(jclazz == nullptr) {
2954       // exception occurred accessing class
2955       return nullptr;
2956     }
2957 
2958     static jmethodID mid = env->GetMethodID(jclazz, "merge", "(I[B[B)V");
2959     assert(mid != nullptr);
2960     return mid;
2961   }
2962 
2963   /**
2964    * Get the Java Method: WriteBatch.Handler#merge
2965    *
2966    * @param env A pointer to the Java environment
2967    *
2968    * @return The Java Method ID or nullptr if the class or method id could not
2969    *     be retrieved
2970    */
getMergeMethodId(JNIEnv * env)2971   static jmethodID getMergeMethodId(JNIEnv* env) {
2972     jclass jclazz = getJClass(env);
2973     if(jclazz == nullptr) {
2974       // exception occurred accessing class
2975       return nullptr;
2976     }
2977 
2978     static jmethodID mid = env->GetMethodID(jclazz, "merge", "([B[B)V");
2979     assert(mid != nullptr);
2980     return mid;
2981   }
2982 
2983   /**
2984    * Get the Java Method: WriteBatch.Handler#delete
2985    *
2986    * @param env A pointer to the Java environment
2987    *
2988    * @return The Java Method ID or nullptr if the class or method id could not
2989    *     be retrieved
2990    */
getDeleteCfMethodId(JNIEnv * env)2991   static jmethodID getDeleteCfMethodId(JNIEnv* env) {
2992     jclass jclazz = getJClass(env);
2993     if(jclazz == nullptr) {
2994       // exception occurred accessing class
2995       return nullptr;
2996     }
2997 
2998     static jmethodID mid = env->GetMethodID(jclazz, "delete", "(I[B)V");
2999     assert(mid != nullptr);
3000     return mid;
3001   }
3002 
3003   /**
3004    * Get the Java Method: WriteBatch.Handler#delete
3005    *
3006    * @param env A pointer to the Java environment
3007    *
3008    * @return The Java Method ID or nullptr if the class or method id could not
3009    *     be retrieved
3010    */
getDeleteMethodId(JNIEnv * env)3011   static jmethodID getDeleteMethodId(JNIEnv* env) {
3012     jclass jclazz = getJClass(env);
3013     if(jclazz == nullptr) {
3014       // exception occurred accessing class
3015       return nullptr;
3016     }
3017 
3018     static jmethodID mid = env->GetMethodID(jclazz, "delete", "([B)V");
3019     assert(mid != nullptr);
3020     return mid;
3021   }
3022 
3023   /**
3024    * Get the Java Method: WriteBatch.Handler#singleDelete
3025    *
3026    * @param env A pointer to the Java environment
3027    *
3028    * @return The Java Method ID or nullptr if the class or method id could not
3029    *     be retrieved
3030    */
getSingleDeleteCfMethodId(JNIEnv * env)3031   static jmethodID getSingleDeleteCfMethodId(JNIEnv* env) {
3032     jclass jclazz = getJClass(env);
3033     if(jclazz == nullptr) {
3034       // exception occurred accessing class
3035       return nullptr;
3036     }
3037 
3038     static jmethodID mid = env->GetMethodID(jclazz, "singleDelete", "(I[B)V");
3039     assert(mid != nullptr);
3040     return mid;
3041   }
3042 
3043   /**
3044    * Get the Java Method: WriteBatch.Handler#singleDelete
3045    *
3046    * @param env A pointer to the Java environment
3047    *
3048    * @return The Java Method ID or nullptr if the class or method id could not
3049    *     be retrieved
3050    */
getSingleDeleteMethodId(JNIEnv * env)3051   static jmethodID getSingleDeleteMethodId(JNIEnv* env) {
3052     jclass jclazz = getJClass(env);
3053     if(jclazz == nullptr) {
3054       // exception occurred accessing class
3055       return nullptr;
3056     }
3057 
3058     static jmethodID mid = env->GetMethodID(jclazz, "singleDelete", "([B)V");
3059     assert(mid != nullptr);
3060     return mid;
3061   }
3062 
3063   /**
3064    * Get the Java Method: WriteBatch.Handler#deleteRange
3065    *
3066    * @param env A pointer to the Java environment
3067    *
3068    * @return The Java Method ID or nullptr if the class or method id could not
3069    *     be retrieved
3070    */
getDeleteRangeCfMethodId(JNIEnv * env)3071   static jmethodID getDeleteRangeCfMethodId(JNIEnv* env) {
3072     jclass jclazz = getJClass(env);
3073     if (jclazz == nullptr) {
3074       // exception occurred accessing class
3075       return nullptr;
3076     }
3077 
3078     static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "(I[B[B)V");
3079     assert(mid != nullptr);
3080     return mid;
3081   }
3082 
3083   /**
3084    * Get the Java Method: WriteBatch.Handler#deleteRange
3085    *
3086    * @param env A pointer to the Java environment
3087    *
3088    * @return The Java Method ID or nullptr if the class or method id could not
3089    *     be retrieved
3090    */
getDeleteRangeMethodId(JNIEnv * env)3091   static jmethodID getDeleteRangeMethodId(JNIEnv* env) {
3092     jclass jclazz = getJClass(env);
3093     if (jclazz == nullptr) {
3094       // exception occurred accessing class
3095       return nullptr;
3096     }
3097 
3098     static jmethodID mid = env->GetMethodID(jclazz, "deleteRange", "([B[B)V");
3099     assert(mid != nullptr);
3100     return mid;
3101   }
3102 
3103   /**
3104    * Get the Java Method: WriteBatch.Handler#logData
3105    *
3106    * @param env A pointer to the Java environment
3107    *
3108    * @return The Java Method ID or nullptr if the class or method id could not
3109    *     be retrieved
3110    */
getLogDataMethodId(JNIEnv * env)3111   static jmethodID getLogDataMethodId(JNIEnv* env) {
3112     jclass jclazz = getJClass(env);
3113     if(jclazz == nullptr) {
3114       // exception occurred accessing class
3115       return nullptr;
3116     }
3117 
3118     static jmethodID mid = env->GetMethodID(jclazz, "logData", "([B)V");
3119     assert(mid != nullptr);
3120     return mid;
3121   }
3122 
3123   /**
3124    * Get the Java Method: WriteBatch.Handler#putBlobIndex
3125    *
3126    * @param env A pointer to the Java environment
3127    *
3128    * @return The Java Method ID or nullptr if the class or method id could not
3129    *     be retrieved
3130    */
getPutBlobIndexCfMethodId(JNIEnv * env)3131   static jmethodID getPutBlobIndexCfMethodId(JNIEnv* env) {
3132     jclass jclazz = getJClass(env);
3133     if(jclazz == nullptr) {
3134       // exception occurred accessing class
3135       return nullptr;
3136     }
3137 
3138     static jmethodID mid = env->GetMethodID(jclazz, "putBlobIndex", "(I[B[B)V");
3139     assert(mid != nullptr);
3140     return mid;
3141   }
3142 
3143   /**
3144    * Get the Java Method: WriteBatch.Handler#markBeginPrepare
3145    *
3146    * @param env A pointer to the Java environment
3147    *
3148    * @return The Java Method ID or nullptr if the class or method id could not
3149    *     be retrieved
3150    */
getMarkBeginPrepareMethodId(JNIEnv * env)3151   static jmethodID getMarkBeginPrepareMethodId(JNIEnv* env) {
3152     jclass jclazz = getJClass(env);
3153     if(jclazz == nullptr) {
3154       // exception occurred accessing class
3155       return nullptr;
3156     }
3157 
3158     static jmethodID mid = env->GetMethodID(jclazz, "markBeginPrepare", "()V");
3159     assert(mid != nullptr);
3160     return mid;
3161   }
3162 
3163   /**
3164    * Get the Java Method: WriteBatch.Handler#markEndPrepare
3165    *
3166    * @param env A pointer to the Java environment
3167    *
3168    * @return The Java Method ID or nullptr if the class or method id could not
3169    *     be retrieved
3170    */
getMarkEndPrepareMethodId(JNIEnv * env)3171   static jmethodID getMarkEndPrepareMethodId(JNIEnv* env) {
3172     jclass jclazz = getJClass(env);
3173     if(jclazz == nullptr) {
3174       // exception occurred accessing class
3175       return nullptr;
3176     }
3177 
3178     static jmethodID mid = env->GetMethodID(jclazz, "markEndPrepare", "([B)V");
3179     assert(mid != nullptr);
3180     return mid;
3181   }
3182 
3183   /**
3184    * Get the Java Method: WriteBatch.Handler#markNoop
3185    *
3186    * @param env A pointer to the Java environment
3187    *
3188    * @return The Java Method ID or nullptr if the class or method id could not
3189    *     be retrieved
3190    */
getMarkNoopMethodId(JNIEnv * env)3191   static jmethodID getMarkNoopMethodId(JNIEnv* env) {
3192     jclass jclazz = getJClass(env);
3193     if(jclazz == nullptr) {
3194       // exception occurred accessing class
3195       return nullptr;
3196     }
3197 
3198     static jmethodID mid = env->GetMethodID(jclazz, "markNoop", "(Z)V");
3199     assert(mid != nullptr);
3200     return mid;
3201   }
3202 
3203   /**
3204    * Get the Java Method: WriteBatch.Handler#markRollback
3205    *
3206    * @param env A pointer to the Java environment
3207    *
3208    * @return The Java Method ID or nullptr if the class or method id could not
3209    *     be retrieved
3210    */
getMarkRollbackMethodId(JNIEnv * env)3211   static jmethodID getMarkRollbackMethodId(JNIEnv* env) {
3212     jclass jclazz = getJClass(env);
3213     if(jclazz == nullptr) {
3214       // exception occurred accessing class
3215       return nullptr;
3216     }
3217 
3218     static jmethodID mid = env->GetMethodID(jclazz, "markRollback", "([B)V");
3219     assert(mid != nullptr);
3220     return mid;
3221   }
3222 
3223   /**
3224    * Get the Java Method: WriteBatch.Handler#markCommit
3225    *
3226    * @param env A pointer to the Java environment
3227    *
3228    * @return The Java Method ID or nullptr if the class or method id could not
3229    *     be retrieved
3230    */
getMarkCommitMethodId(JNIEnv * env)3231   static jmethodID getMarkCommitMethodId(JNIEnv* env) {
3232     jclass jclazz = getJClass(env);
3233     if(jclazz == nullptr) {
3234       // exception occurred accessing class
3235       return nullptr;
3236     }
3237 
3238     static jmethodID mid = env->GetMethodID(jclazz, "markCommit", "([B)V");
3239     assert(mid != nullptr);
3240     return mid;
3241   }
3242 
3243   /**
3244    * Get the Java Method: WriteBatch.Handler#shouldContinue
3245    *
3246    * @param env A pointer to the Java environment
3247    *
3248    * @return The Java Method ID or nullptr if the class or method id could not
3249    *     be retrieved
3250    */
getContinueMethodId(JNIEnv * env)3251   static jmethodID getContinueMethodId(JNIEnv* env) {
3252     jclass jclazz = getJClass(env);
3253     if(jclazz == nullptr) {
3254       // exception occurred accessing class
3255       return nullptr;
3256     }
3257 
3258     static jmethodID mid = env->GetMethodID(jclazz, "shouldContinue", "()Z");
3259     assert(mid != nullptr);
3260     return mid;
3261   }
3262 };
3263 
3264 class WriteBatchSavePointJni : public JavaClass {
3265  public:
3266   /**
3267    * Get the Java Class org.rocksdb.WriteBatch.SavePoint
3268    *
3269    * @param env A pointer to the Java environment
3270    *
3271    * @return The Java Class or nullptr if one of the
3272    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3273    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3274    */
getJClass(JNIEnv * env)3275   static jclass getJClass(JNIEnv* env) {
3276     return JavaClass::getJClass(env, "org/rocksdb/WriteBatch$SavePoint");
3277   }
3278 
3279   /**
3280    * Get the Java Method: HistogramData constructor
3281    *
3282    * @param env A pointer to the Java environment
3283    *
3284    * @return The Java Method ID or nullptr if the class or method id could not
3285    *     be retrieved
3286    */
getConstructorMethodId(JNIEnv * env)3287   static jmethodID getConstructorMethodId(JNIEnv* env) {
3288     jclass jclazz = getJClass(env);
3289     if(jclazz == nullptr) {
3290       // exception occurred accessing class
3291       return nullptr;
3292     }
3293 
3294     static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JJJ)V");
3295     assert(mid != nullptr);
3296     return mid;
3297   }
3298 
3299   /**
3300    * Create a new Java org.rocksdb.WriteBatch.SavePoint object
3301    *
3302    * @param env A pointer to the Java environment
3303    * @param savePoint A pointer to ROCKSDB_NAMESPACE::WriteBatch::SavePoint
3304    * object
3305    *
3306    * @return A reference to a Java org.rocksdb.WriteBatch.SavePoint object, or
3307    * nullptr if an an exception occurs
3308    */
construct(JNIEnv * env,const SavePoint & save_point)3309   static jobject construct(JNIEnv* env, const SavePoint &save_point) {
3310     jclass jclazz = getJClass(env);
3311     if(jclazz == nullptr) {
3312       // exception occurred accessing class
3313       return nullptr;
3314     }
3315 
3316     jmethodID mid = getConstructorMethodId(env);
3317     if (mid == nullptr) {
3318       // exception thrown: NoSuchMethodException or OutOfMemoryError
3319       return nullptr;
3320     }
3321 
3322     jobject jsave_point = env->NewObject(jclazz, mid,
3323         static_cast<jlong>(save_point.size),
3324         static_cast<jlong>(save_point.count),
3325         static_cast<jlong>(save_point.content_flags));
3326     if (env->ExceptionCheck()) {
3327       return nullptr;
3328     }
3329 
3330     return jsave_point;
3331   }
3332 };
3333 
3334 // The portal class for org.rocksdb.WriteBatchWithIndex
3335 class WriteBatchWithIndexJni
3336     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::WriteBatchWithIndex*,
3337                                 WriteBatchWithIndexJni> {
3338  public:
3339   /**
3340    * Get the Java Class org.rocksdb.WriteBatchWithIndex
3341    *
3342    * @param env A pointer to the Java environment
3343    *
3344    * @return The Java Class or nullptr if one of the
3345    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3346    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3347    */
getJClass(JNIEnv * env)3348   static jclass getJClass(JNIEnv* env) {
3349     return RocksDBNativeClass::getJClass(env,
3350         "org/rocksdb/WriteBatchWithIndex");
3351   }
3352 };
3353 
3354 // The portal class for org.rocksdb.HistogramData
3355 class HistogramDataJni : public JavaClass {
3356  public:
3357   /**
3358    * Get the Java Class org.rocksdb.HistogramData
3359    *
3360    * @param env A pointer to the Java environment
3361    *
3362    * @return The Java Class or nullptr if one of the
3363    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3364    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3365    */
getJClass(JNIEnv * env)3366   static jclass getJClass(JNIEnv* env) {
3367     return JavaClass::getJClass(env, "org/rocksdb/HistogramData");
3368   }
3369 
3370   /**
3371    * Get the Java Method: HistogramData constructor
3372    *
3373    * @param env A pointer to the Java environment
3374    *
3375    * @return The Java Method ID or nullptr if the class or method id could not
3376    *     be retrieved
3377    */
getConstructorMethodId(JNIEnv * env)3378   static jmethodID getConstructorMethodId(JNIEnv* env) {
3379     jclass jclazz = getJClass(env);
3380     if(jclazz == nullptr) {
3381       // exception occurred accessing class
3382       return nullptr;
3383     }
3384 
3385     static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(DDDDDDJJD)V");
3386     assert(mid != nullptr);
3387     return mid;
3388   }
3389 };
3390 
3391 // The portal class for org.rocksdb.BackupableDBOptions
3392 class BackupableDBOptionsJni
3393     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::BackupableDBOptions*,
3394                                 BackupableDBOptionsJni> {
3395  public:
3396   /**
3397    * Get the Java Class org.rocksdb.BackupableDBOptions
3398    *
3399    * @param env A pointer to the Java environment
3400    *
3401    * @return The Java Class or nullptr if one of the
3402    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3403    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3404    */
getJClass(JNIEnv * env)3405   static jclass getJClass(JNIEnv* env) {
3406     return RocksDBNativeClass::getJClass(env,
3407         "org/rocksdb/BackupableDBOptions");
3408   }
3409 };
3410 
3411 // The portal class for org.rocksdb.BackupEngine
3412 class BackupEngineJni
3413     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::BackupEngine*,
3414                                 BackupEngineJni> {
3415  public:
3416   /**
3417    * Get the Java Class org.rocksdb.BackupableEngine
3418    *
3419    * @param env A pointer to the Java environment
3420    *
3421    * @return The Java Class or nullptr if one of the
3422    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3423    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3424    */
getJClass(JNIEnv * env)3425   static jclass getJClass(JNIEnv* env) {
3426     return RocksDBNativeClass::getJClass(env, "org/rocksdb/BackupEngine");
3427   }
3428 };
3429 
3430 // The portal class for org.rocksdb.RocksIterator
3431 class IteratorJni
3432     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::Iterator*, IteratorJni> {
3433  public:
3434   /**
3435    * Get the Java Class org.rocksdb.RocksIterator
3436    *
3437    * @param env A pointer to the Java environment
3438    *
3439    * @return The Java Class or nullptr if one of the
3440    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3441    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3442    */
getJClass(JNIEnv * env)3443   static jclass getJClass(JNIEnv* env) {
3444     return RocksDBNativeClass::getJClass(env, "org/rocksdb/RocksIterator");
3445   }
3446 };
3447 
3448 // The portal class for org.rocksdb.Filter
3449 class FilterJni
3450     : public RocksDBNativeClass<
3451           std::shared_ptr<ROCKSDB_NAMESPACE::FilterPolicy>*, FilterJni> {
3452  public:
3453   /**
3454    * Get the Java Class org.rocksdb.Filter
3455    *
3456    * @param env A pointer to the Java environment
3457    *
3458    * @return The Java Class or nullptr if one of the
3459    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3460    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3461    */
getJClass(JNIEnv * env)3462   static jclass getJClass(JNIEnv* env) {
3463     return RocksDBNativeClass::getJClass(env, "org/rocksdb/Filter");
3464   }
3465 };
3466 
3467 // The portal class for org.rocksdb.ColumnFamilyHandle
3468 class ColumnFamilyHandleJni
3469     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
3470                                 ColumnFamilyHandleJni> {
3471  public:
fromCppColumnFamilyHandle(JNIEnv * env,const ROCKSDB_NAMESPACE::ColumnFamilyHandle * info)3472   static jobject fromCppColumnFamilyHandle(
3473       JNIEnv* env, const ROCKSDB_NAMESPACE::ColumnFamilyHandle* info) {
3474     jclass jclazz = getJClass(env);
3475     assert(jclazz != nullptr);
3476     static jmethodID ctor = getConstructorMethodId(env, jclazz);
3477     assert(ctor != nullptr);
3478     return env->NewObject(jclazz, ctor, reinterpret_cast<jlong>(info));
3479   }
3480 
getConstructorMethodId(JNIEnv * env,jclass clazz)3481   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
3482     return env->GetMethodID(clazz, "<init>", "(J)V");
3483   }
3484 
3485   /**
3486    * Get the Java Class org.rocksdb.ColumnFamilyHandle
3487    *
3488    * @param env A pointer to the Java environment
3489    *
3490    * @return The Java Class or nullptr if one of the
3491    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3492    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3493    */
getJClass(JNIEnv * env)3494   static jclass getJClass(JNIEnv* env) {
3495     return RocksDBNativeClass::getJClass(env,
3496         "org/rocksdb/ColumnFamilyHandle");
3497   }
3498 };
3499 
3500 // The portal class for org.rocksdb.FlushOptions
3501 class FlushOptionsJni
3502     : public RocksDBNativeClass<ROCKSDB_NAMESPACE::FlushOptions*,
3503                                 FlushOptionsJni> {
3504  public:
3505   /**
3506    * Get the Java Class org.rocksdb.FlushOptions
3507    *
3508    * @param env A pointer to the Java environment
3509    *
3510    * @return The Java Class or nullptr if one of the
3511    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3512    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3513    */
getJClass(JNIEnv * env)3514   static jclass getJClass(JNIEnv* env) {
3515     return RocksDBNativeClass::getJClass(env, "org/rocksdb/FlushOptions");
3516   }
3517 };
3518 
3519 // The portal class for org.rocksdb.ComparatorOptions
3520 class ComparatorOptionsJni
3521     : public RocksDBNativeClass<
3522           ROCKSDB_NAMESPACE::ComparatorJniCallbackOptions*,
3523           ComparatorOptionsJni> {
3524  public:
3525   /**
3526    * Get the Java Class org.rocksdb.ComparatorOptions
3527    *
3528    * @param env A pointer to the Java environment
3529    *
3530    * @return The Java Class or nullptr if one of the
3531    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3532    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3533    */
getJClass(JNIEnv * env)3534   static jclass getJClass(JNIEnv* env) {
3535     return RocksDBNativeClass::getJClass(env, "org/rocksdb/ComparatorOptions");
3536   }
3537 };
3538 
3539 // The portal class for org.rocksdb.AbstractCompactionFilterFactory
3540 class AbstractCompactionFilterFactoryJni
3541     : public RocksDBNativeClass<
3542           const ROCKSDB_NAMESPACE::CompactionFilterFactoryJniCallback*,
3543           AbstractCompactionFilterFactoryJni> {
3544  public:
3545   /**
3546    * Get the Java Class org.rocksdb.AbstractCompactionFilterFactory
3547    *
3548    * @param env A pointer to the Java environment
3549    *
3550    * @return The Java Class or nullptr if one of the
3551    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3552    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3553    */
getJClass(JNIEnv * env)3554   static jclass getJClass(JNIEnv* env) {
3555     return RocksDBNativeClass::getJClass(env,
3556         "org/rocksdb/AbstractCompactionFilterFactory");
3557   }
3558 
3559   /**
3560    * Get the Java Method: AbstractCompactionFilterFactory#name
3561    *
3562    * @param env A pointer to the Java environment
3563    *
3564    * @return The Java Method ID or nullptr if the class or method id could not
3565    *     be retrieved
3566    */
getNameMethodId(JNIEnv * env)3567   static jmethodID getNameMethodId(JNIEnv* env) {
3568     jclass jclazz = getJClass(env);
3569     if(jclazz == nullptr) {
3570       // exception occurred accessing class
3571       return nullptr;
3572     }
3573 
3574     static jmethodID mid = env->GetMethodID(
3575         jclazz, "name", "()Ljava/lang/String;");
3576     assert(mid != nullptr);
3577     return mid;
3578   }
3579 
3580   /**
3581    * Get the Java Method: AbstractCompactionFilterFactory#createCompactionFilter
3582    *
3583    * @param env A pointer to the Java environment
3584    *
3585    * @return The Java Method ID or nullptr if the class or method id could not
3586    *     be retrieved
3587    */
getCreateCompactionFilterMethodId(JNIEnv * env)3588   static jmethodID getCreateCompactionFilterMethodId(JNIEnv* env) {
3589     jclass jclazz = getJClass(env);
3590     if(jclazz == nullptr) {
3591       // exception occurred accessing class
3592       return nullptr;
3593     }
3594 
3595     static jmethodID mid = env->GetMethodID(jclazz,
3596       "createCompactionFilter",
3597       "(ZZ)J");
3598     assert(mid != nullptr);
3599     return mid;
3600   }
3601 };
3602 
3603 // The portal class for org.rocksdb.AbstractTransactionNotifier
3604 class AbstractTransactionNotifierJni
3605     : public RocksDBNativeClass<
3606           const ROCKSDB_NAMESPACE::TransactionNotifierJniCallback*,
3607           AbstractTransactionNotifierJni> {
3608  public:
getJClass(JNIEnv * env)3609   static jclass getJClass(JNIEnv* env) {
3610     return RocksDBNativeClass::getJClass(env,
3611         "org/rocksdb/AbstractTransactionNotifier");
3612   }
3613 
3614   // Get the java method `snapshotCreated`
3615   // of org.rocksdb.AbstractTransactionNotifier.
getSnapshotCreatedMethodId(JNIEnv * env)3616   static jmethodID getSnapshotCreatedMethodId(JNIEnv* env) {
3617     jclass jclazz = getJClass(env);
3618     if(jclazz == nullptr) {
3619       // exception occurred accessing class
3620       return nullptr;
3621     }
3622 
3623     static jmethodID mid = env->GetMethodID(jclazz, "snapshotCreated", "(J)V");
3624     assert(mid != nullptr);
3625     return mid;
3626   }
3627 };
3628 
3629 // The portal class for org.rocksdb.AbstractComparatorJniBridge
3630 class AbstractComparatorJniBridge : public JavaClass {
3631  public:
3632   /**
3633    * Get the Java Class org.rocksdb.AbstractComparatorJniBridge
3634    *
3635    * @param env A pointer to the Java environment
3636    *
3637    * @return The Java Class or nullptr if one of the
3638    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3639    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3640    */
getJClass(JNIEnv * env)3641   static jclass getJClass(JNIEnv* env) {
3642     return JavaClass::getJClass(env,
3643         "org/rocksdb/AbstractComparatorJniBridge");
3644   }
3645 
3646   /**
3647    * Get the Java Method: Comparator#compareInternal
3648    *
3649    * @param env A pointer to the Java environment
3650    * @param jclazz the AbstractComparatorJniBridge class
3651    *
3652    * @return The Java Method ID or nullptr if the class or method id could not
3653    *     be retrieved
3654    */
getCompareInternalMethodId(JNIEnv * env,jclass jclazz)3655   static jmethodID getCompareInternalMethodId(JNIEnv* env, jclass jclazz) {
3656     static jmethodID mid =
3657         env->GetStaticMethodID(jclazz, "compareInternal",
3658             "(Lorg/rocksdb/AbstractComparator;Ljava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)I");
3659     assert(mid != nullptr);
3660     return mid;
3661   }
3662 
3663   /**
3664    * Get the Java Method: Comparator#findShortestSeparatorInternal
3665    *
3666    * @param env A pointer to the Java environment
3667    * @param jclazz the AbstractComparatorJniBridge class
3668    *
3669    * @return The Java Method ID or nullptr if the class or method id could not
3670    *     be retrieved
3671    */
getFindShortestSeparatorInternalMethodId(JNIEnv * env,jclass jclazz)3672   static jmethodID getFindShortestSeparatorInternalMethodId(JNIEnv* env, jclass jclazz) {
3673     static jmethodID mid =
3674         env->GetStaticMethodID(jclazz, "findShortestSeparatorInternal",
3675             "(Lorg/rocksdb/AbstractComparator;Ljava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)I");
3676     assert(mid != nullptr);
3677     return mid;
3678   }
3679 
3680   /**
3681    * Get the Java Method: Comparator#findShortSuccessorInternal
3682    *
3683    * @param env A pointer to the Java environment
3684    * @param jclazz the AbstractComparatorJniBridge class
3685    *
3686    * @return The Java Method ID or nullptr if the class or method id could not
3687    *     be retrieved
3688    */
getFindShortSuccessorInternalMethodId(JNIEnv * env,jclass jclazz)3689   static jmethodID getFindShortSuccessorInternalMethodId(JNIEnv* env, jclass jclazz) {
3690     static jmethodID mid =
3691         env->GetStaticMethodID(jclazz, "findShortSuccessorInternal",
3692             "(Lorg/rocksdb/AbstractComparator;Ljava/nio/ByteBuffer;I)I");
3693     assert(mid != nullptr);
3694     return mid;
3695   }
3696 };
3697 
3698 // The portal class for org.rocksdb.AbstractComparator
3699 class AbstractComparatorJni
3700     : public RocksDBNativeClass<const ROCKSDB_NAMESPACE::ComparatorJniCallback*,
3701                                 AbstractComparatorJni> {
3702  public:
3703   /**
3704    * Get the Java Class org.rocksdb.AbstractComparator
3705    *
3706    * @param env A pointer to the Java environment
3707    *
3708    * @return The Java Class or nullptr if one of the
3709    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3710    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3711    */
getJClass(JNIEnv * env)3712   static jclass getJClass(JNIEnv* env) {
3713     return RocksDBNativeClass::getJClass(env,
3714         "org/rocksdb/AbstractComparator");
3715   }
3716 
3717   /**
3718    * Get the Java Method: Comparator#name
3719    *
3720    * @param env A pointer to the Java environment
3721    *
3722    * @return The Java Method ID or nullptr if the class or method id could not
3723    *     be retrieved
3724    */
getNameMethodId(JNIEnv * env)3725   static jmethodID getNameMethodId(JNIEnv* env) {
3726     jclass jclazz = getJClass(env);
3727     if(jclazz == nullptr) {
3728       // exception occurred accessing class
3729       return nullptr;
3730     }
3731 
3732     static jmethodID mid =
3733         env->GetMethodID(jclazz, "name", "()Ljava/lang/String;");
3734     assert(mid != nullptr);
3735     return mid;
3736   }
3737 };
3738 
3739 // The portal class for org.rocksdb.AbstractSlice
3740 class AbstractSliceJni
3741     : public NativeRocksMutableObject<const ROCKSDB_NAMESPACE::Slice*,
3742                                       AbstractSliceJni> {
3743  public:
3744   /**
3745    * Get the Java Class org.rocksdb.AbstractSlice
3746    *
3747    * @param env A pointer to the Java environment
3748    *
3749    * @return The Java Class or nullptr if one of the
3750    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3751    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3752    */
getJClass(JNIEnv * env)3753   static jclass getJClass(JNIEnv* env) {
3754     return RocksDBNativeClass::getJClass(env, "org/rocksdb/AbstractSlice");
3755   }
3756 };
3757 
3758 // The portal class for org.rocksdb.Slice
3759 class SliceJni
3760     : public NativeRocksMutableObject<const ROCKSDB_NAMESPACE::Slice*,
3761                                       AbstractSliceJni> {
3762  public:
3763   /**
3764    * Get the Java Class org.rocksdb.Slice
3765    *
3766    * @param env A pointer to the Java environment
3767    *
3768    * @return The Java Class or nullptr if one of the
3769    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3770    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3771    */
getJClass(JNIEnv * env)3772   static jclass getJClass(JNIEnv* env) {
3773     return RocksDBNativeClass::getJClass(env, "org/rocksdb/Slice");
3774   }
3775 
3776   /**
3777    * Constructs a Slice object
3778    *
3779    * @param env A pointer to the Java environment
3780    *
3781    * @return A reference to a Java Slice object, or a nullptr if an
3782    *     exception occurs
3783    */
construct0(JNIEnv * env)3784   static jobject construct0(JNIEnv* env) {
3785     jclass jclazz = getJClass(env);
3786     if(jclazz == nullptr) {
3787       // exception occurred accessing class
3788       return nullptr;
3789     }
3790 
3791     static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
3792     if(mid == nullptr) {
3793       // exception occurred accessing method
3794       return nullptr;
3795     }
3796 
3797     jobject jslice = env->NewObject(jclazz, mid);
3798     if(env->ExceptionCheck()) {
3799       return nullptr;
3800     }
3801 
3802     return jslice;
3803   }
3804 };
3805 
3806 // The portal class for org.rocksdb.DirectSlice
3807 class DirectSliceJni
3808     : public NativeRocksMutableObject<const ROCKSDB_NAMESPACE::Slice*,
3809                                       AbstractSliceJni> {
3810  public:
3811   /**
3812    * Get the Java Class org.rocksdb.DirectSlice
3813    *
3814    * @param env A pointer to the Java environment
3815    *
3816    * @return The Java Class or nullptr if one of the
3817    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3818    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3819    */
getJClass(JNIEnv * env)3820   static jclass getJClass(JNIEnv* env) {
3821     return RocksDBNativeClass::getJClass(env, "org/rocksdb/DirectSlice");
3822   }
3823 
3824   /**
3825    * Constructs a DirectSlice object
3826    *
3827    * @param env A pointer to the Java environment
3828    *
3829    * @return A reference to a Java DirectSlice object, or a nullptr if an
3830    *     exception occurs
3831    */
construct0(JNIEnv * env)3832   static jobject construct0(JNIEnv* env) {
3833     jclass jclazz = getJClass(env);
3834     if(jclazz == nullptr) {
3835       // exception occurred accessing class
3836       return nullptr;
3837     }
3838 
3839     static jmethodID mid = env->GetMethodID(jclazz, "<init>", "()V");
3840     if(mid == nullptr) {
3841       // exception occurred accessing method
3842       return nullptr;
3843     }
3844 
3845     jobject jdirect_slice = env->NewObject(jclazz, mid);
3846     if(env->ExceptionCheck()) {
3847       return nullptr;
3848     }
3849 
3850     return jdirect_slice;
3851   }
3852 };
3853 
3854 // The portal class for org.rocksdb.BackupInfo
3855 class BackupInfoJni : public JavaClass {
3856  public:
3857   /**
3858    * Get the Java Class org.rocksdb.BackupInfo
3859    *
3860    * @param env A pointer to the Java environment
3861    *
3862    * @return The Java Class or nullptr if one of the
3863    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
3864    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
3865    */
getJClass(JNIEnv * env)3866   static jclass getJClass(JNIEnv* env) {
3867     return JavaClass::getJClass(env, "org/rocksdb/BackupInfo");
3868   }
3869 
3870   /**
3871    * Constructs a BackupInfo object
3872    *
3873    * @param env A pointer to the Java environment
3874    * @param backup_id id of the backup
3875    * @param timestamp timestamp of the backup
3876    * @param size size of the backup
3877    * @param number_files number of files related to the backup
3878    * @param app_metadata application specific metadata
3879    *
3880    * @return A reference to a Java BackupInfo object, or a nullptr if an
3881    *     exception occurs
3882    */
construct0(JNIEnv * env,uint32_t backup_id,int64_t timestamp,uint64_t size,uint32_t number_files,const std::string & app_metadata)3883   static jobject construct0(JNIEnv* env, uint32_t backup_id, int64_t timestamp,
3884                             uint64_t size, uint32_t number_files,
3885                             const std::string& app_metadata) {
3886     jclass jclazz = getJClass(env);
3887     if(jclazz == nullptr) {
3888       // exception occurred accessing class
3889       return nullptr;
3890     }
3891 
3892     static jmethodID mid =
3893         env->GetMethodID(jclazz, "<init>", "(IJJILjava/lang/String;)V");
3894     if(mid == nullptr) {
3895       // exception occurred accessing method
3896       return nullptr;
3897     }
3898 
3899     jstring japp_metadata = nullptr;
3900     if (app_metadata != nullptr) {
3901       japp_metadata = env->NewStringUTF(app_metadata.c_str());
3902       if (japp_metadata == nullptr) {
3903         // exception occurred creating java string
3904         return nullptr;
3905       }
3906     }
3907 
3908     jobject jbackup_info = env->NewObject(jclazz, mid, backup_id, timestamp,
3909                                           size, number_files, japp_metadata);
3910     if(env->ExceptionCheck()) {
3911       env->DeleteLocalRef(japp_metadata);
3912       return nullptr;
3913     }
3914 
3915     return jbackup_info;
3916   }
3917 };
3918 
3919 class BackupInfoListJni {
3920  public:
3921   /**
3922    * Converts a C++ std::vector<BackupInfo> object to
3923    * a Java ArrayList<org.rocksdb.BackupInfo> object
3924    *
3925    * @param env A pointer to the Java environment
3926    * @param backup_infos A vector of BackupInfo
3927    *
3928    * @return Either a reference to a Java ArrayList object, or a nullptr
3929    *     if an exception occurs
3930    */
getBackupInfo(JNIEnv * env,std::vector<BackupInfo> backup_infos)3931   static jobject getBackupInfo(JNIEnv* env,
3932       std::vector<BackupInfo> backup_infos) {
3933     jclass jarray_list_clazz =
3934         ROCKSDB_NAMESPACE::ListJni::getArrayListClass(env);
3935     if(jarray_list_clazz == nullptr) {
3936       // exception occurred accessing class
3937       return nullptr;
3938     }
3939 
3940     jmethodID cstr_mid =
3941         ROCKSDB_NAMESPACE::ListJni::getArrayListConstructorMethodId(env);
3942     if(cstr_mid == nullptr) {
3943       // exception occurred accessing method
3944       return nullptr;
3945     }
3946 
3947     jmethodID add_mid = ROCKSDB_NAMESPACE::ListJni::getListAddMethodId(env);
3948     if(add_mid == nullptr) {
3949       // exception occurred accessing method
3950       return nullptr;
3951     }
3952 
3953     // create java list
3954     jobject jbackup_info_handle_list =
3955         env->NewObject(jarray_list_clazz, cstr_mid, backup_infos.size());
3956     if(env->ExceptionCheck()) {
3957       // exception occurred constructing object
3958       return nullptr;
3959     }
3960 
3961     // insert in java list
3962     auto end = backup_infos.end();
3963     for (auto it = backup_infos.begin(); it != end; ++it) {
3964       auto backup_info = *it;
3965 
3966       jobject obj = ROCKSDB_NAMESPACE::BackupInfoJni::construct0(
3967           env, backup_info.backup_id, backup_info.timestamp, backup_info.size,
3968           backup_info.number_files, backup_info.app_metadata);
3969       if(env->ExceptionCheck()) {
3970         // exception occurred constructing object
3971         if(obj != nullptr) {
3972           env->DeleteLocalRef(obj);
3973         }
3974         if(jbackup_info_handle_list != nullptr) {
3975           env->DeleteLocalRef(jbackup_info_handle_list);
3976         }
3977         return nullptr;
3978       }
3979 
3980       jboolean rs =
3981           env->CallBooleanMethod(jbackup_info_handle_list, add_mid, obj);
3982       if(env->ExceptionCheck() || rs == JNI_FALSE) {
3983         // exception occurred calling method, or could not add
3984         if(obj != nullptr) {
3985           env->DeleteLocalRef(obj);
3986         }
3987         if(jbackup_info_handle_list != nullptr) {
3988           env->DeleteLocalRef(jbackup_info_handle_list);
3989         }
3990         return nullptr;
3991       }
3992     }
3993 
3994     return jbackup_info_handle_list;
3995   }
3996 };
3997 
3998 // The portal class for org.rocksdb.WBWIRocksIterator
3999 class WBWIRocksIteratorJni : public JavaClass {
4000  public:
4001   /**
4002    * Get the Java Class org.rocksdb.WBWIRocksIterator
4003    *
4004    * @param env A pointer to the Java environment
4005    *
4006    * @return The Java Class or nullptr if one of the
4007    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4008    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4009    */
getJClass(JNIEnv * env)4010   static jclass getJClass(JNIEnv* env) {
4011     return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator");
4012   }
4013 
4014   /**
4015    * Get the Java Field: WBWIRocksIterator#entry
4016    *
4017    * @param env A pointer to the Java environment
4018    *
4019    * @return The Java Field ID or nullptr if the class or field id could not
4020    *     be retrieved
4021    */
getWriteEntryField(JNIEnv * env)4022   static jfieldID getWriteEntryField(JNIEnv* env) {
4023     jclass jclazz = getJClass(env);
4024     if(jclazz == nullptr) {
4025       // exception occurred accessing class
4026       return nullptr;
4027     }
4028 
4029     static jfieldID fid =
4030         env->GetFieldID(jclazz, "entry",
4031             "Lorg/rocksdb/WBWIRocksIterator$WriteEntry;");
4032     assert(fid != nullptr);
4033     return fid;
4034   }
4035 
4036   /**
4037    * Gets the value of the WBWIRocksIterator#entry
4038    *
4039    * @param env A pointer to the Java environment
4040    * @param jwbwi_rocks_iterator A reference to a WBWIIterator
4041    *
4042    * @return A reference to a Java WBWIRocksIterator.WriteEntry object, or
4043    *     a nullptr if an exception occurs
4044    */
getWriteEntry(JNIEnv * env,jobject jwbwi_rocks_iterator)4045   static jobject getWriteEntry(JNIEnv* env, jobject jwbwi_rocks_iterator) {
4046     assert(jwbwi_rocks_iterator != nullptr);
4047 
4048     jfieldID jwrite_entry_field = getWriteEntryField(env);
4049     if(jwrite_entry_field == nullptr) {
4050       // exception occurred accessing the field
4051       return nullptr;
4052     }
4053 
4054     jobject jwe = env->GetObjectField(jwbwi_rocks_iterator, jwrite_entry_field);
4055     assert(jwe != nullptr);
4056     return jwe;
4057   }
4058 };
4059 
4060 // The portal class for org.rocksdb.WBWIRocksIterator.WriteType
4061 class WriteTypeJni : public JavaClass {
4062  public:
4063   /**
4064    * Get the PUT enum field value of WBWIRocksIterator.WriteType
4065    *
4066    * @param env A pointer to the Java environment
4067    *
4068    * @return A reference to the enum field value or a nullptr if
4069    *     the enum field value could not be retrieved
4070    */
PUT(JNIEnv * env)4071   static jobject PUT(JNIEnv* env) {
4072     return getEnum(env, "PUT");
4073   }
4074 
4075   /**
4076    * Get the MERGE enum field value of WBWIRocksIterator.WriteType
4077    *
4078    * @param env A pointer to the Java environment
4079    *
4080    * @return A reference to the enum field value or a nullptr if
4081    *     the enum field value could not be retrieved
4082    */
MERGE(JNIEnv * env)4083   static jobject MERGE(JNIEnv* env) {
4084     return getEnum(env, "MERGE");
4085   }
4086 
4087   /**
4088    * Get the DELETE enum field value of WBWIRocksIterator.WriteType
4089    *
4090    * @param env A pointer to the Java environment
4091    *
4092    * @return A reference to the enum field value or a nullptr if
4093    *     the enum field value could not be retrieved
4094    */
DELETE(JNIEnv * env)4095   static jobject DELETE(JNIEnv* env) {
4096     return getEnum(env, "DELETE");
4097   }
4098 
4099   /**
4100    * Get the LOG enum field value of WBWIRocksIterator.WriteType
4101    *
4102    * @param env A pointer to the Java environment
4103    *
4104    * @return A reference to the enum field value or a nullptr if
4105    *     the enum field value could not be retrieved
4106    */
LOG(JNIEnv * env)4107   static jobject LOG(JNIEnv* env) {
4108     return getEnum(env, "LOG");
4109   }
4110 
4111   // Returns the equivalent org.rocksdb.WBWIRocksIterator.WriteType for the
4112   // provided C++ ROCKSDB_NAMESPACE::WriteType enum
toJavaWriteType(const ROCKSDB_NAMESPACE::WriteType & writeType)4113   static jbyte toJavaWriteType(const ROCKSDB_NAMESPACE::WriteType& writeType) {
4114     switch (writeType) {
4115       case ROCKSDB_NAMESPACE::WriteType::kPutRecord:
4116         return 0x0;
4117       case ROCKSDB_NAMESPACE::WriteType::kMergeRecord:
4118         return 0x1;
4119       case ROCKSDB_NAMESPACE::WriteType::kDeleteRecord:
4120         return 0x2;
4121       case ROCKSDB_NAMESPACE::WriteType::kSingleDeleteRecord:
4122         return 0x3;
4123       case ROCKSDB_NAMESPACE::WriteType::kDeleteRangeRecord:
4124         return 0x4;
4125       case ROCKSDB_NAMESPACE::WriteType::kLogDataRecord:
4126         return 0x5;
4127       case ROCKSDB_NAMESPACE::WriteType::kXIDRecord:
4128         return 0x6;
4129       default:
4130         return 0x7F;  // undefined
4131     }
4132   }
4133 
4134  private:
4135   /**
4136    * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteType
4137    *
4138    * @param env A pointer to the Java environment
4139    *
4140    * @return The Java Class or nullptr if one of the
4141    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4142    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4143    */
getJClass(JNIEnv * env)4144   static jclass getJClass(JNIEnv* env) {
4145     return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteType");
4146   }
4147 
4148   /**
4149    * Get an enum field of org.rocksdb.WBWIRocksIterator.WriteType
4150    *
4151    * @param env A pointer to the Java environment
4152    * @param name The name of the enum field
4153    *
4154    * @return A reference to the enum field value or a nullptr if
4155    *     the enum field value could not be retrieved
4156    */
getEnum(JNIEnv * env,const char name[])4157   static jobject getEnum(JNIEnv* env, const char name[]) {
4158     jclass jclazz = getJClass(env);
4159     if(jclazz == nullptr) {
4160       // exception occurred accessing class
4161       return nullptr;
4162     }
4163 
4164     jfieldID jfid =
4165         env->GetStaticFieldID(jclazz, name,
4166             "Lorg/rocksdb/WBWIRocksIterator$WriteType;");
4167     if(env->ExceptionCheck()) {
4168       // exception occurred while getting field
4169       return nullptr;
4170     } else if(jfid == nullptr) {
4171       return nullptr;
4172     }
4173 
4174     jobject jwrite_type = env->GetStaticObjectField(jclazz, jfid);
4175     assert(jwrite_type != nullptr);
4176     return jwrite_type;
4177   }
4178 };
4179 
4180 // The portal class for org.rocksdb.WBWIRocksIterator.WriteEntry
4181 class WriteEntryJni : public JavaClass {
4182  public:
4183   /**
4184    * Get the Java Class org.rocksdb.WBWIRocksIterator.WriteEntry
4185    *
4186    * @param env A pointer to the Java environment
4187    *
4188    * @return The Java Class or nullptr if one of the
4189    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4190    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4191    */
getJClass(JNIEnv * env)4192     static jclass getJClass(JNIEnv* env) {
4193       return JavaClass::getJClass(env, "org/rocksdb/WBWIRocksIterator$WriteEntry");
4194     }
4195 };
4196 
4197 // The portal class for org.rocksdb.InfoLogLevel
4198 class InfoLogLevelJni : public JavaClass {
4199  public:
4200     /**
4201      * Get the DEBUG_LEVEL enum field value of InfoLogLevel
4202      *
4203      * @param env A pointer to the Java environment
4204      *
4205      * @return A reference to the enum field value or a nullptr if
4206      *     the enum field value could not be retrieved
4207      */
DEBUG_LEVEL(JNIEnv * env)4208     static jobject DEBUG_LEVEL(JNIEnv* env) {
4209       return getEnum(env, "DEBUG_LEVEL");
4210     }
4211 
4212     /**
4213      * Get the INFO_LEVEL enum field value of InfoLogLevel
4214      *
4215      * @param env A pointer to the Java environment
4216      *
4217      * @return A reference to the enum field value or a nullptr if
4218      *     the enum field value could not be retrieved
4219      */
INFO_LEVEL(JNIEnv * env)4220     static jobject INFO_LEVEL(JNIEnv* env) {
4221       return getEnum(env, "INFO_LEVEL");
4222     }
4223 
4224     /**
4225      * Get the WARN_LEVEL enum field value of InfoLogLevel
4226      *
4227      * @param env A pointer to the Java environment
4228      *
4229      * @return A reference to the enum field value or a nullptr if
4230      *     the enum field value could not be retrieved
4231      */
WARN_LEVEL(JNIEnv * env)4232     static jobject WARN_LEVEL(JNIEnv* env) {
4233       return getEnum(env, "WARN_LEVEL");
4234     }
4235 
4236     /**
4237      * Get the ERROR_LEVEL enum field value of InfoLogLevel
4238      *
4239      * @param env A pointer to the Java environment
4240      *
4241      * @return A reference to the enum field value or a nullptr if
4242      *     the enum field value could not be retrieved
4243      */
ERROR_LEVEL(JNIEnv * env)4244     static jobject ERROR_LEVEL(JNIEnv* env) {
4245       return getEnum(env, "ERROR_LEVEL");
4246     }
4247 
4248     /**
4249      * Get the FATAL_LEVEL enum field value of InfoLogLevel
4250      *
4251      * @param env A pointer to the Java environment
4252      *
4253      * @return A reference to the enum field value or a nullptr if
4254      *     the enum field value could not be retrieved
4255      */
FATAL_LEVEL(JNIEnv * env)4256     static jobject FATAL_LEVEL(JNIEnv* env) {
4257       return getEnum(env, "FATAL_LEVEL");
4258     }
4259 
4260     /**
4261      * Get the HEADER_LEVEL enum field value of InfoLogLevel
4262      *
4263      * @param env A pointer to the Java environment
4264      *
4265      * @return A reference to the enum field value or a nullptr if
4266      *     the enum field value could not be retrieved
4267      */
HEADER_LEVEL(JNIEnv * env)4268     static jobject HEADER_LEVEL(JNIEnv* env) {
4269       return getEnum(env, "HEADER_LEVEL");
4270     }
4271 
4272  private:
4273   /**
4274    * Get the Java Class org.rocksdb.InfoLogLevel
4275    *
4276    * @param env A pointer to the Java environment
4277    *
4278    * @return The Java Class or nullptr if one of the
4279    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4280    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4281    */
getJClass(JNIEnv * env)4282   static jclass getJClass(JNIEnv* env) {
4283     return JavaClass::getJClass(env, "org/rocksdb/InfoLogLevel");
4284   }
4285 
4286   /**
4287    * Get an enum field of org.rocksdb.InfoLogLevel
4288    *
4289    * @param env A pointer to the Java environment
4290    * @param name The name of the enum field
4291    *
4292    * @return A reference to the enum field value or a nullptr if
4293    *     the enum field value could not be retrieved
4294    */
getEnum(JNIEnv * env,const char name[])4295   static jobject getEnum(JNIEnv* env, const char name[]) {
4296     jclass jclazz = getJClass(env);
4297     if(jclazz == nullptr) {
4298       // exception occurred accessing class
4299       return nullptr;
4300     }
4301 
4302     jfieldID jfid =
4303         env->GetStaticFieldID(jclazz, name, "Lorg/rocksdb/InfoLogLevel;");
4304     if(env->ExceptionCheck()) {
4305       // exception occurred while getting field
4306       return nullptr;
4307     } else if(jfid == nullptr) {
4308       return nullptr;
4309     }
4310 
4311     jobject jinfo_log_level = env->GetStaticObjectField(jclazz, jfid);
4312     assert(jinfo_log_level != nullptr);
4313     return jinfo_log_level;
4314   }
4315 };
4316 
4317 // The portal class for org.rocksdb.Logger
4318 class LoggerJni
4319     : public RocksDBNativeClass<
4320           std::shared_ptr<ROCKSDB_NAMESPACE::LoggerJniCallback>*, LoggerJni> {
4321  public:
4322   /**
4323    * Get the Java Class org/rocksdb/Logger
4324    *
4325    * @param env A pointer to the Java environment
4326    *
4327    * @return The Java Class or nullptr if one of the
4328    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4329    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4330    */
getJClass(JNIEnv * env)4331   static jclass getJClass(JNIEnv* env) {
4332     return RocksDBNativeClass::getJClass(env, "org/rocksdb/Logger");
4333   }
4334 
4335   /**
4336    * Get the Java Method: Logger#log
4337    *
4338    * @param env A pointer to the Java environment
4339    *
4340    * @return The Java Method ID or nullptr if the class or method id could not
4341    *     be retrieved
4342    */
getLogMethodId(JNIEnv * env)4343   static jmethodID getLogMethodId(JNIEnv* env) {
4344     jclass jclazz = getJClass(env);
4345     if(jclazz == nullptr) {
4346       // exception occurred accessing class
4347       return nullptr;
4348     }
4349 
4350     static jmethodID mid =
4351         env->GetMethodID(jclazz, "log",
4352             "(Lorg/rocksdb/InfoLogLevel;Ljava/lang/String;)V");
4353     assert(mid != nullptr);
4354     return mid;
4355   }
4356 };
4357 
4358 // The portal class for org.rocksdb.TransactionLogIterator.BatchResult
4359 class BatchResultJni : public JavaClass {
4360   public:
4361   /**
4362    * Get the Java Class org.rocksdb.TransactionLogIterator.BatchResult
4363    *
4364    * @param env A pointer to the Java environment
4365    *
4366    * @return The Java Class or nullptr if one of the
4367    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
4368    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
4369    */
getJClass(JNIEnv * env)4370   static jclass getJClass(JNIEnv* env) {
4371     return JavaClass::getJClass(env,
4372         "org/rocksdb/TransactionLogIterator$BatchResult");
4373   }
4374 
4375   /**
4376    * Create a new Java org.rocksdb.TransactionLogIterator.BatchResult object
4377    * with the same properties as the provided C++ ROCKSDB_NAMESPACE::BatchResult
4378    * object
4379    *
4380    * @param env A pointer to the Java environment
4381    * @param batch_result The ROCKSDB_NAMESPACE::BatchResult object
4382    *
4383    * @return A reference to a Java
4384    *     org.rocksdb.TransactionLogIterator.BatchResult object,
4385    *     or nullptr if an an exception occurs
4386    */
construct(JNIEnv * env,ROCKSDB_NAMESPACE::BatchResult & batch_result)4387   static jobject construct(JNIEnv* env,
4388                            ROCKSDB_NAMESPACE::BatchResult& batch_result) {
4389     jclass jclazz = getJClass(env);
4390     if(jclazz == nullptr) {
4391       // exception occurred accessing class
4392       return nullptr;
4393     }
4394 
4395     jmethodID mid = env->GetMethodID(
4396       jclazz, "<init>", "(JJ)V");
4397     if(mid == nullptr) {
4398       // exception thrown: NoSuchMethodException or OutOfMemoryError
4399       return nullptr;
4400     }
4401 
4402     jobject jbatch_result = env->NewObject(jclazz, mid,
4403       batch_result.sequence, batch_result.writeBatchPtr.get());
4404     if(jbatch_result == nullptr) {
4405       // exception thrown: InstantiationException or OutOfMemoryError
4406       return nullptr;
4407     }
4408 
4409     batch_result.writeBatchPtr.release();
4410     return jbatch_result;
4411   }
4412 };
4413 
4414 // The portal class for org.rocksdb.BottommostLevelCompaction
4415 class BottommostLevelCompactionJni {
4416  public:
4417   // Returns the equivalent org.rocksdb.BottommostLevelCompaction for the
4418   // provided C++ ROCKSDB_NAMESPACE::BottommostLevelCompaction enum
toJavaBottommostLevelCompaction(const ROCKSDB_NAMESPACE::BottommostLevelCompaction & bottommost_level_compaction)4419   static jint toJavaBottommostLevelCompaction(
4420       const ROCKSDB_NAMESPACE::BottommostLevelCompaction&
4421           bottommost_level_compaction) {
4422     switch(bottommost_level_compaction) {
4423       case ROCKSDB_NAMESPACE::BottommostLevelCompaction::kSkip:
4424         return 0x0;
4425       case ROCKSDB_NAMESPACE::BottommostLevelCompaction::
4426           kIfHaveCompactionFilter:
4427         return 0x1;
4428       case ROCKSDB_NAMESPACE::BottommostLevelCompaction::kForce:
4429         return 0x2;
4430       case ROCKSDB_NAMESPACE::BottommostLevelCompaction::kForceOptimized:
4431         return 0x3;
4432       default:
4433         return 0x7F;  // undefined
4434     }
4435   }
4436 
4437   // Returns the equivalent C++ ROCKSDB_NAMESPACE::BottommostLevelCompaction
4438   // enum for the provided Java org.rocksdb.BottommostLevelCompaction
4439   static ROCKSDB_NAMESPACE::BottommostLevelCompaction
toCppBottommostLevelCompaction(jint bottommost_level_compaction)4440   toCppBottommostLevelCompaction(jint bottommost_level_compaction) {
4441     switch(bottommost_level_compaction) {
4442       case 0x0:
4443         return ROCKSDB_NAMESPACE::BottommostLevelCompaction::kSkip;
4444       case 0x1:
4445         return ROCKSDB_NAMESPACE::BottommostLevelCompaction::
4446             kIfHaveCompactionFilter;
4447       case 0x2:
4448         return ROCKSDB_NAMESPACE::BottommostLevelCompaction::kForce;
4449       case 0x3:
4450         return ROCKSDB_NAMESPACE::BottommostLevelCompaction::kForceOptimized;
4451       default:
4452         // undefined/default
4453         return ROCKSDB_NAMESPACE::BottommostLevelCompaction::
4454             kIfHaveCompactionFilter;
4455     }
4456   }
4457 };
4458 
4459 // The portal class for org.rocksdb.CompactionStopStyle
4460 class CompactionStopStyleJni {
4461  public:
4462   // Returns the equivalent org.rocksdb.CompactionStopStyle for the provided
4463   // C++ ROCKSDB_NAMESPACE::CompactionStopStyle enum
toJavaCompactionStopStyle(const ROCKSDB_NAMESPACE::CompactionStopStyle & compaction_stop_style)4464   static jbyte toJavaCompactionStopStyle(
4465       const ROCKSDB_NAMESPACE::CompactionStopStyle& compaction_stop_style) {
4466     switch(compaction_stop_style) {
4467       case ROCKSDB_NAMESPACE::CompactionStopStyle::
4468           kCompactionStopStyleSimilarSize:
4469         return 0x0;
4470       case ROCKSDB_NAMESPACE::CompactionStopStyle::
4471           kCompactionStopStyleTotalSize:
4472         return 0x1;
4473       default:
4474         return 0x7F;  // undefined
4475     }
4476   }
4477 
4478   // Returns the equivalent C++ ROCKSDB_NAMESPACE::CompactionStopStyle enum for
4479   // the provided Java org.rocksdb.CompactionStopStyle
toCppCompactionStopStyle(jbyte jcompaction_stop_style)4480   static ROCKSDB_NAMESPACE::CompactionStopStyle toCppCompactionStopStyle(
4481       jbyte jcompaction_stop_style) {
4482     switch(jcompaction_stop_style) {
4483       case 0x0:
4484         return ROCKSDB_NAMESPACE::CompactionStopStyle::
4485             kCompactionStopStyleSimilarSize;
4486       case 0x1:
4487         return ROCKSDB_NAMESPACE::CompactionStopStyle::
4488             kCompactionStopStyleTotalSize;
4489       default:
4490         // undefined/default
4491         return ROCKSDB_NAMESPACE::CompactionStopStyle::
4492             kCompactionStopStyleSimilarSize;
4493     }
4494   }
4495 };
4496 
4497 // The portal class for org.rocksdb.CompressionType
4498 class CompressionTypeJni {
4499  public:
4500   // Returns the equivalent org.rocksdb.CompressionType for the provided
4501   // C++ ROCKSDB_NAMESPACE::CompressionType enum
toJavaCompressionType(const ROCKSDB_NAMESPACE::CompressionType & compression_type)4502   static jbyte toJavaCompressionType(
4503       const ROCKSDB_NAMESPACE::CompressionType& compression_type) {
4504     switch(compression_type) {
4505       case ROCKSDB_NAMESPACE::CompressionType::kNoCompression:
4506         return 0x0;
4507       case ROCKSDB_NAMESPACE::CompressionType::kSnappyCompression:
4508         return 0x1;
4509       case ROCKSDB_NAMESPACE::CompressionType::kZlibCompression:
4510         return 0x2;
4511       case ROCKSDB_NAMESPACE::CompressionType::kBZip2Compression:
4512         return 0x3;
4513       case ROCKSDB_NAMESPACE::CompressionType::kLZ4Compression:
4514         return 0x4;
4515       case ROCKSDB_NAMESPACE::CompressionType::kLZ4HCCompression:
4516         return 0x5;
4517       case ROCKSDB_NAMESPACE::CompressionType::kXpressCompression:
4518         return 0x6;
4519       case ROCKSDB_NAMESPACE::CompressionType::kZSTD:
4520         return 0x7;
4521       case ROCKSDB_NAMESPACE::CompressionType::kDisableCompressionOption:
4522       default:
4523         return 0x7F;
4524     }
4525   }
4526 
4527   // Returns the equivalent C++ ROCKSDB_NAMESPACE::CompressionType enum for the
4528   // provided Java org.rocksdb.CompressionType
toCppCompressionType(jbyte jcompression_type)4529   static ROCKSDB_NAMESPACE::CompressionType toCppCompressionType(
4530       jbyte jcompression_type) {
4531     switch(jcompression_type) {
4532       case 0x0:
4533         return ROCKSDB_NAMESPACE::CompressionType::kNoCompression;
4534       case 0x1:
4535         return ROCKSDB_NAMESPACE::CompressionType::kSnappyCompression;
4536       case 0x2:
4537         return ROCKSDB_NAMESPACE::CompressionType::kZlibCompression;
4538       case 0x3:
4539         return ROCKSDB_NAMESPACE::CompressionType::kBZip2Compression;
4540       case 0x4:
4541         return ROCKSDB_NAMESPACE::CompressionType::kLZ4Compression;
4542       case 0x5:
4543         return ROCKSDB_NAMESPACE::CompressionType::kLZ4HCCompression;
4544       case 0x6:
4545         return ROCKSDB_NAMESPACE::CompressionType::kXpressCompression;
4546       case 0x7:
4547         return ROCKSDB_NAMESPACE::CompressionType::kZSTD;
4548       case 0x7F:
4549       default:
4550         return ROCKSDB_NAMESPACE::CompressionType::kDisableCompressionOption;
4551     }
4552   }
4553 };
4554 
4555 // The portal class for org.rocksdb.CompactionPriority
4556 class CompactionPriorityJni {
4557  public:
4558   // Returns the equivalent org.rocksdb.CompactionPriority for the provided
4559   // C++ ROCKSDB_NAMESPACE::CompactionPri enum
toJavaCompactionPriority(const ROCKSDB_NAMESPACE::CompactionPri & compaction_priority)4560   static jbyte toJavaCompactionPriority(
4561       const ROCKSDB_NAMESPACE::CompactionPri& compaction_priority) {
4562     switch(compaction_priority) {
4563       case ROCKSDB_NAMESPACE::CompactionPri::kByCompensatedSize:
4564         return 0x0;
4565       case ROCKSDB_NAMESPACE::CompactionPri::kOldestLargestSeqFirst:
4566         return 0x1;
4567       case ROCKSDB_NAMESPACE::CompactionPri::kOldestSmallestSeqFirst:
4568         return 0x2;
4569       case ROCKSDB_NAMESPACE::CompactionPri::kMinOverlappingRatio:
4570         return 0x3;
4571       default:
4572         return 0x0;  // undefined
4573     }
4574   }
4575 
4576   // Returns the equivalent C++ ROCKSDB_NAMESPACE::CompactionPri enum for the
4577   // provided Java org.rocksdb.CompactionPriority
toCppCompactionPriority(jbyte jcompaction_priority)4578   static ROCKSDB_NAMESPACE::CompactionPri toCppCompactionPriority(
4579       jbyte jcompaction_priority) {
4580     switch(jcompaction_priority) {
4581       case 0x0:
4582         return ROCKSDB_NAMESPACE::CompactionPri::kByCompensatedSize;
4583       case 0x1:
4584         return ROCKSDB_NAMESPACE::CompactionPri::kOldestLargestSeqFirst;
4585       case 0x2:
4586         return ROCKSDB_NAMESPACE::CompactionPri::kOldestSmallestSeqFirst;
4587       case 0x3:
4588         return ROCKSDB_NAMESPACE::CompactionPri::kMinOverlappingRatio;
4589       default:
4590         // undefined/default
4591         return ROCKSDB_NAMESPACE::CompactionPri::kByCompensatedSize;
4592     }
4593   }
4594 };
4595 
4596 // The portal class for org.rocksdb.AccessHint
4597 class AccessHintJni {
4598  public:
4599   // Returns the equivalent org.rocksdb.AccessHint for the provided
4600   // C++ ROCKSDB_NAMESPACE::DBOptions::AccessHint enum
toJavaAccessHint(const ROCKSDB_NAMESPACE::DBOptions::AccessHint & access_hint)4601   static jbyte toJavaAccessHint(
4602       const ROCKSDB_NAMESPACE::DBOptions::AccessHint& access_hint) {
4603     switch(access_hint) {
4604       case ROCKSDB_NAMESPACE::DBOptions::AccessHint::NONE:
4605         return 0x0;
4606       case ROCKSDB_NAMESPACE::DBOptions::AccessHint::NORMAL:
4607         return 0x1;
4608       case ROCKSDB_NAMESPACE::DBOptions::AccessHint::SEQUENTIAL:
4609         return 0x2;
4610       case ROCKSDB_NAMESPACE::DBOptions::AccessHint::WILLNEED:
4611         return 0x3;
4612       default:
4613         // undefined/default
4614         return 0x1;
4615     }
4616   }
4617 
4618   // Returns the equivalent C++ ROCKSDB_NAMESPACE::DBOptions::AccessHint enum
4619   // for the provided Java org.rocksdb.AccessHint
toCppAccessHint(jbyte jaccess_hint)4620   static ROCKSDB_NAMESPACE::DBOptions::AccessHint toCppAccessHint(
4621       jbyte jaccess_hint) {
4622     switch(jaccess_hint) {
4623       case 0x0:
4624         return ROCKSDB_NAMESPACE::DBOptions::AccessHint::NONE;
4625       case 0x1:
4626         return ROCKSDB_NAMESPACE::DBOptions::AccessHint::NORMAL;
4627       case 0x2:
4628         return ROCKSDB_NAMESPACE::DBOptions::AccessHint::SEQUENTIAL;
4629       case 0x3:
4630         return ROCKSDB_NAMESPACE::DBOptions::AccessHint::WILLNEED;
4631       default:
4632         // undefined/default
4633         return ROCKSDB_NAMESPACE::DBOptions::AccessHint::NORMAL;
4634     }
4635   }
4636 };
4637 
4638 // The portal class for org.rocksdb.WALRecoveryMode
4639 class WALRecoveryModeJni {
4640  public:
4641   // Returns the equivalent org.rocksdb.WALRecoveryMode for the provided
4642   // C++ ROCKSDB_NAMESPACE::WALRecoveryMode enum
toJavaWALRecoveryMode(const ROCKSDB_NAMESPACE::WALRecoveryMode & wal_recovery_mode)4643   static jbyte toJavaWALRecoveryMode(
4644       const ROCKSDB_NAMESPACE::WALRecoveryMode& wal_recovery_mode) {
4645     switch(wal_recovery_mode) {
4646       case ROCKSDB_NAMESPACE::WALRecoveryMode::kTolerateCorruptedTailRecords:
4647         return 0x0;
4648       case ROCKSDB_NAMESPACE::WALRecoveryMode::kAbsoluteConsistency:
4649         return 0x1;
4650       case ROCKSDB_NAMESPACE::WALRecoveryMode::kPointInTimeRecovery:
4651         return 0x2;
4652       case ROCKSDB_NAMESPACE::WALRecoveryMode::kSkipAnyCorruptedRecords:
4653         return 0x3;
4654       default:
4655         // undefined/default
4656         return 0x2;
4657     }
4658   }
4659 
4660   // Returns the equivalent C++ ROCKSDB_NAMESPACE::WALRecoveryMode enum for the
4661   // provided Java org.rocksdb.WALRecoveryMode
toCppWALRecoveryMode(jbyte jwal_recovery_mode)4662   static ROCKSDB_NAMESPACE::WALRecoveryMode toCppWALRecoveryMode(
4663       jbyte jwal_recovery_mode) {
4664     switch(jwal_recovery_mode) {
4665       case 0x0:
4666         return ROCKSDB_NAMESPACE::WALRecoveryMode::
4667             kTolerateCorruptedTailRecords;
4668       case 0x1:
4669         return ROCKSDB_NAMESPACE::WALRecoveryMode::kAbsoluteConsistency;
4670       case 0x2:
4671         return ROCKSDB_NAMESPACE::WALRecoveryMode::kPointInTimeRecovery;
4672       case 0x3:
4673         return ROCKSDB_NAMESPACE::WALRecoveryMode::kSkipAnyCorruptedRecords;
4674       default:
4675         // undefined/default
4676         return ROCKSDB_NAMESPACE::WALRecoveryMode::kPointInTimeRecovery;
4677     }
4678   }
4679 };
4680 
4681 // The portal class for org.rocksdb.TickerType
4682 class TickerTypeJni {
4683  public:
4684   // Returns the equivalent org.rocksdb.TickerType for the provided
4685   // C++ ROCKSDB_NAMESPACE::Tickers enum
toJavaTickerType(const ROCKSDB_NAMESPACE::Tickers & tickers)4686   static jbyte toJavaTickerType(const ROCKSDB_NAMESPACE::Tickers& tickers) {
4687     switch(tickers) {
4688       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_MISS:
4689         return 0x0;
4690       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_HIT:
4691         return 0x1;
4692       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_ADD:
4693         return 0x2;
4694       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_ADD_FAILURES:
4695         return 0x3;
4696       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_MISS:
4697         return 0x4;
4698       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_HIT:
4699         return 0x5;
4700       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_ADD:
4701         return 0x6;
4702       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_BYTES_INSERT:
4703         return 0x7;
4704       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_BYTES_EVICT:
4705         return 0x8;
4706       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_MISS:
4707         return 0x9;
4708       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_HIT:
4709         return 0xA;
4710       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_ADD:
4711         return 0xB;
4712       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_BYTES_INSERT:
4713         return 0xC;
4714       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_BYTES_EVICT:
4715         return 0xD;
4716       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_MISS:
4717         return 0xE;
4718       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_HIT:
4719         return 0xF;
4720       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_ADD:
4721         return 0x10;
4722       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT:
4723         return 0x11;
4724       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_BYTES_READ:
4725         return 0x12;
4726       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_BYTES_WRITE:
4727         return 0x13;
4728       case ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_USEFUL:
4729         return 0x14;
4730       case ROCKSDB_NAMESPACE::Tickers::PERSISTENT_CACHE_HIT:
4731         return 0x15;
4732       case ROCKSDB_NAMESPACE::Tickers::PERSISTENT_CACHE_MISS:
4733         return 0x16;
4734       case ROCKSDB_NAMESPACE::Tickers::SIM_BLOCK_CACHE_HIT:
4735         return 0x17;
4736       case ROCKSDB_NAMESPACE::Tickers::SIM_BLOCK_CACHE_MISS:
4737         return 0x18;
4738       case ROCKSDB_NAMESPACE::Tickers::MEMTABLE_HIT:
4739         return 0x19;
4740       case ROCKSDB_NAMESPACE::Tickers::MEMTABLE_MISS:
4741         return 0x1A;
4742       case ROCKSDB_NAMESPACE::Tickers::GET_HIT_L0:
4743         return 0x1B;
4744       case ROCKSDB_NAMESPACE::Tickers::GET_HIT_L1:
4745         return 0x1C;
4746       case ROCKSDB_NAMESPACE::Tickers::GET_HIT_L2_AND_UP:
4747         return 0x1D;
4748       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_NEWER_ENTRY:
4749         return 0x1E;
4750       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_OBSOLETE:
4751         return 0x1F;
4752       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_RANGE_DEL:
4753         return 0x20;
4754       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_USER:
4755         return 0x21;
4756       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_RANGE_DEL_DROP_OBSOLETE:
4757         return 0x22;
4758       case ROCKSDB_NAMESPACE::Tickers::NUMBER_KEYS_WRITTEN:
4759         return 0x23;
4760       case ROCKSDB_NAMESPACE::Tickers::NUMBER_KEYS_READ:
4761         return 0x24;
4762       case ROCKSDB_NAMESPACE::Tickers::NUMBER_KEYS_UPDATED:
4763         return 0x25;
4764       case ROCKSDB_NAMESPACE::Tickers::BYTES_WRITTEN:
4765         return 0x26;
4766       case ROCKSDB_NAMESPACE::Tickers::BYTES_READ:
4767         return 0x27;
4768       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_SEEK:
4769         return 0x28;
4770       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_NEXT:
4771         return 0x29;
4772       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_PREV:
4773         return 0x2A;
4774       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_SEEK_FOUND:
4775         return 0x2B;
4776       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_NEXT_FOUND:
4777         return 0x2C;
4778       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_PREV_FOUND:
4779         return 0x2D;
4780       case ROCKSDB_NAMESPACE::Tickers::ITER_BYTES_READ:
4781         return 0x2E;
4782       case ROCKSDB_NAMESPACE::Tickers::NO_FILE_CLOSES:
4783         return 0x2F;
4784       case ROCKSDB_NAMESPACE::Tickers::NO_FILE_OPENS:
4785         return 0x30;
4786       case ROCKSDB_NAMESPACE::Tickers::NO_FILE_ERRORS:
4787         return 0x31;
4788       case ROCKSDB_NAMESPACE::Tickers::STALL_L0_SLOWDOWN_MICROS:
4789         return 0x32;
4790       case ROCKSDB_NAMESPACE::Tickers::STALL_MEMTABLE_COMPACTION_MICROS:
4791         return 0x33;
4792       case ROCKSDB_NAMESPACE::Tickers::STALL_L0_NUM_FILES_MICROS:
4793         return 0x34;
4794       case ROCKSDB_NAMESPACE::Tickers::STALL_MICROS:
4795         return 0x35;
4796       case ROCKSDB_NAMESPACE::Tickers::DB_MUTEX_WAIT_MICROS:
4797         return 0x36;
4798       case ROCKSDB_NAMESPACE::Tickers::RATE_LIMIT_DELAY_MILLIS:
4799         return 0x37;
4800       case ROCKSDB_NAMESPACE::Tickers::NO_ITERATORS:
4801         return 0x38;
4802       case ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_CALLS:
4803         return 0x39;
4804       case ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_KEYS_READ:
4805         return 0x3A;
4806       case ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_BYTES_READ:
4807         return 0x3B;
4808       case ROCKSDB_NAMESPACE::Tickers::NUMBER_FILTERED_DELETES:
4809         return 0x3C;
4810       case ROCKSDB_NAMESPACE::Tickers::NUMBER_MERGE_FAILURES:
4811         return 0x3D;
4812       case ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_PREFIX_CHECKED:
4813         return 0x3E;
4814       case ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_PREFIX_USEFUL:
4815         return 0x3F;
4816       case ROCKSDB_NAMESPACE::Tickers::NUMBER_OF_RESEEKS_IN_ITERATION:
4817         return 0x40;
4818       case ROCKSDB_NAMESPACE::Tickers::GET_UPDATES_SINCE_CALLS:
4819         return 0x41;
4820       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_MISS:
4821         return 0x42;
4822       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_HIT:
4823         return 0x43;
4824       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_ADD:
4825         return 0x44;
4826       case ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_ADD_FAILURES:
4827         return 0x45;
4828       case ROCKSDB_NAMESPACE::Tickers::WAL_FILE_SYNCED:
4829         return 0x46;
4830       case ROCKSDB_NAMESPACE::Tickers::WAL_FILE_BYTES:
4831         return 0x47;
4832       case ROCKSDB_NAMESPACE::Tickers::WRITE_DONE_BY_SELF:
4833         return 0x48;
4834       case ROCKSDB_NAMESPACE::Tickers::WRITE_DONE_BY_OTHER:
4835         return 0x49;
4836       case ROCKSDB_NAMESPACE::Tickers::WRITE_TIMEDOUT:
4837         return 0x4A;
4838       case ROCKSDB_NAMESPACE::Tickers::WRITE_WITH_WAL:
4839         return 0x4B;
4840       case ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES:
4841         return 0x4C;
4842       case ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES:
4843         return 0x4D;
4844       case ROCKSDB_NAMESPACE::Tickers::FLUSH_WRITE_BYTES:
4845         return 0x4E;
4846       case ROCKSDB_NAMESPACE::Tickers::NUMBER_DIRECT_LOAD_TABLE_PROPERTIES:
4847         return 0x4F;
4848       case ROCKSDB_NAMESPACE::Tickers::NUMBER_SUPERVERSION_ACQUIRES:
4849         return 0x50;
4850       case ROCKSDB_NAMESPACE::Tickers::NUMBER_SUPERVERSION_RELEASES:
4851         return 0x51;
4852       case ROCKSDB_NAMESPACE::Tickers::NUMBER_SUPERVERSION_CLEANUPS:
4853         return 0x52;
4854       case ROCKSDB_NAMESPACE::Tickers::NUMBER_BLOCK_COMPRESSED:
4855         return 0x53;
4856       case ROCKSDB_NAMESPACE::Tickers::NUMBER_BLOCK_DECOMPRESSED:
4857         return 0x54;
4858       case ROCKSDB_NAMESPACE::Tickers::NUMBER_BLOCK_NOT_COMPRESSED:
4859         return 0x55;
4860       case ROCKSDB_NAMESPACE::Tickers::MERGE_OPERATION_TOTAL_TIME:
4861         return 0x56;
4862       case ROCKSDB_NAMESPACE::Tickers::FILTER_OPERATION_TOTAL_TIME:
4863         return 0x57;
4864       case ROCKSDB_NAMESPACE::Tickers::ROW_CACHE_HIT:
4865         return 0x58;
4866       case ROCKSDB_NAMESPACE::Tickers::ROW_CACHE_MISS:
4867         return 0x59;
4868       case ROCKSDB_NAMESPACE::Tickers::READ_AMP_ESTIMATE_USEFUL_BYTES:
4869         return 0x5A;
4870       case ROCKSDB_NAMESPACE::Tickers::READ_AMP_TOTAL_READ_BYTES:
4871         return 0x5B;
4872       case ROCKSDB_NAMESPACE::Tickers::NUMBER_RATE_LIMITER_DRAINS:
4873         return 0x5C;
4874       case ROCKSDB_NAMESPACE::Tickers::NUMBER_ITER_SKIP:
4875         return 0x5D;
4876       case ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_KEYS_FOUND:
4877         return 0x5E;
4878       case ROCKSDB_NAMESPACE::Tickers::NO_ITERATOR_CREATED:
4879         // -0x01 to fixate the new value that incorrectly changed TICKER_ENUM_MAX.
4880         return -0x01;
4881       case ROCKSDB_NAMESPACE::Tickers::NO_ITERATOR_DELETED:
4882         return 0x60;
4883       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_OPTIMIZED_DEL_DROP_OBSOLETE:
4884         return 0x61;
4885       case ROCKSDB_NAMESPACE::Tickers::COMPACTION_CANCELLED:
4886         return 0x62;
4887       case ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_FULL_POSITIVE:
4888         return 0x63;
4889       case ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_FULL_TRUE_POSITIVE:
4890         return 0x64;
4891       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_PUT:
4892         return 0x65;
4893       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_WRITE:
4894         return 0x66;
4895       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_GET:
4896         return 0x67;
4897       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_MULTIGET:
4898         return 0x68;
4899       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_SEEK:
4900         return 0x69;
4901       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_NEXT:
4902         return 0x6A;
4903       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_PREV:
4904         return 0x6B;
4905       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_KEYS_WRITTEN:
4906         return 0x6C;
4907       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_KEYS_READ:
4908         return 0x6D;
4909       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BYTES_WRITTEN:
4910         return 0x6E;
4911       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BYTES_READ:
4912         return 0x6F;
4913       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_INLINED:
4914         return 0x70;
4915       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_INLINED_TTL:
4916         return 0x71;
4917       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_BLOB:
4918         return 0x72;
4919       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_BLOB_TTL:
4920         return 0x73;
4921       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_FILE_BYTES_WRITTEN:
4922         return 0x74;
4923       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_FILE_BYTES_READ:
4924         return 0x75;
4925       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_FILE_SYNCED:
4926         return 0x76;
4927       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_COUNT:
4928         return 0x77;
4929       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_SIZE:
4930         return 0x78;
4931       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_COUNT:
4932         return 0x79;
4933       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_SIZE:
4934         return 0x7A;
4935       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_FILES:
4936         return 0x7B;
4937       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_NEW_FILES:
4938         return 0x7C;
4939       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_FAILURES:
4940         return 0x7D;
4941       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_KEYS_OVERWRITTEN:
4942         return 0x7E;
4943       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_KEYS_EXPIRED:
4944         return 0x7F;
4945       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_KEYS_RELOCATED:
4946         return -0x02;
4947       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_BYTES_OVERWRITTEN:
4948         return -0x03;
4949       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_BYTES_EXPIRED:
4950         return -0x04;
4951       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_BYTES_RELOCATED:
4952         return -0x05;
4953       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_FIFO_NUM_FILES_EVICTED:
4954         return -0x06;
4955       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_FIFO_NUM_KEYS_EVICTED:
4956         return -0x07;
4957       case ROCKSDB_NAMESPACE::Tickers::BLOB_DB_FIFO_BYTES_EVICTED:
4958         return -0x08;
4959       case ROCKSDB_NAMESPACE::Tickers::TXN_PREPARE_MUTEX_OVERHEAD:
4960         return -0x09;
4961       case ROCKSDB_NAMESPACE::Tickers::TXN_OLD_COMMIT_MAP_MUTEX_OVERHEAD:
4962         return -0x0A;
4963       case ROCKSDB_NAMESPACE::Tickers::TXN_DUPLICATE_KEY_OVERHEAD:
4964         return -0x0B;
4965       case ROCKSDB_NAMESPACE::Tickers::TXN_SNAPSHOT_MUTEX_OVERHEAD:
4966         return -0x0C;
4967       case ROCKSDB_NAMESPACE::Tickers::TXN_GET_TRY_AGAIN:
4968         return -0x0D;
4969       case ROCKSDB_NAMESPACE::Tickers::FILES_MARKED_TRASH:
4970         return -0x0E;
4971       case ROCKSDB_NAMESPACE::Tickers::FILES_DELETED_IMMEDIATELY:
4972         return -0X0F;
4973       case ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES_MARKED:
4974         return -0x10;
4975       case ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES_PERIODIC:
4976         return -0x11;
4977       case ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES_TTL:
4978         return -0x12;
4979       case ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES_MARKED:
4980         return -0x13;
4981       case ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES_PERIODIC:
4982         return -0x14;
4983       case ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES_TTL:
4984         return -0x15;
4985       case ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_BG_ERROR_COUNT:
4986         return -0x16;
4987       case ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_BG_IO_ERROR_COUNT:
4988         return -0x17;
4989       case ROCKSDB_NAMESPACE::Tickers::
4990           ERROR_HANDLER_BG_RETRYABLE_IO_ERROR_COUNT:
4991         return -0x18;
4992       case ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_AUTORESUME_COUNT:
4993         return -0x19;
4994       case ROCKSDB_NAMESPACE::Tickers::
4995           ERROR_HANDLER_AUTORESUME_RETRY_TOTAL_COUNT:
4996         return -0x1A;
4997       case ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_AUTORESUME_SUCCESS_COUNT:
4998         return -0x1B;
4999       case ROCKSDB_NAMESPACE::Tickers::TICKER_ENUM_MAX:
5000         // 0x5F for backwards compatibility on current minor version.
5001         return 0x5F;
5002       default:
5003         // undefined/default
5004         return 0x0;
5005     }
5006   }
5007 
5008   // Returns the equivalent C++ ROCKSDB_NAMESPACE::Tickers enum for the
5009   // provided Java org.rocksdb.TickerType
toCppTickers(jbyte jticker_type)5010   static ROCKSDB_NAMESPACE::Tickers toCppTickers(jbyte jticker_type) {
5011     switch(jticker_type) {
5012       case 0x0:
5013         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_MISS;
5014       case 0x1:
5015         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_HIT;
5016       case 0x2:
5017         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_ADD;
5018       case 0x3:
5019         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_ADD_FAILURES;
5020       case 0x4:
5021         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_MISS;
5022       case 0x5:
5023         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_HIT;
5024       case 0x6:
5025         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_ADD;
5026       case 0x7:
5027         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_BYTES_INSERT;
5028       case 0x8:
5029         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_INDEX_BYTES_EVICT;
5030       case 0x9:
5031         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_MISS;
5032       case 0xA:
5033         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_HIT;
5034       case 0xB:
5035         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_ADD;
5036       case 0xC:
5037         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_BYTES_INSERT;
5038       case 0xD:
5039         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_FILTER_BYTES_EVICT;
5040       case 0xE:
5041         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_MISS;
5042       case 0xF:
5043         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_HIT;
5044       case 0x10:
5045         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_ADD;
5046       case 0x11:
5047         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT;
5048       case 0x12:
5049         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_BYTES_READ;
5050       case 0x13:
5051         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_BYTES_WRITE;
5052       case 0x14:
5053         return ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_USEFUL;
5054       case 0x15:
5055         return ROCKSDB_NAMESPACE::Tickers::PERSISTENT_CACHE_HIT;
5056       case 0x16:
5057         return ROCKSDB_NAMESPACE::Tickers::PERSISTENT_CACHE_MISS;
5058       case 0x17:
5059         return ROCKSDB_NAMESPACE::Tickers::SIM_BLOCK_CACHE_HIT;
5060       case 0x18:
5061         return ROCKSDB_NAMESPACE::Tickers::SIM_BLOCK_CACHE_MISS;
5062       case 0x19:
5063         return ROCKSDB_NAMESPACE::Tickers::MEMTABLE_HIT;
5064       case 0x1A:
5065         return ROCKSDB_NAMESPACE::Tickers::MEMTABLE_MISS;
5066       case 0x1B:
5067         return ROCKSDB_NAMESPACE::Tickers::GET_HIT_L0;
5068       case 0x1C:
5069         return ROCKSDB_NAMESPACE::Tickers::GET_HIT_L1;
5070       case 0x1D:
5071         return ROCKSDB_NAMESPACE::Tickers::GET_HIT_L2_AND_UP;
5072       case 0x1E:
5073         return ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_NEWER_ENTRY;
5074       case 0x1F:
5075         return ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_OBSOLETE;
5076       case 0x20:
5077         return ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_RANGE_DEL;
5078       case 0x21:
5079         return ROCKSDB_NAMESPACE::Tickers::COMPACTION_KEY_DROP_USER;
5080       case 0x22:
5081         return ROCKSDB_NAMESPACE::Tickers::COMPACTION_RANGE_DEL_DROP_OBSOLETE;
5082       case 0x23:
5083         return ROCKSDB_NAMESPACE::Tickers::NUMBER_KEYS_WRITTEN;
5084       case 0x24:
5085         return ROCKSDB_NAMESPACE::Tickers::NUMBER_KEYS_READ;
5086       case 0x25:
5087         return ROCKSDB_NAMESPACE::Tickers::NUMBER_KEYS_UPDATED;
5088       case 0x26:
5089         return ROCKSDB_NAMESPACE::Tickers::BYTES_WRITTEN;
5090       case 0x27:
5091         return ROCKSDB_NAMESPACE::Tickers::BYTES_READ;
5092       case 0x28:
5093         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_SEEK;
5094       case 0x29:
5095         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_NEXT;
5096       case 0x2A:
5097         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_PREV;
5098       case 0x2B:
5099         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_SEEK_FOUND;
5100       case 0x2C:
5101         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_NEXT_FOUND;
5102       case 0x2D:
5103         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DB_PREV_FOUND;
5104       case 0x2E:
5105         return ROCKSDB_NAMESPACE::Tickers::ITER_BYTES_READ;
5106       case 0x2F:
5107         return ROCKSDB_NAMESPACE::Tickers::NO_FILE_CLOSES;
5108       case 0x30:
5109         return ROCKSDB_NAMESPACE::Tickers::NO_FILE_OPENS;
5110       case 0x31:
5111         return ROCKSDB_NAMESPACE::Tickers::NO_FILE_ERRORS;
5112       case 0x32:
5113         return ROCKSDB_NAMESPACE::Tickers::STALL_L0_SLOWDOWN_MICROS;
5114       case 0x33:
5115         return ROCKSDB_NAMESPACE::Tickers::STALL_MEMTABLE_COMPACTION_MICROS;
5116       case 0x34:
5117         return ROCKSDB_NAMESPACE::Tickers::STALL_L0_NUM_FILES_MICROS;
5118       case 0x35:
5119         return ROCKSDB_NAMESPACE::Tickers::STALL_MICROS;
5120       case 0x36:
5121         return ROCKSDB_NAMESPACE::Tickers::DB_MUTEX_WAIT_MICROS;
5122       case 0x37:
5123         return ROCKSDB_NAMESPACE::Tickers::RATE_LIMIT_DELAY_MILLIS;
5124       case 0x38:
5125         return ROCKSDB_NAMESPACE::Tickers::NO_ITERATORS;
5126       case 0x39:
5127         return ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_CALLS;
5128       case 0x3A:
5129         return ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_KEYS_READ;
5130       case 0x3B:
5131         return ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_BYTES_READ;
5132       case 0x3C:
5133         return ROCKSDB_NAMESPACE::Tickers::NUMBER_FILTERED_DELETES;
5134       case 0x3D:
5135         return ROCKSDB_NAMESPACE::Tickers::NUMBER_MERGE_FAILURES;
5136       case 0x3E:
5137         return ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_PREFIX_CHECKED;
5138       case 0x3F:
5139         return ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_PREFIX_USEFUL;
5140       case 0x40:
5141         return ROCKSDB_NAMESPACE::Tickers::NUMBER_OF_RESEEKS_IN_ITERATION;
5142       case 0x41:
5143         return ROCKSDB_NAMESPACE::Tickers::GET_UPDATES_SINCE_CALLS;
5144       case 0x42:
5145         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_MISS;
5146       case 0x43:
5147         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_HIT;
5148       case 0x44:
5149         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_ADD;
5150       case 0x45:
5151         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_COMPRESSED_ADD_FAILURES;
5152       case 0x46:
5153         return ROCKSDB_NAMESPACE::Tickers::WAL_FILE_SYNCED;
5154       case 0x47:
5155         return ROCKSDB_NAMESPACE::Tickers::WAL_FILE_BYTES;
5156       case 0x48:
5157         return ROCKSDB_NAMESPACE::Tickers::WRITE_DONE_BY_SELF;
5158       case 0x49:
5159         return ROCKSDB_NAMESPACE::Tickers::WRITE_DONE_BY_OTHER;
5160       case 0x4A:
5161         return ROCKSDB_NAMESPACE::Tickers::WRITE_TIMEDOUT;
5162       case 0x4B:
5163         return ROCKSDB_NAMESPACE::Tickers::WRITE_WITH_WAL;
5164       case 0x4C:
5165         return ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES;
5166       case 0x4D:
5167         return ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES;
5168       case 0x4E:
5169         return ROCKSDB_NAMESPACE::Tickers::FLUSH_WRITE_BYTES;
5170       case 0x4F:
5171         return ROCKSDB_NAMESPACE::Tickers::NUMBER_DIRECT_LOAD_TABLE_PROPERTIES;
5172       case 0x50:
5173         return ROCKSDB_NAMESPACE::Tickers::NUMBER_SUPERVERSION_ACQUIRES;
5174       case 0x51:
5175         return ROCKSDB_NAMESPACE::Tickers::NUMBER_SUPERVERSION_RELEASES;
5176       case 0x52:
5177         return ROCKSDB_NAMESPACE::Tickers::NUMBER_SUPERVERSION_CLEANUPS;
5178       case 0x53:
5179         return ROCKSDB_NAMESPACE::Tickers::NUMBER_BLOCK_COMPRESSED;
5180       case 0x54:
5181         return ROCKSDB_NAMESPACE::Tickers::NUMBER_BLOCK_DECOMPRESSED;
5182       case 0x55:
5183         return ROCKSDB_NAMESPACE::Tickers::NUMBER_BLOCK_NOT_COMPRESSED;
5184       case 0x56:
5185         return ROCKSDB_NAMESPACE::Tickers::MERGE_OPERATION_TOTAL_TIME;
5186       case 0x57:
5187         return ROCKSDB_NAMESPACE::Tickers::FILTER_OPERATION_TOTAL_TIME;
5188       case 0x58:
5189         return ROCKSDB_NAMESPACE::Tickers::ROW_CACHE_HIT;
5190       case 0x59:
5191         return ROCKSDB_NAMESPACE::Tickers::ROW_CACHE_MISS;
5192       case 0x5A:
5193         return ROCKSDB_NAMESPACE::Tickers::READ_AMP_ESTIMATE_USEFUL_BYTES;
5194       case 0x5B:
5195         return ROCKSDB_NAMESPACE::Tickers::READ_AMP_TOTAL_READ_BYTES;
5196       case 0x5C:
5197         return ROCKSDB_NAMESPACE::Tickers::NUMBER_RATE_LIMITER_DRAINS;
5198       case 0x5D:
5199         return ROCKSDB_NAMESPACE::Tickers::NUMBER_ITER_SKIP;
5200       case 0x5E:
5201         return ROCKSDB_NAMESPACE::Tickers::NUMBER_MULTIGET_KEYS_FOUND;
5202       case -0x01:
5203         // -0x01 to fixate the new value that incorrectly changed TICKER_ENUM_MAX.
5204         return ROCKSDB_NAMESPACE::Tickers::NO_ITERATOR_CREATED;
5205       case 0x60:
5206         return ROCKSDB_NAMESPACE::Tickers::NO_ITERATOR_DELETED;
5207       case 0x61:
5208         return ROCKSDB_NAMESPACE::Tickers::
5209             COMPACTION_OPTIMIZED_DEL_DROP_OBSOLETE;
5210       case 0x62:
5211         return ROCKSDB_NAMESPACE::Tickers::COMPACTION_CANCELLED;
5212       case 0x63:
5213         return ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_FULL_POSITIVE;
5214       case 0x64:
5215         return ROCKSDB_NAMESPACE::Tickers::BLOOM_FILTER_FULL_TRUE_POSITIVE;
5216       case 0x65:
5217         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_PUT;
5218       case 0x66:
5219         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_WRITE;
5220       case 0x67:
5221         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_GET;
5222       case 0x68:
5223         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_MULTIGET;
5224       case 0x69:
5225         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_SEEK;
5226       case 0x6A:
5227         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_NEXT;
5228       case 0x6B:
5229         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_PREV;
5230       case 0x6C:
5231         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_KEYS_WRITTEN;
5232       case 0x6D:
5233         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_NUM_KEYS_READ;
5234       case 0x6E:
5235         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BYTES_WRITTEN;
5236       case 0x6F:
5237         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BYTES_READ;
5238       case 0x70:
5239         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_INLINED;
5240       case 0x71:
5241         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_INLINED_TTL;
5242       case 0x72:
5243         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_BLOB;
5244       case 0x73:
5245         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_WRITE_BLOB_TTL;
5246       case 0x74:
5247         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_FILE_BYTES_WRITTEN;
5248       case 0x75:
5249         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_FILE_BYTES_READ;
5250       case 0x76:
5251         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_FILE_SYNCED;
5252       case 0x77:
5253         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_COUNT;
5254       case 0x78:
5255         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EXPIRED_SIZE;
5256       case 0x79:
5257         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_COUNT;
5258       case 0x7A:
5259         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_BLOB_INDEX_EVICTED_SIZE;
5260       case 0x7B:
5261         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_FILES;
5262       case 0x7C:
5263         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_NEW_FILES;
5264       case 0x7D:
5265         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_FAILURES;
5266       case 0x7E:
5267         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_KEYS_OVERWRITTEN;
5268       case 0x7F:
5269         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_KEYS_EXPIRED;
5270       case -0x02:
5271         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_NUM_KEYS_RELOCATED;
5272       case -0x03:
5273         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_BYTES_OVERWRITTEN;
5274       case -0x04:
5275         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_BYTES_EXPIRED;
5276       case -0x05:
5277         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_GC_BYTES_RELOCATED;
5278       case -0x06:
5279         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_FIFO_NUM_FILES_EVICTED;
5280       case -0x07:
5281         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_FIFO_NUM_KEYS_EVICTED;
5282       case -0x08:
5283         return ROCKSDB_NAMESPACE::Tickers::BLOB_DB_FIFO_BYTES_EVICTED;
5284       case -0x09:
5285         return ROCKSDB_NAMESPACE::Tickers::TXN_PREPARE_MUTEX_OVERHEAD;
5286       case -0x0A:
5287         return ROCKSDB_NAMESPACE::Tickers::TXN_OLD_COMMIT_MAP_MUTEX_OVERHEAD;
5288       case -0x0B:
5289         return ROCKSDB_NAMESPACE::Tickers::TXN_DUPLICATE_KEY_OVERHEAD;
5290       case -0x0C:
5291         return ROCKSDB_NAMESPACE::Tickers::TXN_SNAPSHOT_MUTEX_OVERHEAD;
5292       case -0x0D:
5293         return ROCKSDB_NAMESPACE::Tickers::TXN_GET_TRY_AGAIN;
5294       case -0x0E:
5295         return ROCKSDB_NAMESPACE::Tickers::FILES_MARKED_TRASH;
5296       case -0x0F:
5297         return ROCKSDB_NAMESPACE::Tickers::FILES_DELETED_IMMEDIATELY;
5298       case -0x10:
5299         return ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES_MARKED;
5300       case -0x11:
5301         return ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES_PERIODIC;
5302       case -0x12:
5303         return ROCKSDB_NAMESPACE::Tickers::COMPACT_READ_BYTES_TTL;
5304       case -0x13:
5305         return ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES_MARKED;
5306       case -0x14:
5307         return ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES_PERIODIC;
5308       case -0x15:
5309         return ROCKSDB_NAMESPACE::Tickers::COMPACT_WRITE_BYTES_TTL;
5310       case -0x16:
5311         return ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_BG_ERROR_COUNT;
5312       case -0x17:
5313         return ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_BG_IO_ERROR_COUNT;
5314       case -0x18:
5315         return ROCKSDB_NAMESPACE::Tickers::
5316             ERROR_HANDLER_BG_RETRYABLE_IO_ERROR_COUNT;
5317       case -0x19:
5318         return ROCKSDB_NAMESPACE::Tickers::ERROR_HANDLER_AUTORESUME_COUNT;
5319       case -0x1A:
5320         return ROCKSDB_NAMESPACE::Tickers::
5321             ERROR_HANDLER_AUTORESUME_RETRY_TOTAL_COUNT;
5322       case -0x1B:
5323         return ROCKSDB_NAMESPACE::Tickers::
5324             ERROR_HANDLER_AUTORESUME_SUCCESS_COUNT;
5325       case 0x5F:
5326         // 0x5F for backwards compatibility on current minor version.
5327         return ROCKSDB_NAMESPACE::Tickers::TICKER_ENUM_MAX;
5328 
5329       default:
5330         // undefined/default
5331         return ROCKSDB_NAMESPACE::Tickers::BLOCK_CACHE_MISS;
5332     }
5333   }
5334 };
5335 
5336 // The portal class for org.rocksdb.HistogramType
5337 class HistogramTypeJni {
5338  public:
5339   // Returns the equivalent org.rocksdb.HistogramType for the provided
5340   // C++ ROCKSDB_NAMESPACE::Histograms enum
toJavaHistogramsType(const ROCKSDB_NAMESPACE::Histograms & histograms)5341   static jbyte toJavaHistogramsType(
5342       const ROCKSDB_NAMESPACE::Histograms& histograms) {
5343     switch(histograms) {
5344       case ROCKSDB_NAMESPACE::Histograms::DB_GET:
5345         return 0x0;
5346       case ROCKSDB_NAMESPACE::Histograms::DB_WRITE:
5347         return 0x1;
5348       case ROCKSDB_NAMESPACE::Histograms::COMPACTION_TIME:
5349         return 0x2;
5350       case ROCKSDB_NAMESPACE::Histograms::SUBCOMPACTION_SETUP_TIME:
5351         return 0x3;
5352       case ROCKSDB_NAMESPACE::Histograms::TABLE_SYNC_MICROS:
5353         return 0x4;
5354       case ROCKSDB_NAMESPACE::Histograms::COMPACTION_OUTFILE_SYNC_MICROS:
5355         return 0x5;
5356       case ROCKSDB_NAMESPACE::Histograms::WAL_FILE_SYNC_MICROS:
5357         return 0x6;
5358       case ROCKSDB_NAMESPACE::Histograms::MANIFEST_FILE_SYNC_MICROS:
5359         return 0x7;
5360       case ROCKSDB_NAMESPACE::Histograms::TABLE_OPEN_IO_MICROS:
5361         return 0x8;
5362       case ROCKSDB_NAMESPACE::Histograms::DB_MULTIGET:
5363         return 0x9;
5364       case ROCKSDB_NAMESPACE::Histograms::READ_BLOCK_COMPACTION_MICROS:
5365         return 0xA;
5366       case ROCKSDB_NAMESPACE::Histograms::READ_BLOCK_GET_MICROS:
5367         return 0xB;
5368       case ROCKSDB_NAMESPACE::Histograms::WRITE_RAW_BLOCK_MICROS:
5369         return 0xC;
5370       case ROCKSDB_NAMESPACE::Histograms::STALL_L0_SLOWDOWN_COUNT:
5371         return 0xD;
5372       case ROCKSDB_NAMESPACE::Histograms::STALL_MEMTABLE_COMPACTION_COUNT:
5373         return 0xE;
5374       case ROCKSDB_NAMESPACE::Histograms::STALL_L0_NUM_FILES_COUNT:
5375         return 0xF;
5376       case ROCKSDB_NAMESPACE::Histograms::HARD_RATE_LIMIT_DELAY_COUNT:
5377         return 0x10;
5378       case ROCKSDB_NAMESPACE::Histograms::SOFT_RATE_LIMIT_DELAY_COUNT:
5379         return 0x11;
5380       case ROCKSDB_NAMESPACE::Histograms::NUM_FILES_IN_SINGLE_COMPACTION:
5381         return 0x12;
5382       case ROCKSDB_NAMESPACE::Histograms::DB_SEEK:
5383         return 0x13;
5384       case ROCKSDB_NAMESPACE::Histograms::WRITE_STALL:
5385         return 0x14;
5386       case ROCKSDB_NAMESPACE::Histograms::SST_READ_MICROS:
5387         return 0x15;
5388       case ROCKSDB_NAMESPACE::Histograms::NUM_SUBCOMPACTIONS_SCHEDULED:
5389         return 0x16;
5390       case ROCKSDB_NAMESPACE::Histograms::BYTES_PER_READ:
5391         return 0x17;
5392       case ROCKSDB_NAMESPACE::Histograms::BYTES_PER_WRITE:
5393         return 0x18;
5394       case ROCKSDB_NAMESPACE::Histograms::BYTES_PER_MULTIGET:
5395         return 0x19;
5396       case ROCKSDB_NAMESPACE::Histograms::BYTES_COMPRESSED:
5397         return 0x1A;
5398       case ROCKSDB_NAMESPACE::Histograms::BYTES_DECOMPRESSED:
5399         return 0x1B;
5400       case ROCKSDB_NAMESPACE::Histograms::COMPRESSION_TIMES_NANOS:
5401         return 0x1C;
5402       case ROCKSDB_NAMESPACE::Histograms::DECOMPRESSION_TIMES_NANOS:
5403         return 0x1D;
5404       case ROCKSDB_NAMESPACE::Histograms::READ_NUM_MERGE_OPERANDS:
5405         return 0x1E;
5406       // 0x20 to skip 0x1F so TICKER_ENUM_MAX remains unchanged for minor version compatibility.
5407       case ROCKSDB_NAMESPACE::Histograms::FLUSH_TIME:
5408         return 0x20;
5409       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_KEY_SIZE:
5410         return 0x21;
5411       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_VALUE_SIZE:
5412         return 0x22;
5413       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_WRITE_MICROS:
5414         return 0x23;
5415       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_GET_MICROS:
5416         return 0x24;
5417       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_MULTIGET_MICROS:
5418         return 0x25;
5419       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_SEEK_MICROS:
5420         return 0x26;
5421       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_NEXT_MICROS:
5422         return 0x27;
5423       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_PREV_MICROS:
5424         return 0x28;
5425       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_BLOB_FILE_WRITE_MICROS:
5426         return 0x29;
5427       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_BLOB_FILE_READ_MICROS:
5428         return 0x2A;
5429       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_BLOB_FILE_SYNC_MICROS:
5430         return 0x2B;
5431       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_GC_MICROS:
5432         return 0x2C;
5433       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_COMPRESSION_MICROS:
5434         return 0x2D;
5435       case ROCKSDB_NAMESPACE::Histograms::BLOB_DB_DECOMPRESSION_MICROS:
5436         return 0x2E;
5437       case ROCKSDB_NAMESPACE::Histograms::
5438           NUM_INDEX_AND_FILTER_BLOCKS_READ_PER_LEVEL:
5439         return 0x2F;
5440       case ROCKSDB_NAMESPACE::Histograms::NUM_DATA_BLOCKS_READ_PER_LEVEL:
5441         return 0x30;
5442       case ROCKSDB_NAMESPACE::Histograms::NUM_SST_READ_PER_LEVEL:
5443         return 0x31;
5444       case ROCKSDB_NAMESPACE::Histograms::ERROR_HANDLER_AUTORESUME_RETRY_COUNT:
5445         return 0x31;
5446       case ROCKSDB_NAMESPACE::Histograms::HISTOGRAM_ENUM_MAX:
5447         // 0x1F for backwards compatibility on current minor version.
5448         return 0x1F;
5449 
5450       default:
5451         // undefined/default
5452         return 0x0;
5453     }
5454   }
5455 
5456   // Returns the equivalent C++ ROCKSDB_NAMESPACE::Histograms enum for the
5457   // provided Java org.rocksdb.HistogramsType
toCppHistograms(jbyte jhistograms_type)5458   static ROCKSDB_NAMESPACE::Histograms toCppHistograms(jbyte jhistograms_type) {
5459     switch(jhistograms_type) {
5460       case 0x0:
5461         return ROCKSDB_NAMESPACE::Histograms::DB_GET;
5462       case 0x1:
5463         return ROCKSDB_NAMESPACE::Histograms::DB_WRITE;
5464       case 0x2:
5465         return ROCKSDB_NAMESPACE::Histograms::COMPACTION_TIME;
5466       case 0x3:
5467         return ROCKSDB_NAMESPACE::Histograms::SUBCOMPACTION_SETUP_TIME;
5468       case 0x4:
5469         return ROCKSDB_NAMESPACE::Histograms::TABLE_SYNC_MICROS;
5470       case 0x5:
5471         return ROCKSDB_NAMESPACE::Histograms::COMPACTION_OUTFILE_SYNC_MICROS;
5472       case 0x6:
5473         return ROCKSDB_NAMESPACE::Histograms::WAL_FILE_SYNC_MICROS;
5474       case 0x7:
5475         return ROCKSDB_NAMESPACE::Histograms::MANIFEST_FILE_SYNC_MICROS;
5476       case 0x8:
5477         return ROCKSDB_NAMESPACE::Histograms::TABLE_OPEN_IO_MICROS;
5478       case 0x9:
5479         return ROCKSDB_NAMESPACE::Histograms::DB_MULTIGET;
5480       case 0xA:
5481         return ROCKSDB_NAMESPACE::Histograms::READ_BLOCK_COMPACTION_MICROS;
5482       case 0xB:
5483         return ROCKSDB_NAMESPACE::Histograms::READ_BLOCK_GET_MICROS;
5484       case 0xC:
5485         return ROCKSDB_NAMESPACE::Histograms::WRITE_RAW_BLOCK_MICROS;
5486       case 0xD:
5487         return ROCKSDB_NAMESPACE::Histograms::STALL_L0_SLOWDOWN_COUNT;
5488       case 0xE:
5489         return ROCKSDB_NAMESPACE::Histograms::STALL_MEMTABLE_COMPACTION_COUNT;
5490       case 0xF:
5491         return ROCKSDB_NAMESPACE::Histograms::STALL_L0_NUM_FILES_COUNT;
5492       case 0x10:
5493         return ROCKSDB_NAMESPACE::Histograms::HARD_RATE_LIMIT_DELAY_COUNT;
5494       case 0x11:
5495         return ROCKSDB_NAMESPACE::Histograms::SOFT_RATE_LIMIT_DELAY_COUNT;
5496       case 0x12:
5497         return ROCKSDB_NAMESPACE::Histograms::NUM_FILES_IN_SINGLE_COMPACTION;
5498       case 0x13:
5499         return ROCKSDB_NAMESPACE::Histograms::DB_SEEK;
5500       case 0x14:
5501         return ROCKSDB_NAMESPACE::Histograms::WRITE_STALL;
5502       case 0x15:
5503         return ROCKSDB_NAMESPACE::Histograms::SST_READ_MICROS;
5504       case 0x16:
5505         return ROCKSDB_NAMESPACE::Histograms::NUM_SUBCOMPACTIONS_SCHEDULED;
5506       case 0x17:
5507         return ROCKSDB_NAMESPACE::Histograms::BYTES_PER_READ;
5508       case 0x18:
5509         return ROCKSDB_NAMESPACE::Histograms::BYTES_PER_WRITE;
5510       case 0x19:
5511         return ROCKSDB_NAMESPACE::Histograms::BYTES_PER_MULTIGET;
5512       case 0x1A:
5513         return ROCKSDB_NAMESPACE::Histograms::BYTES_COMPRESSED;
5514       case 0x1B:
5515         return ROCKSDB_NAMESPACE::Histograms::BYTES_DECOMPRESSED;
5516       case 0x1C:
5517         return ROCKSDB_NAMESPACE::Histograms::COMPRESSION_TIMES_NANOS;
5518       case 0x1D:
5519         return ROCKSDB_NAMESPACE::Histograms::DECOMPRESSION_TIMES_NANOS;
5520       case 0x1E:
5521         return ROCKSDB_NAMESPACE::Histograms::READ_NUM_MERGE_OPERANDS;
5522       // 0x20 to skip 0x1F so TICKER_ENUM_MAX remains unchanged for minor version compatibility.
5523       case 0x20:
5524         return ROCKSDB_NAMESPACE::Histograms::FLUSH_TIME;
5525       case 0x21:
5526         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_KEY_SIZE;
5527       case 0x22:
5528         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_VALUE_SIZE;
5529       case 0x23:
5530         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_WRITE_MICROS;
5531       case 0x24:
5532         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_GET_MICROS;
5533       case 0x25:
5534         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_MULTIGET_MICROS;
5535       case 0x26:
5536         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_SEEK_MICROS;
5537       case 0x27:
5538         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_NEXT_MICROS;
5539       case 0x28:
5540         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_PREV_MICROS;
5541       case 0x29:
5542         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_BLOB_FILE_WRITE_MICROS;
5543       case 0x2A:
5544         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_BLOB_FILE_READ_MICROS;
5545       case 0x2B:
5546         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_BLOB_FILE_SYNC_MICROS;
5547       case 0x2C:
5548         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_GC_MICROS;
5549       case 0x2D:
5550         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_COMPRESSION_MICROS;
5551       case 0x2E:
5552         return ROCKSDB_NAMESPACE::Histograms::BLOB_DB_DECOMPRESSION_MICROS;
5553       case 0x2F:
5554         return ROCKSDB_NAMESPACE::Histograms::
5555             NUM_INDEX_AND_FILTER_BLOCKS_READ_PER_LEVEL;
5556       case 0x30:
5557         return ROCKSDB_NAMESPACE::Histograms::NUM_DATA_BLOCKS_READ_PER_LEVEL;
5558       case 0x31:
5559         return ROCKSDB_NAMESPACE::Histograms::NUM_SST_READ_PER_LEVEL;
5560       case 0x32:
5561         return ROCKSDB_NAMESPACE::Histograms::
5562             ERROR_HANDLER_AUTORESUME_RETRY_COUNT;
5563       case 0x1F:
5564         // 0x1F for backwards compatibility on current minor version.
5565         return ROCKSDB_NAMESPACE::Histograms::HISTOGRAM_ENUM_MAX;
5566 
5567       default:
5568         // undefined/default
5569         return ROCKSDB_NAMESPACE::Histograms::DB_GET;
5570     }
5571   }
5572 };
5573 
5574 // The portal class for org.rocksdb.StatsLevel
5575 class StatsLevelJni {
5576  public:
5577   // Returns the equivalent org.rocksdb.StatsLevel for the provided
5578   // C++ ROCKSDB_NAMESPACE::StatsLevel enum
toJavaStatsLevel(const ROCKSDB_NAMESPACE::StatsLevel & stats_level)5579   static jbyte toJavaStatsLevel(
5580       const ROCKSDB_NAMESPACE::StatsLevel& stats_level) {
5581     switch(stats_level) {
5582       case ROCKSDB_NAMESPACE::StatsLevel::kExceptDetailedTimers:
5583         return 0x0;
5584       case ROCKSDB_NAMESPACE::StatsLevel::kExceptTimeForMutex:
5585         return 0x1;
5586       case ROCKSDB_NAMESPACE::StatsLevel::kAll:
5587         return 0x2;
5588 
5589       default:
5590         // undefined/default
5591         return 0x0;
5592     }
5593   }
5594 
5595   // Returns the equivalent C++ ROCKSDB_NAMESPACE::StatsLevel enum for the
5596   // provided Java org.rocksdb.StatsLevel
toCppStatsLevel(jbyte jstats_level)5597   static ROCKSDB_NAMESPACE::StatsLevel toCppStatsLevel(jbyte jstats_level) {
5598     switch(jstats_level) {
5599       case 0x0:
5600         return ROCKSDB_NAMESPACE::StatsLevel::kExceptDetailedTimers;
5601       case 0x1:
5602         return ROCKSDB_NAMESPACE::StatsLevel::kExceptTimeForMutex;
5603       case 0x2:
5604         return ROCKSDB_NAMESPACE::StatsLevel::kAll;
5605 
5606       default:
5607         // undefined/default
5608         return ROCKSDB_NAMESPACE::StatsLevel::kExceptDetailedTimers;
5609     }
5610   }
5611 };
5612 
5613 // The portal class for org.rocksdb.RateLimiterMode
5614 class RateLimiterModeJni {
5615  public:
5616   // Returns the equivalent org.rocksdb.RateLimiterMode for the provided
5617   // C++ ROCKSDB_NAMESPACE::RateLimiter::Mode enum
toJavaRateLimiterMode(const ROCKSDB_NAMESPACE::RateLimiter::Mode & rate_limiter_mode)5618   static jbyte toJavaRateLimiterMode(
5619       const ROCKSDB_NAMESPACE::RateLimiter::Mode& rate_limiter_mode) {
5620     switch(rate_limiter_mode) {
5621       case ROCKSDB_NAMESPACE::RateLimiter::Mode::kReadsOnly:
5622         return 0x0;
5623       case ROCKSDB_NAMESPACE::RateLimiter::Mode::kWritesOnly:
5624         return 0x1;
5625       case ROCKSDB_NAMESPACE::RateLimiter::Mode::kAllIo:
5626         return 0x2;
5627 
5628       default:
5629         // undefined/default
5630         return 0x1;
5631     }
5632   }
5633 
5634   // Returns the equivalent C++ ROCKSDB_NAMESPACE::RateLimiter::Mode enum for
5635   // the provided Java org.rocksdb.RateLimiterMode
toCppRateLimiterMode(jbyte jrate_limiter_mode)5636   static ROCKSDB_NAMESPACE::RateLimiter::Mode toCppRateLimiterMode(
5637       jbyte jrate_limiter_mode) {
5638     switch(jrate_limiter_mode) {
5639       case 0x0:
5640         return ROCKSDB_NAMESPACE::RateLimiter::Mode::kReadsOnly;
5641       case 0x1:
5642         return ROCKSDB_NAMESPACE::RateLimiter::Mode::kWritesOnly;
5643       case 0x2:
5644         return ROCKSDB_NAMESPACE::RateLimiter::Mode::kAllIo;
5645 
5646       default:
5647         // undefined/default
5648         return ROCKSDB_NAMESPACE::RateLimiter::Mode::kWritesOnly;
5649     }
5650   }
5651 };
5652 
5653 // The portal class for org.rocksdb.MemoryUsageType
5654 class MemoryUsageTypeJni {
5655 public:
5656  // Returns the equivalent org.rocksdb.MemoryUsageType for the provided
5657  // C++ ROCKSDB_NAMESPACE::MemoryUtil::UsageType enum
toJavaMemoryUsageType(const ROCKSDB_NAMESPACE::MemoryUtil::UsageType & usage_type)5658  static jbyte toJavaMemoryUsageType(
5659      const ROCKSDB_NAMESPACE::MemoryUtil::UsageType& usage_type) {
5660    switch (usage_type) {
5661      case ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kMemTableTotal:
5662        return 0x0;
5663      case ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kMemTableUnFlushed:
5664        return 0x1;
5665      case ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kTableReadersTotal:
5666        return 0x2;
5667      case ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kCacheTotal:
5668        return 0x3;
5669      default:
5670        // undefined: use kNumUsageTypes
5671        return 0x4;
5672    }
5673  }
5674 
5675  // Returns the equivalent C++ ROCKSDB_NAMESPACE::MemoryUtil::UsageType enum for
5676  // the provided Java org.rocksdb.MemoryUsageType
toCppMemoryUsageType(jbyte usage_type)5677  static ROCKSDB_NAMESPACE::MemoryUtil::UsageType toCppMemoryUsageType(
5678      jbyte usage_type) {
5679    switch (usage_type) {
5680      case 0x0:
5681        return ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kMemTableTotal;
5682      case 0x1:
5683        return ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kMemTableUnFlushed;
5684      case 0x2:
5685        return ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kTableReadersTotal;
5686      case 0x3:
5687        return ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kCacheTotal;
5688      default:
5689        // undefined/default: use kNumUsageTypes
5690        return ROCKSDB_NAMESPACE::MemoryUtil::UsageType::kNumUsageTypes;
5691    }
5692  }
5693 };
5694 
5695 // The portal class for org.rocksdb.Transaction
5696 class TransactionJni : public JavaClass {
5697  public:
5698   /**
5699    * Get the Java Class org.rocksdb.Transaction
5700    *
5701    * @param env A pointer to the Java environment
5702    *
5703    * @return The Java Class or nullptr if one of the
5704    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
5705    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
5706    */
getJClass(JNIEnv * env)5707   static jclass getJClass(JNIEnv* env) {
5708     return JavaClass::getJClass(env,
5709         "org/rocksdb/Transaction");
5710   }
5711 
5712   /**
5713    * Create a new Java org.rocksdb.Transaction.WaitingTransactions object
5714    *
5715    * @param env A pointer to the Java environment
5716    * @param jtransaction A Java org.rocksdb.Transaction object
5717    * @param column_family_id The id of the column family
5718    * @param key The key
5719    * @param transaction_ids The transaction ids
5720    *
5721    * @return A reference to a Java
5722    *     org.rocksdb.Transaction.WaitingTransactions object,
5723    *     or nullptr if an an exception occurs
5724    */
newWaitingTransactions(JNIEnv * env,jobject jtransaction,const uint32_t column_family_id,const std::string & key,const std::vector<TransactionID> & transaction_ids)5725   static jobject newWaitingTransactions(JNIEnv* env, jobject jtransaction,
5726       const uint32_t column_family_id, const std::string &key,
5727       const std::vector<TransactionID> &transaction_ids) {
5728     jclass jclazz = getJClass(env);
5729     if(jclazz == nullptr) {
5730       // exception occurred accessing class
5731       return nullptr;
5732     }
5733 
5734     jmethodID mid = env->GetMethodID(
5735       jclazz, "newWaitingTransactions", "(JLjava/lang/String;[J)Lorg/rocksdb/Transaction$WaitingTransactions;");
5736     if(mid == nullptr) {
5737       // exception thrown: NoSuchMethodException or OutOfMemoryError
5738       return nullptr;
5739     }
5740 
5741     jstring jkey = env->NewStringUTF(key.c_str());
5742     if(jkey == nullptr) {
5743       // exception thrown: OutOfMemoryError
5744       return nullptr;
5745     }
5746 
5747     const size_t len = transaction_ids.size();
5748     jlongArray jtransaction_ids = env->NewLongArray(static_cast<jsize>(len));
5749     if(jtransaction_ids == nullptr) {
5750       // exception thrown: OutOfMemoryError
5751       env->DeleteLocalRef(jkey);
5752       return nullptr;
5753     }
5754 
5755     jboolean is_copy;
5756     jlong* body = env->GetLongArrayElements(jtransaction_ids, &is_copy);
5757     if(body == nullptr) {
5758         // exception thrown: OutOfMemoryError
5759         env->DeleteLocalRef(jkey);
5760         env->DeleteLocalRef(jtransaction_ids);
5761         return nullptr;
5762     }
5763     for(size_t i = 0; i < len; ++i) {
5764       body[i] = static_cast<jlong>(transaction_ids[i]);
5765     }
5766     env->ReleaseLongArrayElements(jtransaction_ids, body,
5767                                   is_copy == JNI_TRUE ? 0 : JNI_ABORT);
5768 
5769     jobject jwaiting_transactions = env->CallObjectMethod(jtransaction,
5770       mid, static_cast<jlong>(column_family_id), jkey, jtransaction_ids);
5771     if(env->ExceptionCheck()) {
5772       // exception thrown: InstantiationException or OutOfMemoryError
5773       env->DeleteLocalRef(jkey);
5774       env->DeleteLocalRef(jtransaction_ids);
5775       return nullptr;
5776     }
5777 
5778     return jwaiting_transactions;
5779   }
5780 };
5781 
5782 // The portal class for org.rocksdb.TransactionDB
5783 class TransactionDBJni : public JavaClass {
5784  public:
5785  /**
5786   * Get the Java Class org.rocksdb.TransactionDB
5787   *
5788   * @param env A pointer to the Java environment
5789   *
5790   * @return The Java Class or nullptr if one of the
5791   *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
5792   *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
5793   */
getJClass(JNIEnv * env)5794   static jclass getJClass(JNIEnv* env) {
5795     return JavaClass::getJClass(env,
5796        "org/rocksdb/TransactionDB");
5797   }
5798 
5799   /**
5800    * Create a new Java org.rocksdb.TransactionDB.DeadlockInfo object
5801    *
5802    * @param env A pointer to the Java environment
5803    * @param jtransaction A Java org.rocksdb.Transaction object
5804    * @param column_family_id The id of the column family
5805    * @param key The key
5806    * @param transaction_ids The transaction ids
5807    *
5808    * @return A reference to a Java
5809    *     org.rocksdb.Transaction.WaitingTransactions object,
5810    *     or nullptr if an an exception occurs
5811    */
newDeadlockInfo(JNIEnv * env,jobject jtransaction_db,const ROCKSDB_NAMESPACE::TransactionID transaction_id,const uint32_t column_family_id,const std::string & waiting_key,const bool exclusive)5812   static jobject newDeadlockInfo(
5813       JNIEnv* env, jobject jtransaction_db,
5814       const ROCKSDB_NAMESPACE::TransactionID transaction_id,
5815       const uint32_t column_family_id, const std::string& waiting_key,
5816       const bool exclusive) {
5817     jclass jclazz = getJClass(env);
5818     if(jclazz == nullptr) {
5819       // exception occurred accessing class
5820       return nullptr;
5821     }
5822 
5823     jmethodID mid = env->GetMethodID(
5824         jclazz, "newDeadlockInfo", "(JJLjava/lang/String;Z)Lorg/rocksdb/TransactionDB$DeadlockInfo;");
5825     if(mid == nullptr) {
5826       // exception thrown: NoSuchMethodException or OutOfMemoryError
5827       return nullptr;
5828     }
5829 
5830     jstring jwaiting_key = env->NewStringUTF(waiting_key.c_str());
5831     if(jwaiting_key == nullptr) {
5832       // exception thrown: OutOfMemoryError
5833       return nullptr;
5834     }
5835 
5836     // resolve the column family id to a ColumnFamilyHandle
5837     jobject jdeadlock_info = env->CallObjectMethod(jtransaction_db,
5838         mid, transaction_id, static_cast<jlong>(column_family_id),
5839         jwaiting_key, exclusive);
5840     if(env->ExceptionCheck()) {
5841       // exception thrown: InstantiationException or OutOfMemoryError
5842       env->DeleteLocalRef(jwaiting_key);
5843       return nullptr;
5844     }
5845 
5846     return jdeadlock_info;
5847   }
5848 };
5849 
5850 // The portal class for org.rocksdb.TxnDBWritePolicy
5851 class TxnDBWritePolicyJni {
5852  public:
5853   // Returns the equivalent org.rocksdb.TxnDBWritePolicy for the provided
5854   // C++ ROCKSDB_NAMESPACE::TxnDBWritePolicy enum
toJavaTxnDBWritePolicy(const ROCKSDB_NAMESPACE::TxnDBWritePolicy & txndb_write_policy)5855   static jbyte toJavaTxnDBWritePolicy(
5856       const ROCKSDB_NAMESPACE::TxnDBWritePolicy& txndb_write_policy) {
5857     switch (txndb_write_policy) {
5858       case ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_COMMITTED:
5859         return 0x0;
5860       case ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_PREPARED:
5861         return 0x1;
5862       case ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_UNPREPARED:
5863         return 0x2;
5864       default:
5865         return 0x7F;  // undefined
5866     }
5867   }
5868 
5869   // Returns the equivalent C++ ROCKSDB_NAMESPACE::TxnDBWritePolicy enum for the
5870   // provided Java org.rocksdb.TxnDBWritePolicy
toCppTxnDBWritePolicy(jbyte jtxndb_write_policy)5871   static ROCKSDB_NAMESPACE::TxnDBWritePolicy toCppTxnDBWritePolicy(
5872       jbyte jtxndb_write_policy) {
5873     switch (jtxndb_write_policy) {
5874       case 0x0:
5875         return ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_COMMITTED;
5876       case 0x1:
5877         return ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_PREPARED;
5878       case 0x2:
5879         return ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_UNPREPARED;
5880       default:
5881         // undefined/default
5882         return ROCKSDB_NAMESPACE::TxnDBWritePolicy::WRITE_COMMITTED;
5883     }
5884   }
5885 };
5886 
5887 // The portal class for org.rocksdb.TransactionDB.KeyLockInfo
5888 class KeyLockInfoJni : public JavaClass {
5889  public:
5890   /**
5891    * Get the Java Class org.rocksdb.TransactionDB.KeyLockInfo
5892    *
5893    * @param env A pointer to the Java environment
5894    *
5895    * @return The Java Class or nullptr if one of the
5896    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
5897    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
5898    */
getJClass(JNIEnv * env)5899   static jclass getJClass(JNIEnv* env) {
5900     return JavaClass::getJClass(env,
5901         "org/rocksdb/TransactionDB$KeyLockInfo");
5902   }
5903 
5904   /**
5905    * Create a new Java org.rocksdb.TransactionDB.KeyLockInfo object
5906    * with the same properties as the provided C++ ROCKSDB_NAMESPACE::KeyLockInfo
5907    * object
5908    *
5909    * @param env A pointer to the Java environment
5910    * @param key_lock_info The ROCKSDB_NAMESPACE::KeyLockInfo object
5911    *
5912    * @return A reference to a Java
5913    *     org.rocksdb.TransactionDB.KeyLockInfo object,
5914    *     or nullptr if an an exception occurs
5915    */
construct(JNIEnv * env,const ROCKSDB_NAMESPACE::KeyLockInfo & key_lock_info)5916   static jobject construct(
5917       JNIEnv* env, const ROCKSDB_NAMESPACE::KeyLockInfo& key_lock_info) {
5918     jclass jclazz = getJClass(env);
5919     if(jclazz == nullptr) {
5920       // exception occurred accessing class
5921       return nullptr;
5922     }
5923 
5924     jmethodID mid = env->GetMethodID(
5925       jclazz, "<init>", "(Ljava/lang/String;[JZ)V");
5926     if (mid == nullptr) {
5927       // exception thrown: NoSuchMethodException or OutOfMemoryError
5928       return nullptr;
5929     }
5930 
5931     jstring jkey = env->NewStringUTF(key_lock_info.key.c_str());
5932     if (jkey == nullptr) {
5933       // exception thrown: OutOfMemoryError
5934       return nullptr;
5935     }
5936 
5937     const jsize jtransaction_ids_len = static_cast<jsize>(key_lock_info.ids.size());
5938     jlongArray jtransactions_ids = env->NewLongArray(jtransaction_ids_len);
5939     if (jtransactions_ids == nullptr) {
5940       // exception thrown: OutOfMemoryError
5941       env->DeleteLocalRef(jkey);
5942       return nullptr;
5943     }
5944 
5945     const jobject jkey_lock_info = env->NewObject(jclazz, mid,
5946       jkey, jtransactions_ids, key_lock_info.exclusive);
5947     if(jkey_lock_info == nullptr) {
5948       // exception thrown: InstantiationException or OutOfMemoryError
5949       env->DeleteLocalRef(jtransactions_ids);
5950       env->DeleteLocalRef(jkey);
5951       return nullptr;
5952     }
5953 
5954     return jkey_lock_info;
5955   }
5956 };
5957 
5958 // The portal class for org.rocksdb.TransactionDB.DeadlockInfo
5959 class DeadlockInfoJni : public JavaClass {
5960  public:
5961   /**
5962    * Get the Java Class org.rocksdb.TransactionDB.DeadlockInfo
5963    *
5964    * @param env A pointer to the Java environment
5965    *
5966    * @return The Java Class or nullptr if one of the
5967    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
5968    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
5969    */
getJClass(JNIEnv * env)5970    static jclass getJClass(JNIEnv* env) {
5971      return JavaClass::getJClass(env,"org/rocksdb/TransactionDB$DeadlockInfo");
5972   }
5973 };
5974 
5975 // The portal class for org.rocksdb.TransactionDB.DeadlockPath
5976 class DeadlockPathJni : public JavaClass {
5977  public:
5978   /**
5979    * Get the Java Class org.rocksdb.TransactionDB.DeadlockPath
5980    *
5981    * @param env A pointer to the Java environment
5982    *
5983    * @return The Java Class or nullptr if one of the
5984    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
5985    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
5986    */
getJClass(JNIEnv * env)5987   static jclass getJClass(JNIEnv* env) {
5988     return JavaClass::getJClass(env,
5989         "org/rocksdb/TransactionDB$DeadlockPath");
5990   }
5991 
5992   /**
5993    * Create a new Java org.rocksdb.TransactionDB.DeadlockPath object
5994    *
5995    * @param env A pointer to the Java environment
5996    *
5997    * @return A reference to a Java
5998    *     org.rocksdb.TransactionDB.DeadlockPath object,
5999    *     or nullptr if an an exception occurs
6000    */
construct(JNIEnv * env,const jobjectArray jdeadlock_infos,const bool limit_exceeded)6001   static jobject construct(JNIEnv* env,
6002     const jobjectArray jdeadlock_infos, const bool limit_exceeded) {
6003     jclass jclazz = getJClass(env);
6004     if(jclazz == nullptr) {
6005       // exception occurred accessing class
6006       return nullptr;
6007     }
6008 
6009     jmethodID mid = env->GetMethodID(
6010       jclazz, "<init>", "([LDeadlockInfo;Z)V");
6011     if (mid == nullptr) {
6012       // exception thrown: NoSuchMethodException or OutOfMemoryError
6013       return nullptr;
6014     }
6015 
6016     const jobject jdeadlock_path = env->NewObject(jclazz, mid,
6017       jdeadlock_infos, limit_exceeded);
6018     if(jdeadlock_path == nullptr) {
6019       // exception thrown: InstantiationException or OutOfMemoryError
6020       return nullptr;
6021     }
6022 
6023     return jdeadlock_path;
6024   }
6025 };
6026 
6027 class AbstractTableFilterJni
6028     : public RocksDBNativeClass<
6029           const ROCKSDB_NAMESPACE::TableFilterJniCallback*,
6030           AbstractTableFilterJni> {
6031  public:
6032   /**
6033    * Get the Java Method: TableFilter#filter(TableProperties)
6034    *
6035    * @param env A pointer to the Java environment
6036    *
6037    * @return The Java Method ID or nullptr if the class or method id could not
6038    *     be retrieved
6039    */
getFilterMethod(JNIEnv * env)6040   static jmethodID getFilterMethod(JNIEnv* env) {
6041     jclass jclazz = getJClass(env);
6042     if(jclazz == nullptr) {
6043       // exception occurred accessing class
6044       return nullptr;
6045     }
6046 
6047     static jmethodID mid =
6048         env->GetMethodID(jclazz, "filter", "(Lorg/rocksdb/TableProperties;)Z");
6049     assert(mid != nullptr);
6050     return mid;
6051   }
6052 
6053  private:
getJClass(JNIEnv * env)6054   static jclass getJClass(JNIEnv* env) {
6055     return JavaClass::getJClass(env, "org/rocksdb/TableFilter");
6056   }
6057 };
6058 
6059 class TablePropertiesJni : public JavaClass {
6060  public:
6061   /**
6062    * Create a new Java org.rocksdb.TableProperties object.
6063    *
6064    * @param env A pointer to the Java environment
6065    * @param table_properties A Cpp table properties object
6066    *
6067    * @return A reference to a Java org.rocksdb.TableProperties object, or
6068    * nullptr if an an exception occurs
6069    */
fromCppTableProperties(JNIEnv * env,const ROCKSDB_NAMESPACE::TableProperties & table_properties)6070   static jobject fromCppTableProperties(
6071       JNIEnv* env, const ROCKSDB_NAMESPACE::TableProperties& table_properties) {
6072     jclass jclazz = getJClass(env);
6073     if (jclazz == nullptr) {
6074       // exception occurred accessing class
6075       return nullptr;
6076     }
6077 
6078     jmethodID mid = env->GetMethodID(
6079         jclazz, "<init>",
6080         "(JJJJJJJJJJJJJJJJJJJJJ[BLjava/lang/String;Ljava/lang/String;Ljava/"
6081         "lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
6082         "String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V");
6083     if (mid == nullptr) {
6084       // exception thrown: NoSuchMethodException or OutOfMemoryError
6085       return nullptr;
6086     }
6087 
6088     jbyteArray jcolumn_family_name = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
6089         env, table_properties.column_family_name);
6090     if (jcolumn_family_name == nullptr) {
6091       // exception occurred creating java string
6092       return nullptr;
6093     }
6094 
6095     jstring jfilter_policy_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
6096         env, &table_properties.filter_policy_name, true);
6097     if (env->ExceptionCheck()) {
6098       // exception occurred creating java string
6099       env->DeleteLocalRef(jcolumn_family_name);
6100       return nullptr;
6101     }
6102 
6103     jstring jcomparator_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
6104         env, &table_properties.comparator_name, true);
6105     if (env->ExceptionCheck()) {
6106       // exception occurred creating java string
6107       env->DeleteLocalRef(jcolumn_family_name);
6108       env->DeleteLocalRef(jfilter_policy_name);
6109       return nullptr;
6110     }
6111 
6112     jstring jmerge_operator_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
6113         env, &table_properties.merge_operator_name, true);
6114     if (env->ExceptionCheck()) {
6115       // exception occurred creating java string
6116       env->DeleteLocalRef(jcolumn_family_name);
6117       env->DeleteLocalRef(jfilter_policy_name);
6118       env->DeleteLocalRef(jcomparator_name);
6119       return nullptr;
6120     }
6121 
6122     jstring jprefix_extractor_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
6123         env, &table_properties.prefix_extractor_name, true);
6124     if (env->ExceptionCheck()) {
6125       // exception occurred creating java string
6126       env->DeleteLocalRef(jcolumn_family_name);
6127       env->DeleteLocalRef(jfilter_policy_name);
6128       env->DeleteLocalRef(jcomparator_name);
6129       env->DeleteLocalRef(jmerge_operator_name);
6130       return nullptr;
6131     }
6132 
6133     jstring jproperty_collectors_names =
6134         ROCKSDB_NAMESPACE::JniUtil::toJavaString(
6135             env, &table_properties.property_collectors_names, true);
6136     if (env->ExceptionCheck()) {
6137       // exception occurred creating java string
6138       env->DeleteLocalRef(jcolumn_family_name);
6139       env->DeleteLocalRef(jfilter_policy_name);
6140       env->DeleteLocalRef(jcomparator_name);
6141       env->DeleteLocalRef(jmerge_operator_name);
6142       env->DeleteLocalRef(jprefix_extractor_name);
6143       return nullptr;
6144     }
6145 
6146     jstring jcompression_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
6147         env, &table_properties.compression_name, true);
6148     if (env->ExceptionCheck()) {
6149       // exception occurred creating java string
6150       env->DeleteLocalRef(jcolumn_family_name);
6151       env->DeleteLocalRef(jfilter_policy_name);
6152       env->DeleteLocalRef(jcomparator_name);
6153       env->DeleteLocalRef(jmerge_operator_name);
6154       env->DeleteLocalRef(jprefix_extractor_name);
6155       env->DeleteLocalRef(jproperty_collectors_names);
6156       return nullptr;
6157     }
6158 
6159     // Map<String, String>
6160     jobject juser_collected_properties =
6161         ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(
6162             env, &table_properties.user_collected_properties);
6163     if (env->ExceptionCheck()) {
6164       // exception occurred creating java map
6165       env->DeleteLocalRef(jcolumn_family_name);
6166       env->DeleteLocalRef(jfilter_policy_name);
6167       env->DeleteLocalRef(jcomparator_name);
6168       env->DeleteLocalRef(jmerge_operator_name);
6169       env->DeleteLocalRef(jprefix_extractor_name);
6170       env->DeleteLocalRef(jproperty_collectors_names);
6171       env->DeleteLocalRef(jcompression_name);
6172       return nullptr;
6173     }
6174 
6175     // Map<String, String>
6176     jobject jreadable_properties = ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(
6177         env, &table_properties.readable_properties);
6178     if (env->ExceptionCheck()) {
6179       // exception occurred creating java map
6180       env->DeleteLocalRef(jcolumn_family_name);
6181       env->DeleteLocalRef(jfilter_policy_name);
6182       env->DeleteLocalRef(jcomparator_name);
6183       env->DeleteLocalRef(jmerge_operator_name);
6184       env->DeleteLocalRef(jprefix_extractor_name);
6185       env->DeleteLocalRef(jproperty_collectors_names);
6186       env->DeleteLocalRef(jcompression_name);
6187       env->DeleteLocalRef(juser_collected_properties);
6188       return nullptr;
6189     }
6190 
6191     // Map<String, Long>
6192     jobject jproperties_offsets = ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(
6193         env, &table_properties.properties_offsets);
6194     if (env->ExceptionCheck()) {
6195       // exception occurred creating java map
6196       env->DeleteLocalRef(jcolumn_family_name);
6197       env->DeleteLocalRef(jfilter_policy_name);
6198       env->DeleteLocalRef(jcomparator_name);
6199       env->DeleteLocalRef(jmerge_operator_name);
6200       env->DeleteLocalRef(jprefix_extractor_name);
6201       env->DeleteLocalRef(jproperty_collectors_names);
6202       env->DeleteLocalRef(jcompression_name);
6203       env->DeleteLocalRef(juser_collected_properties);
6204       env->DeleteLocalRef(jreadable_properties);
6205       return nullptr;
6206     }
6207 
6208     jobject jtable_properties = env->NewObject(
6209         jclazz, mid, static_cast<jlong>(table_properties.data_size),
6210         static_cast<jlong>(table_properties.index_size),
6211         static_cast<jlong>(table_properties.index_partitions),
6212         static_cast<jlong>(table_properties.top_level_index_size),
6213         static_cast<jlong>(table_properties.index_key_is_user_key),
6214         static_cast<jlong>(table_properties.index_value_is_delta_encoded),
6215         static_cast<jlong>(table_properties.filter_size),
6216         static_cast<jlong>(table_properties.raw_key_size),
6217         static_cast<jlong>(table_properties.raw_value_size),
6218         static_cast<jlong>(table_properties.num_data_blocks),
6219         static_cast<jlong>(table_properties.num_entries),
6220         static_cast<jlong>(table_properties.num_deletions),
6221         static_cast<jlong>(table_properties.num_merge_operands),
6222         static_cast<jlong>(table_properties.num_range_deletions),
6223         static_cast<jlong>(table_properties.format_version),
6224         static_cast<jlong>(table_properties.fixed_key_len),
6225         static_cast<jlong>(table_properties.column_family_id),
6226         static_cast<jlong>(table_properties.creation_time),
6227         static_cast<jlong>(table_properties.oldest_key_time),
6228         static_cast<jlong>(
6229             table_properties.slow_compression_estimated_data_size),
6230         static_cast<jlong>(
6231             table_properties.fast_compression_estimated_data_size),
6232         jcolumn_family_name, jfilter_policy_name, jcomparator_name,
6233         jmerge_operator_name, jprefix_extractor_name,
6234         jproperty_collectors_names, jcompression_name,
6235         juser_collected_properties, jreadable_properties, jproperties_offsets);
6236 
6237     if (env->ExceptionCheck()) {
6238       return nullptr;
6239     }
6240 
6241     return jtable_properties;
6242   }
6243 
6244  private:
getJClass(JNIEnv * env)6245   static jclass getJClass(JNIEnv* env) {
6246     return JavaClass::getJClass(env, "org/rocksdb/TableProperties");
6247   }
6248 };
6249 
6250 class ColumnFamilyDescriptorJni : public JavaClass {
6251  public:
6252   /**
6253    * Get the Java Class org.rocksdb.ColumnFamilyDescriptor
6254    *
6255    * @param env A pointer to the Java environment
6256    *
6257    * @return The Java Class or nullptr if one of the
6258    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
6259    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
6260    */
getJClass(JNIEnv * env)6261   static jclass getJClass(JNIEnv* env) {
6262     return JavaClass::getJClass(env, "org/rocksdb/ColumnFamilyDescriptor");
6263   }
6264 
6265   /**
6266    * Create a new Java org.rocksdb.ColumnFamilyDescriptor object with the same
6267    * properties as the provided C++ ROCKSDB_NAMESPACE::ColumnFamilyDescriptor
6268    * object
6269    *
6270    * @param env A pointer to the Java environment
6271    * @param cfd A pointer to ROCKSDB_NAMESPACE::ColumnFamilyDescriptor object
6272    *
6273    * @return A reference to a Java org.rocksdb.ColumnFamilyDescriptor object, or
6274    * nullptr if an an exception occurs
6275    */
construct(JNIEnv * env,ColumnFamilyDescriptor * cfd)6276   static jobject construct(JNIEnv* env, ColumnFamilyDescriptor* cfd) {
6277     jbyteArray jcf_name = JniUtil::copyBytes(env, cfd->name);
6278     jobject cfopts = ColumnFamilyOptionsJni::construct(env, &(cfd->options));
6279 
6280     jclass jclazz = getJClass(env);
6281     if (jclazz == nullptr) {
6282       // exception occurred accessing class
6283       return nullptr;
6284     }
6285 
6286     jmethodID mid = env->GetMethodID(jclazz, "<init>",
6287                                      "([BLorg/rocksdb/ColumnFamilyOptions;)V");
6288     if (mid == nullptr) {
6289       // exception thrown: NoSuchMethodException or OutOfMemoryError
6290       env->DeleteLocalRef(jcf_name);
6291       return nullptr;
6292     }
6293 
6294     jobject jcfd = env->NewObject(jclazz, mid, jcf_name, cfopts);
6295     if (env->ExceptionCheck()) {
6296       env->DeleteLocalRef(jcf_name);
6297       return nullptr;
6298     }
6299 
6300     return jcfd;
6301   }
6302 
6303   /**
6304    * Get the Java Method: ColumnFamilyDescriptor#columnFamilyName
6305    *
6306    * @param env A pointer to the Java environment
6307    *
6308    * @return The Java Method ID or nullptr if the class or method id could not
6309    *     be retrieved
6310    */
getColumnFamilyNameMethod(JNIEnv * env)6311   static jmethodID getColumnFamilyNameMethod(JNIEnv* env) {
6312     jclass jclazz = getJClass(env);
6313     if (jclazz == nullptr) {
6314       // exception occurred accessing class
6315       return nullptr;
6316     }
6317 
6318     static jmethodID mid = env->GetMethodID(jclazz, "columnFamilyName", "()[B");
6319     assert(mid != nullptr);
6320     return mid;
6321   }
6322 
6323   /**
6324    * Get the Java Method: ColumnFamilyDescriptor#columnFamilyOptions
6325    *
6326    * @param env A pointer to the Java environment
6327    *
6328    * @return The Java Method ID or nullptr if the class or method id could not
6329    *     be retrieved
6330    */
getColumnFamilyOptionsMethod(JNIEnv * env)6331   static jmethodID getColumnFamilyOptionsMethod(JNIEnv* env) {
6332     jclass jclazz = getJClass(env);
6333     if (jclazz == nullptr) {
6334       // exception occurred accessing class
6335       return nullptr;
6336     }
6337 
6338     static jmethodID mid = env->GetMethodID(
6339         jclazz, "columnFamilyOptions", "()Lorg/rocksdb/ColumnFamilyOptions;");
6340     assert(mid != nullptr);
6341     return mid;
6342   }
6343 };
6344 
6345 // The portal class for org.rocksdb.IndexType
6346 class IndexTypeJni {
6347  public:
6348   // Returns the equivalent org.rocksdb.IndexType for the provided
6349   // C++ ROCKSDB_NAMESPACE::IndexType enum
toJavaIndexType(const ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType & index_type)6350   static jbyte toJavaIndexType(
6351       const ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType& index_type) {
6352     switch (index_type) {
6353       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::kBinarySearch:
6354         return 0x0;
6355       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::kHashSearch:
6356         return 0x1;
6357       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6358           kTwoLevelIndexSearch:
6359         return 0x2;
6360       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6361           kBinarySearchWithFirstKey:
6362         return 0x3;
6363       default:
6364         return 0x7F;  // undefined
6365     }
6366   }
6367 
6368   // Returns the equivalent C++ ROCKSDB_NAMESPACE::IndexType enum for the
6369   // provided Java org.rocksdb.IndexType
toCppIndexType(jbyte jindex_type)6370   static ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType toCppIndexType(
6371       jbyte jindex_type) {
6372     switch (jindex_type) {
6373       case 0x0:
6374         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6375             kBinarySearch;
6376       case 0x1:
6377         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6378             kHashSearch;
6379       case 0x2:
6380         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6381             kTwoLevelIndexSearch;
6382       case 0x3:
6383         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6384             kBinarySearchWithFirstKey;
6385       default:
6386         // undefined/default
6387         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexType::
6388             kBinarySearch;
6389     }
6390   }
6391 };
6392 
6393 // The portal class for org.rocksdb.DataBlockIndexType
6394 class DataBlockIndexTypeJni {
6395  public:
6396   // Returns the equivalent org.rocksdb.DataBlockIndexType for the provided
6397   // C++ ROCKSDB_NAMESPACE::DataBlockIndexType enum
toJavaDataBlockIndexType(const ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType & index_type)6398   static jbyte toJavaDataBlockIndexType(
6399       const ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType&
6400           index_type) {
6401     switch (index_type) {
6402       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType::
6403           kDataBlockBinarySearch:
6404         return 0x0;
6405       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType::
6406           kDataBlockBinaryAndHash:
6407         return 0x1;
6408       default:
6409         return 0x7F;  // undefined
6410     }
6411   }
6412 
6413   // Returns the equivalent C++ ROCKSDB_NAMESPACE::DataBlockIndexType enum for
6414   // the provided Java org.rocksdb.DataBlockIndexType
6415   static ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType
toCppDataBlockIndexType(jbyte jindex_type)6416   toCppDataBlockIndexType(jbyte jindex_type) {
6417     switch (jindex_type) {
6418       case 0x0:
6419         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType::
6420             kDataBlockBinarySearch;
6421       case 0x1:
6422         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType::
6423             kDataBlockBinaryAndHash;
6424       default:
6425         // undefined/default
6426         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::DataBlockIndexType::
6427             kDataBlockBinarySearch;
6428     }
6429   }
6430 };
6431 
6432 // The portal class for org.rocksdb.ChecksumType
6433 class ChecksumTypeJni {
6434  public:
6435   // Returns the equivalent org.rocksdb.ChecksumType for the provided
6436   // C++ ROCKSDB_NAMESPACE::ChecksumType enum
toJavaChecksumType(const ROCKSDB_NAMESPACE::ChecksumType & checksum_type)6437   static jbyte toJavaChecksumType(
6438       const ROCKSDB_NAMESPACE::ChecksumType& checksum_type) {
6439     switch (checksum_type) {
6440       case ROCKSDB_NAMESPACE::ChecksumType::kNoChecksum:
6441         return 0x0;
6442       case ROCKSDB_NAMESPACE::ChecksumType::kCRC32c:
6443         return 0x1;
6444       case ROCKSDB_NAMESPACE::ChecksumType::kxxHash:
6445         return 0x2;
6446       case ROCKSDB_NAMESPACE::ChecksumType::kxxHash64:
6447         return 0x3;
6448       default:
6449         return 0x7F;  // undefined
6450     }
6451   }
6452 
6453   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ChecksumType enum for the
6454   // provided Java org.rocksdb.ChecksumType
toCppChecksumType(jbyte jchecksum_type)6455   static ROCKSDB_NAMESPACE::ChecksumType toCppChecksumType(
6456       jbyte jchecksum_type) {
6457     switch (jchecksum_type) {
6458       case 0x0:
6459         return ROCKSDB_NAMESPACE::ChecksumType::kNoChecksum;
6460       case 0x1:
6461         return ROCKSDB_NAMESPACE::ChecksumType::kCRC32c;
6462       case 0x2:
6463         return ROCKSDB_NAMESPACE::ChecksumType::kxxHash;
6464       case 0x3:
6465         return ROCKSDB_NAMESPACE::ChecksumType::kxxHash64;
6466       default:
6467         // undefined/default
6468         return ROCKSDB_NAMESPACE::ChecksumType::kCRC32c;
6469     }
6470   }
6471 };
6472 
6473 // The portal class for org.rocksdb.IndexShorteningMode
6474 class IndexShorteningModeJni {
6475  public:
6476   // Returns the equivalent org.rocksdb.IndexShorteningMode for the provided
6477   // C++ ROCKSDB_NAMESPACE::IndexShorteningMode enum
toJavaIndexShorteningMode(const ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode & index_shortening_mode)6478   static jbyte toJavaIndexShorteningMode(
6479       const ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode&
6480           index_shortening_mode) {
6481     switch (index_shortening_mode) {
6482       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6483           kNoShortening:
6484         return 0x0;
6485       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6486           kShortenSeparators:
6487         return 0x1;
6488       case ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6489           kShortenSeparatorsAndSuccessor:
6490         return 0x2;
6491       default:
6492         return 0x7F;  // undefined
6493     }
6494   }
6495 
6496   // Returns the equivalent C++ ROCKSDB_NAMESPACE::IndexShorteningMode enum for
6497   // the provided Java org.rocksdb.IndexShorteningMode
6498   static ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode
toCppIndexShorteningMode(jbyte jindex_shortening_mode)6499   toCppIndexShorteningMode(jbyte jindex_shortening_mode) {
6500     switch (jindex_shortening_mode) {
6501       case 0x0:
6502         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6503             kNoShortening;
6504       case 0x1:
6505         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6506             kShortenSeparators;
6507       case 0x2:
6508         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6509             kShortenSeparatorsAndSuccessor;
6510       default:
6511         // undefined/default
6512         return ROCKSDB_NAMESPACE::BlockBasedTableOptions::IndexShorteningMode::
6513             kShortenSeparators;
6514     }
6515   }
6516 };
6517 
6518 // The portal class for org.rocksdb.Priority
6519 class PriorityJni {
6520  public:
6521   // Returns the equivalent org.rocksdb.Priority for the provided
6522   // C++ ROCKSDB_NAMESPACE::Env::Priority enum
toJavaPriority(const ROCKSDB_NAMESPACE::Env::Priority & priority)6523   static jbyte toJavaPriority(
6524       const ROCKSDB_NAMESPACE::Env::Priority& priority) {
6525     switch (priority) {
6526       case ROCKSDB_NAMESPACE::Env::Priority::BOTTOM:
6527         return 0x0;
6528       case ROCKSDB_NAMESPACE::Env::Priority::LOW:
6529         return 0x1;
6530       case ROCKSDB_NAMESPACE::Env::Priority::HIGH:
6531         return 0x2;
6532       case ROCKSDB_NAMESPACE::Env::Priority::TOTAL:
6533         return 0x3;
6534       default:
6535         return 0x7F;  // undefined
6536     }
6537   }
6538 
6539   // Returns the equivalent C++ ROCKSDB_NAMESPACE::env::Priority enum for the
6540   // provided Java org.rocksdb.Priority
toCppPriority(jbyte jpriority)6541   static ROCKSDB_NAMESPACE::Env::Priority toCppPriority(jbyte jpriority) {
6542     switch (jpriority) {
6543       case 0x0:
6544         return ROCKSDB_NAMESPACE::Env::Priority::BOTTOM;
6545       case 0x1:
6546         return ROCKSDB_NAMESPACE::Env::Priority::LOW;
6547       case 0x2:
6548         return ROCKSDB_NAMESPACE::Env::Priority::HIGH;
6549       case 0x3:
6550         return ROCKSDB_NAMESPACE::Env::Priority::TOTAL;
6551       default:
6552         // undefined/default
6553         return ROCKSDB_NAMESPACE::Env::Priority::LOW;
6554     }
6555   }
6556 };
6557 
6558 // The portal class for org.rocksdb.ThreadType
6559 class ThreadTypeJni {
6560  public:
6561   // Returns the equivalent org.rocksdb.ThreadType for the provided
6562   // C++ ROCKSDB_NAMESPACE::ThreadStatus::ThreadType enum
toJavaThreadType(const ROCKSDB_NAMESPACE::ThreadStatus::ThreadType & thread_type)6563   static jbyte toJavaThreadType(
6564       const ROCKSDB_NAMESPACE::ThreadStatus::ThreadType& thread_type) {
6565     switch (thread_type) {
6566       case ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::HIGH_PRIORITY:
6567         return 0x0;
6568       case ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::LOW_PRIORITY:
6569         return 0x1;
6570       case ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::USER:
6571         return 0x2;
6572       case ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::BOTTOM_PRIORITY:
6573         return 0x3;
6574       default:
6575         return 0x7F;  // undefined
6576     }
6577   }
6578 
6579   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ThreadStatus::ThreadType enum
6580   // for the provided Java org.rocksdb.ThreadType
toCppThreadType(jbyte jthread_type)6581   static ROCKSDB_NAMESPACE::ThreadStatus::ThreadType toCppThreadType(
6582       jbyte jthread_type) {
6583     switch (jthread_type) {
6584       case 0x0:
6585         return ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::HIGH_PRIORITY;
6586       case 0x1:
6587         return ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::LOW_PRIORITY;
6588       case 0x2:
6589         return ThreadStatus::ThreadType::USER;
6590       case 0x3:
6591         return ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::BOTTOM_PRIORITY;
6592       default:
6593         // undefined/default
6594         return ROCKSDB_NAMESPACE::ThreadStatus::ThreadType::LOW_PRIORITY;
6595     }
6596   }
6597 };
6598 
6599 // The portal class for org.rocksdb.OperationType
6600 class OperationTypeJni {
6601  public:
6602   // Returns the equivalent org.rocksdb.OperationType for the provided
6603   // C++ ROCKSDB_NAMESPACE::ThreadStatus::OperationType enum
toJavaOperationType(const ROCKSDB_NAMESPACE::ThreadStatus::OperationType & operation_type)6604   static jbyte toJavaOperationType(
6605       const ROCKSDB_NAMESPACE::ThreadStatus::OperationType& operation_type) {
6606     switch (operation_type) {
6607       case ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_UNKNOWN:
6608         return 0x0;
6609       case ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_COMPACTION:
6610         return 0x1;
6611       case ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_FLUSH:
6612         return 0x2;
6613       default:
6614         return 0x7F;  // undefined
6615     }
6616   }
6617 
6618   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ThreadStatus::OperationType
6619   // enum for the provided Java org.rocksdb.OperationType
toCppOperationType(jbyte joperation_type)6620   static ROCKSDB_NAMESPACE::ThreadStatus::OperationType toCppOperationType(
6621       jbyte joperation_type) {
6622     switch (joperation_type) {
6623       case 0x0:
6624         return ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_UNKNOWN;
6625       case 0x1:
6626         return ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_COMPACTION;
6627       case 0x2:
6628         return ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_FLUSH;
6629       default:
6630         // undefined/default
6631         return ROCKSDB_NAMESPACE::ThreadStatus::OperationType::OP_UNKNOWN;
6632     }
6633   }
6634 };
6635 
6636 // The portal class for org.rocksdb.OperationStage
6637 class OperationStageJni {
6638  public:
6639   // Returns the equivalent org.rocksdb.OperationStage for the provided
6640   // C++ ROCKSDB_NAMESPACE::ThreadStatus::OperationStage enum
toJavaOperationStage(const ROCKSDB_NAMESPACE::ThreadStatus::OperationStage & operation_stage)6641   static jbyte toJavaOperationStage(
6642       const ROCKSDB_NAMESPACE::ThreadStatus::OperationStage& operation_stage) {
6643     switch (operation_stage) {
6644       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::STAGE_UNKNOWN:
6645         return 0x0;
6646       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::STAGE_FLUSH_RUN:
6647         return 0x1;
6648       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6649           STAGE_FLUSH_WRITE_L0:
6650         return 0x2;
6651       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6652           STAGE_COMPACTION_PREPARE:
6653         return 0x3;
6654       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6655           STAGE_COMPACTION_RUN:
6656         return 0x4;
6657       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6658           STAGE_COMPACTION_PROCESS_KV:
6659         return 0x5;
6660       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6661           STAGE_COMPACTION_INSTALL:
6662         return 0x6;
6663       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6664           STAGE_COMPACTION_SYNC_FILE:
6665         return 0x7;
6666       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6667           STAGE_PICK_MEMTABLES_TO_FLUSH:
6668         return 0x8;
6669       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6670           STAGE_MEMTABLE_ROLLBACK:
6671         return 0x9;
6672       case ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6673           STAGE_MEMTABLE_INSTALL_FLUSH_RESULTS:
6674         return 0xA;
6675       default:
6676         return 0x7F;  // undefined
6677     }
6678   }
6679 
6680   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ThreadStatus::OperationStage
6681   // enum for the provided Java org.rocksdb.OperationStage
toCppOperationStage(jbyte joperation_stage)6682   static ROCKSDB_NAMESPACE::ThreadStatus::OperationStage toCppOperationStage(
6683       jbyte joperation_stage) {
6684     switch (joperation_stage) {
6685       case 0x0:
6686         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::STAGE_UNKNOWN;
6687       case 0x1:
6688         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::STAGE_FLUSH_RUN;
6689       case 0x2:
6690         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6691             STAGE_FLUSH_WRITE_L0;
6692       case 0x3:
6693         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6694             STAGE_COMPACTION_PREPARE;
6695       case 0x4:
6696         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6697             STAGE_COMPACTION_RUN;
6698       case 0x5:
6699         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6700             STAGE_COMPACTION_PROCESS_KV;
6701       case 0x6:
6702         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6703             STAGE_COMPACTION_INSTALL;
6704       case 0x7:
6705         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6706             STAGE_COMPACTION_SYNC_FILE;
6707       case 0x8:
6708         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6709             STAGE_PICK_MEMTABLES_TO_FLUSH;
6710       case 0x9:
6711         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6712             STAGE_MEMTABLE_ROLLBACK;
6713       case 0xA:
6714         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::
6715             STAGE_MEMTABLE_INSTALL_FLUSH_RESULTS;
6716       default:
6717         // undefined/default
6718         return ROCKSDB_NAMESPACE::ThreadStatus::OperationStage::STAGE_UNKNOWN;
6719     }
6720   }
6721 };
6722 
6723 // The portal class for org.rocksdb.StateType
6724 class StateTypeJni {
6725  public:
6726   // Returns the equivalent org.rocksdb.StateType for the provided
6727   // C++ ROCKSDB_NAMESPACE::ThreadStatus::StateType enum
toJavaStateType(const ROCKSDB_NAMESPACE::ThreadStatus::StateType & state_type)6728   static jbyte toJavaStateType(
6729       const ROCKSDB_NAMESPACE::ThreadStatus::StateType& state_type) {
6730     switch (state_type) {
6731       case ROCKSDB_NAMESPACE::ThreadStatus::StateType::STATE_UNKNOWN:
6732         return 0x0;
6733       case ROCKSDB_NAMESPACE::ThreadStatus::StateType::STATE_MUTEX_WAIT:
6734         return 0x1;
6735       default:
6736         return 0x7F;  // undefined
6737     }
6738   }
6739 
6740   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ThreadStatus::StateType enum
6741   // for the provided Java org.rocksdb.StateType
toCppStateType(jbyte jstate_type)6742   static ROCKSDB_NAMESPACE::ThreadStatus::StateType toCppStateType(
6743       jbyte jstate_type) {
6744     switch (jstate_type) {
6745       case 0x0:
6746         return ROCKSDB_NAMESPACE::ThreadStatus::StateType::STATE_UNKNOWN;
6747       case 0x1:
6748         return ROCKSDB_NAMESPACE::ThreadStatus::StateType::STATE_MUTEX_WAIT;
6749       default:
6750         // undefined/default
6751         return ROCKSDB_NAMESPACE::ThreadStatus::StateType::STATE_UNKNOWN;
6752     }
6753   }
6754 };
6755 
6756 // The portal class for org.rocksdb.ThreadStatus
6757 class ThreadStatusJni : public JavaClass {
6758  public:
6759   /**
6760    * Get the Java Class org.rocksdb.ThreadStatus
6761    *
6762    * @param env A pointer to the Java environment
6763    *
6764    * @return The Java Class or nullptr if one of the
6765    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
6766    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
6767    */
getJClass(JNIEnv * env)6768   static jclass getJClass(JNIEnv* env) {
6769     return JavaClass::getJClass(env,
6770         "org/rocksdb/ThreadStatus");
6771   }
6772 
6773   /**
6774    * Create a new Java org.rocksdb.ThreadStatus object with the same
6775    * properties as the provided C++ ROCKSDB_NAMESPACE::ThreadStatus object
6776    *
6777    * @param env A pointer to the Java environment
6778    * @param thread_status A pointer to ROCKSDB_NAMESPACE::ThreadStatus object
6779    *
6780    * @return A reference to a Java org.rocksdb.ColumnFamilyOptions object, or
6781    * nullptr if an an exception occurs
6782    */
construct(JNIEnv * env,const ROCKSDB_NAMESPACE::ThreadStatus * thread_status)6783   static jobject construct(
6784       JNIEnv* env, const ROCKSDB_NAMESPACE::ThreadStatus* thread_status) {
6785     jclass jclazz = getJClass(env);
6786     if(jclazz == nullptr) {
6787       // exception occurred accessing class
6788       return nullptr;
6789     }
6790 
6791     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JBLjava/lang/String;Ljava/lang/String;BJB[JB)V");
6792     if (mid == nullptr) {
6793       // exception thrown: NoSuchMethodException or OutOfMemoryError
6794       return nullptr;
6795     }
6796 
6797     jstring jdb_name =
6798         JniUtil::toJavaString(env, &(thread_status->db_name), true);
6799     if (env->ExceptionCheck()) {
6800         // an error occurred
6801         return nullptr;
6802     }
6803 
6804     jstring jcf_name =
6805         JniUtil::toJavaString(env, &(thread_status->cf_name), true);
6806     if (env->ExceptionCheck()) {
6807         // an error occurred
6808         env->DeleteLocalRef(jdb_name);
6809         return nullptr;
6810     }
6811 
6812     // long[]
6813     const jsize len = static_cast<jsize>(
6814         ROCKSDB_NAMESPACE::ThreadStatus::kNumOperationProperties);
6815     jlongArray joperation_properties =
6816         env->NewLongArray(len);
6817     if (joperation_properties == nullptr) {
6818       // an exception occurred
6819       env->DeleteLocalRef(jdb_name);
6820       env->DeleteLocalRef(jcf_name);
6821       return nullptr;
6822     }
6823     jboolean is_copy;
6824     jlong* body = env->GetLongArrayElements(joperation_properties, &is_copy);
6825     if (body == nullptr) {
6826         // exception thrown: OutOfMemoryError
6827         env->DeleteLocalRef(jdb_name);
6828         env->DeleteLocalRef(jcf_name);
6829         env->DeleteLocalRef(joperation_properties);
6830         return nullptr;
6831     }
6832     for (size_t i = 0; i < len; ++i) {
6833       body[i] = static_cast<jlong>(thread_status->op_properties[i]);
6834     }
6835     env->ReleaseLongArrayElements(joperation_properties, body,
6836                                   is_copy == JNI_TRUE ? 0 : JNI_ABORT);
6837 
6838     jobject jcfd = env->NewObject(jclazz, mid,
6839         static_cast<jlong>(thread_status->thread_id),
6840         ThreadTypeJni::toJavaThreadType(thread_status->thread_type),
6841         jdb_name,
6842         jcf_name,
6843         OperationTypeJni::toJavaOperationType(thread_status->operation_type),
6844         static_cast<jlong>(thread_status->op_elapsed_micros),
6845         OperationStageJni::toJavaOperationStage(thread_status->operation_stage),
6846         joperation_properties,
6847         StateTypeJni::toJavaStateType(thread_status->state_type));
6848     if (env->ExceptionCheck()) {
6849       // exception occurred
6850         env->DeleteLocalRef(jdb_name);
6851         env->DeleteLocalRef(jcf_name);
6852         env->DeleteLocalRef(joperation_properties);
6853       return nullptr;
6854     }
6855 
6856     // cleanup
6857     env->DeleteLocalRef(jdb_name);
6858     env->DeleteLocalRef(jcf_name);
6859     env->DeleteLocalRef(joperation_properties);
6860 
6861     return jcfd;
6862   }
6863 };
6864 
6865 // The portal class for org.rocksdb.CompactionStyle
6866 class CompactionStyleJni {
6867  public:
6868   // Returns the equivalent org.rocksdb.CompactionStyle for the provided
6869   // C++ ROCKSDB_NAMESPACE::CompactionStyle enum
toJavaCompactionStyle(const ROCKSDB_NAMESPACE::CompactionStyle & compaction_style)6870   static jbyte toJavaCompactionStyle(
6871       const ROCKSDB_NAMESPACE::CompactionStyle& compaction_style) {
6872     switch (compaction_style) {
6873       case ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleLevel:
6874         return 0x0;
6875       case ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleUniversal:
6876         return 0x1;
6877       case ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleFIFO:
6878         return 0x2;
6879       case ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleNone:
6880         return 0x3;
6881       default:
6882         return 0x7F;  // undefined
6883     }
6884   }
6885 
6886   // Returns the equivalent C++ ROCKSDB_NAMESPACE::CompactionStyle enum for the
6887   // provided Java org.rocksdb.CompactionStyle
toCppCompactionStyle(jbyte jcompaction_style)6888   static ROCKSDB_NAMESPACE::CompactionStyle toCppCompactionStyle(
6889       jbyte jcompaction_style) {
6890     switch (jcompaction_style) {
6891       case 0x0:
6892         return ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleLevel;
6893       case 0x1:
6894         return ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleUniversal;
6895       case 0x2:
6896         return ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleFIFO;
6897       case 0x3:
6898         return ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleNone;
6899       default:
6900         // undefined/default
6901         return ROCKSDB_NAMESPACE::CompactionStyle::kCompactionStyleLevel;
6902     }
6903   }
6904 };
6905 
6906 // The portal class for org.rocksdb.CompactionReason
6907 class CompactionReasonJni {
6908  public:
6909   // Returns the equivalent org.rocksdb.CompactionReason for the provided
6910   // C++ ROCKSDB_NAMESPACE::CompactionReason enum
toJavaCompactionReason(const ROCKSDB_NAMESPACE::CompactionReason & compaction_reason)6911   static jbyte toJavaCompactionReason(
6912       const ROCKSDB_NAMESPACE::CompactionReason& compaction_reason) {
6913     switch (compaction_reason) {
6914       case ROCKSDB_NAMESPACE::CompactionReason::kUnknown:
6915         return 0x0;
6916       case ROCKSDB_NAMESPACE::CompactionReason::kLevelL0FilesNum:
6917         return 0x1;
6918       case ROCKSDB_NAMESPACE::CompactionReason::kLevelMaxLevelSize:
6919         return 0x2;
6920       case ROCKSDB_NAMESPACE::CompactionReason::kUniversalSizeAmplification:
6921         return 0x3;
6922       case ROCKSDB_NAMESPACE::CompactionReason::kUniversalSizeRatio:
6923         return 0x4;
6924       case ROCKSDB_NAMESPACE::CompactionReason::kUniversalSortedRunNum:
6925         return 0x5;
6926       case ROCKSDB_NAMESPACE::CompactionReason::kFIFOMaxSize:
6927         return 0x6;
6928       case ROCKSDB_NAMESPACE::CompactionReason::kFIFOReduceNumFiles:
6929         return 0x7;
6930       case ROCKSDB_NAMESPACE::CompactionReason::kFIFOTtl:
6931         return 0x8;
6932       case ROCKSDB_NAMESPACE::CompactionReason::kManualCompaction:
6933         return 0x9;
6934       case ROCKSDB_NAMESPACE::CompactionReason::kFilesMarkedForCompaction:
6935         return 0x10;
6936       case ROCKSDB_NAMESPACE::CompactionReason::kBottommostFiles:
6937         return 0x0A;
6938       case ROCKSDB_NAMESPACE::CompactionReason::kTtl:
6939         return 0x0B;
6940       case ROCKSDB_NAMESPACE::CompactionReason::kFlush:
6941         return 0x0C;
6942       case ROCKSDB_NAMESPACE::CompactionReason::kExternalSstIngestion:
6943         return 0x0D;
6944       default:
6945         return 0x7F;  // undefined
6946     }
6947   }
6948 
6949   // Returns the equivalent C++ ROCKSDB_NAMESPACE::CompactionReason enum for the
6950   // provided Java org.rocksdb.CompactionReason
toCppCompactionReason(jbyte jcompaction_reason)6951   static ROCKSDB_NAMESPACE::CompactionReason toCppCompactionReason(
6952       jbyte jcompaction_reason) {
6953     switch (jcompaction_reason) {
6954       case 0x0:
6955         return ROCKSDB_NAMESPACE::CompactionReason::kUnknown;
6956       case 0x1:
6957         return ROCKSDB_NAMESPACE::CompactionReason::kLevelL0FilesNum;
6958       case 0x2:
6959         return ROCKSDB_NAMESPACE::CompactionReason::kLevelMaxLevelSize;
6960       case 0x3:
6961         return ROCKSDB_NAMESPACE::CompactionReason::kUniversalSizeAmplification;
6962       case 0x4:
6963         return ROCKSDB_NAMESPACE::CompactionReason::kUniversalSizeRatio;
6964       case 0x5:
6965         return ROCKSDB_NAMESPACE::CompactionReason::kUniversalSortedRunNum;
6966       case 0x6:
6967         return ROCKSDB_NAMESPACE::CompactionReason::kFIFOMaxSize;
6968       case 0x7:
6969         return ROCKSDB_NAMESPACE::CompactionReason::kFIFOReduceNumFiles;
6970       case 0x8:
6971         return ROCKSDB_NAMESPACE::CompactionReason::kFIFOTtl;
6972       case 0x9:
6973         return ROCKSDB_NAMESPACE::CompactionReason::kManualCompaction;
6974       case 0x10:
6975         return ROCKSDB_NAMESPACE::CompactionReason::kFilesMarkedForCompaction;
6976       case 0x0A:
6977         return ROCKSDB_NAMESPACE::CompactionReason::kBottommostFiles;
6978       case 0x0B:
6979         return ROCKSDB_NAMESPACE::CompactionReason::kTtl;
6980       case 0x0C:
6981         return ROCKSDB_NAMESPACE::CompactionReason::kFlush;
6982       case 0x0D:
6983         return ROCKSDB_NAMESPACE::CompactionReason::kExternalSstIngestion;
6984       default:
6985         // undefined/default
6986         return ROCKSDB_NAMESPACE::CompactionReason::kUnknown;
6987     }
6988   }
6989 };
6990 
6991 // The portal class for org.rocksdb.WalFileType
6992 class WalFileTypeJni {
6993  public:
6994   // Returns the equivalent org.rocksdb.WalFileType for the provided
6995   // C++ ROCKSDB_NAMESPACE::WalFileType enum
toJavaWalFileType(const ROCKSDB_NAMESPACE::WalFileType & wal_file_type)6996   static jbyte toJavaWalFileType(
6997       const ROCKSDB_NAMESPACE::WalFileType& wal_file_type) {
6998     switch (wal_file_type) {
6999       case ROCKSDB_NAMESPACE::WalFileType::kArchivedLogFile:
7000         return 0x0;
7001       case ROCKSDB_NAMESPACE::WalFileType::kAliveLogFile:
7002         return 0x1;
7003       default:
7004         return 0x7F;  // undefined
7005     }
7006   }
7007 
7008   // Returns the equivalent C++ ROCKSDB_NAMESPACE::WalFileType enum for the
7009   // provided Java org.rocksdb.WalFileType
toCppWalFileType(jbyte jwal_file_type)7010   static ROCKSDB_NAMESPACE::WalFileType toCppWalFileType(jbyte jwal_file_type) {
7011     switch (jwal_file_type) {
7012       case 0x0:
7013         return ROCKSDB_NAMESPACE::WalFileType::kArchivedLogFile;
7014       case 0x1:
7015         return ROCKSDB_NAMESPACE::WalFileType::kAliveLogFile;
7016       default:
7017         // undefined/default
7018         return ROCKSDB_NAMESPACE::WalFileType::kAliveLogFile;
7019     }
7020   }
7021 };
7022 
7023 class LogFileJni : public JavaClass {
7024  public:
7025   /**
7026    * Create a new Java org.rocksdb.LogFile object.
7027    *
7028    * @param env A pointer to the Java environment
7029    * @param log_file A Cpp log file object
7030    *
7031    * @return A reference to a Java org.rocksdb.LogFile object, or
7032    * nullptr if an an exception occurs
7033    */
fromCppLogFile(JNIEnv * env,ROCKSDB_NAMESPACE::LogFile * log_file)7034   static jobject fromCppLogFile(JNIEnv* env,
7035                                 ROCKSDB_NAMESPACE::LogFile* log_file) {
7036     jclass jclazz = getJClass(env);
7037     if (jclazz == nullptr) {
7038       // exception occurred accessing class
7039       return nullptr;
7040     }
7041 
7042     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;JBJJ)V");
7043     if (mid == nullptr) {
7044       // exception thrown: NoSuchMethodException or OutOfMemoryError
7045       return nullptr;
7046     }
7047 
7048     std::string path_name = log_file->PathName();
7049     jstring jpath_name =
7050         ROCKSDB_NAMESPACE::JniUtil::toJavaString(env, &path_name, true);
7051     if (env->ExceptionCheck()) {
7052       // exception occurred creating java string
7053       return nullptr;
7054     }
7055 
7056     jobject jlog_file = env->NewObject(
7057         jclazz, mid, jpath_name, static_cast<jlong>(log_file->LogNumber()),
7058         ROCKSDB_NAMESPACE::WalFileTypeJni::toJavaWalFileType(log_file->Type()),
7059         static_cast<jlong>(log_file->StartSequence()),
7060         static_cast<jlong>(log_file->SizeFileBytes()));
7061 
7062     if (env->ExceptionCheck()) {
7063       env->DeleteLocalRef(jpath_name);
7064       return nullptr;
7065     }
7066 
7067     // cleanup
7068     env->DeleteLocalRef(jpath_name);
7069 
7070     return jlog_file;
7071   }
7072 
getJClass(JNIEnv * env)7073   static jclass getJClass(JNIEnv* env) {
7074     return JavaClass::getJClass(env, "org/rocksdb/LogFile");
7075   }
7076 };
7077 
7078 class LiveFileMetaDataJni : public JavaClass {
7079  public:
7080   /**
7081    * Create a new Java org.rocksdb.LiveFileMetaData object.
7082    *
7083    * @param env A pointer to the Java environment
7084    * @param live_file_meta_data A Cpp live file meta data object
7085    *
7086    * @return A reference to a Java org.rocksdb.LiveFileMetaData object, or
7087    * nullptr if an an exception occurs
7088    */
fromCppLiveFileMetaData(JNIEnv * env,ROCKSDB_NAMESPACE::LiveFileMetaData * live_file_meta_data)7089   static jobject fromCppLiveFileMetaData(
7090       JNIEnv* env, ROCKSDB_NAMESPACE::LiveFileMetaData* live_file_meta_data) {
7091     jclass jclazz = getJClass(env);
7092     if (jclazz == nullptr) {
7093       // exception occurred accessing class
7094       return nullptr;
7095     }
7096 
7097     jmethodID mid = env->GetMethodID(jclazz, "<init>", "([BILjava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ)V");
7098     if (mid == nullptr) {
7099       // exception thrown: NoSuchMethodException or OutOfMemoryError
7100       return nullptr;
7101     }
7102 
7103     jbyteArray jcolumn_family_name = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
7104         env, live_file_meta_data->column_family_name);
7105     if (jcolumn_family_name == nullptr) {
7106       // exception occurred creating java byte array
7107       return nullptr;
7108     }
7109 
7110     jstring jfile_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
7111         env, &live_file_meta_data->name, true);
7112     if (env->ExceptionCheck()) {
7113       // exception occurred creating java string
7114       env->DeleteLocalRef(jcolumn_family_name);
7115       return nullptr;
7116     }
7117 
7118     jstring jpath = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
7119         env, &live_file_meta_data->db_path, true);
7120     if (env->ExceptionCheck()) {
7121       // exception occurred creating java string
7122       env->DeleteLocalRef(jcolumn_family_name);
7123       env->DeleteLocalRef(jfile_name);
7124       return nullptr;
7125     }
7126 
7127     jbyteArray jsmallest_key = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
7128         env, live_file_meta_data->smallestkey);
7129     if (jsmallest_key == nullptr) {
7130       // exception occurred creating java byte array
7131       env->DeleteLocalRef(jcolumn_family_name);
7132       env->DeleteLocalRef(jfile_name);
7133       env->DeleteLocalRef(jpath);
7134       return nullptr;
7135     }
7136 
7137     jbyteArray jlargest_key = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
7138         env, live_file_meta_data->largestkey);
7139     if (jlargest_key == nullptr) {
7140       // exception occurred creating java byte array
7141       env->DeleteLocalRef(jcolumn_family_name);
7142       env->DeleteLocalRef(jfile_name);
7143       env->DeleteLocalRef(jpath);
7144       env->DeleteLocalRef(jsmallest_key);
7145       return nullptr;
7146     }
7147 
7148     jobject jlive_file_meta_data = env->NewObject(jclazz, mid,
7149         jcolumn_family_name,
7150         static_cast<jint>(live_file_meta_data->level),
7151         jfile_name,
7152         jpath,
7153         static_cast<jlong>(live_file_meta_data->size),
7154         static_cast<jlong>(live_file_meta_data->smallest_seqno),
7155         static_cast<jlong>(live_file_meta_data->largest_seqno),
7156         jsmallest_key,
7157         jlargest_key,
7158         static_cast<jlong>(live_file_meta_data->num_reads_sampled),
7159         static_cast<jboolean>(live_file_meta_data->being_compacted),
7160         static_cast<jlong>(live_file_meta_data->num_entries),
7161         static_cast<jlong>(live_file_meta_data->num_deletions)
7162     );
7163 
7164     if (env->ExceptionCheck()) {
7165       env->DeleteLocalRef(jcolumn_family_name);
7166       env->DeleteLocalRef(jfile_name);
7167       env->DeleteLocalRef(jpath);
7168       env->DeleteLocalRef(jsmallest_key);
7169       env->DeleteLocalRef(jlargest_key);
7170       return nullptr;
7171     }
7172 
7173     // cleanup
7174     env->DeleteLocalRef(jcolumn_family_name);
7175     env->DeleteLocalRef(jfile_name);
7176     env->DeleteLocalRef(jpath);
7177     env->DeleteLocalRef(jsmallest_key);
7178     env->DeleteLocalRef(jlargest_key);
7179 
7180     return jlive_file_meta_data;
7181   }
7182 
getJClass(JNIEnv * env)7183   static jclass getJClass(JNIEnv* env) {
7184     return JavaClass::getJClass(env, "org/rocksdb/LiveFileMetaData");
7185   }
7186 };
7187 
7188 class SstFileMetaDataJni : public JavaClass {
7189  public:
7190   /**
7191    * Create a new Java org.rocksdb.SstFileMetaData object.
7192    *
7193    * @param env A pointer to the Java environment
7194    * @param sst_file_meta_data A Cpp sst file meta data object
7195    *
7196    * @return A reference to a Java org.rocksdb.SstFileMetaData object, or
7197    * nullptr if an an exception occurs
7198    */
fromCppSstFileMetaData(JNIEnv * env,const ROCKSDB_NAMESPACE::SstFileMetaData * sst_file_meta_data)7199   static jobject fromCppSstFileMetaData(
7200       JNIEnv* env,
7201       const ROCKSDB_NAMESPACE::SstFileMetaData* sst_file_meta_data) {
7202     jclass jclazz = getJClass(env);
7203     if (jclazz == nullptr) {
7204       // exception occurred accessing class
7205       return nullptr;
7206     }
7207 
7208     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ)V");
7209     if (mid == nullptr) {
7210       // exception thrown: NoSuchMethodException or OutOfMemoryError
7211       return nullptr;
7212     }
7213 
7214     jstring jfile_name = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
7215         env, &sst_file_meta_data->name, true);
7216     if (jfile_name == nullptr) {
7217       // exception occurred creating java byte array
7218       return nullptr;
7219     }
7220 
7221     jstring jpath = ROCKSDB_NAMESPACE::JniUtil::toJavaString(
7222         env, &sst_file_meta_data->db_path, true);
7223     if (jpath == nullptr) {
7224       // exception occurred creating java byte array
7225       env->DeleteLocalRef(jfile_name);
7226       return nullptr;
7227     }
7228 
7229     jbyteArray jsmallest_key = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
7230         env, sst_file_meta_data->smallestkey);
7231     if (jsmallest_key == nullptr) {
7232       // exception occurred creating java byte array
7233       env->DeleteLocalRef(jfile_name);
7234       env->DeleteLocalRef(jpath);
7235       return nullptr;
7236     }
7237 
7238     jbyteArray jlargest_key = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
7239         env, sst_file_meta_data->largestkey);
7240     if (jlargest_key == nullptr) {
7241       // exception occurred creating java byte array
7242       env->DeleteLocalRef(jfile_name);
7243       env->DeleteLocalRef(jpath);
7244       env->DeleteLocalRef(jsmallest_key);
7245       return nullptr;
7246     }
7247 
7248     jobject jsst_file_meta_data = env->NewObject(jclazz, mid,
7249         jfile_name,
7250         jpath,
7251         static_cast<jlong>(sst_file_meta_data->size),
7252         static_cast<jint>(sst_file_meta_data->smallest_seqno),
7253         static_cast<jlong>(sst_file_meta_data->largest_seqno),
7254         jsmallest_key,
7255         jlargest_key,
7256         static_cast<jlong>(sst_file_meta_data->num_reads_sampled),
7257         static_cast<jboolean>(sst_file_meta_data->being_compacted),
7258         static_cast<jlong>(sst_file_meta_data->num_entries),
7259         static_cast<jlong>(sst_file_meta_data->num_deletions)
7260     );
7261 
7262     if (env->ExceptionCheck()) {
7263       env->DeleteLocalRef(jfile_name);
7264       env->DeleteLocalRef(jpath);
7265       env->DeleteLocalRef(jsmallest_key);
7266       env->DeleteLocalRef(jlargest_key);
7267       return nullptr;
7268     }
7269 
7270     // cleanup
7271       env->DeleteLocalRef(jfile_name);
7272       env->DeleteLocalRef(jpath);
7273       env->DeleteLocalRef(jsmallest_key);
7274       env->DeleteLocalRef(jlargest_key);
7275 
7276     return jsst_file_meta_data;
7277   }
7278 
getJClass(JNIEnv * env)7279   static jclass getJClass(JNIEnv* env) {
7280     return JavaClass::getJClass(env, "org/rocksdb/SstFileMetaData");
7281   }
7282 };
7283 
7284 class LevelMetaDataJni : public JavaClass {
7285  public:
7286   /**
7287    * Create a new Java org.rocksdb.LevelMetaData object.
7288    *
7289    * @param env A pointer to the Java environment
7290    * @param level_meta_data A Cpp level meta data object
7291    *
7292    * @return A reference to a Java org.rocksdb.LevelMetaData object, or
7293    * nullptr if an an exception occurs
7294    */
fromCppLevelMetaData(JNIEnv * env,const ROCKSDB_NAMESPACE::LevelMetaData * level_meta_data)7295   static jobject fromCppLevelMetaData(
7296       JNIEnv* env, const ROCKSDB_NAMESPACE::LevelMetaData* level_meta_data) {
7297     jclass jclazz = getJClass(env);
7298     if (jclazz == nullptr) {
7299       // exception occurred accessing class
7300       return nullptr;
7301     }
7302 
7303     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(IJ[Lorg/rocksdb/SstFileMetaData;)V");
7304     if (mid == nullptr) {
7305       // exception thrown: NoSuchMethodException or OutOfMemoryError
7306       return nullptr;
7307     }
7308 
7309     const jsize jlen =
7310         static_cast<jsize>(level_meta_data->files.size());
7311     jobjectArray jfiles = env->NewObjectArray(jlen, SstFileMetaDataJni::getJClass(env), nullptr);
7312     if (jfiles == nullptr) {
7313       // exception thrown: OutOfMemoryError
7314       return nullptr;
7315     }
7316 
7317     jsize i = 0;
7318     for (auto it = level_meta_data->files.begin();
7319         it != level_meta_data->files.end(); ++it) {
7320       jobject jfile = SstFileMetaDataJni::fromCppSstFileMetaData(env, &(*it));
7321       if (jfile == nullptr) {
7322         // exception occurred
7323         env->DeleteLocalRef(jfiles);
7324         return nullptr;
7325       }
7326       env->SetObjectArrayElement(jfiles, i++, jfile);
7327     }
7328 
7329     jobject jlevel_meta_data = env->NewObject(jclazz, mid,
7330         static_cast<jint>(level_meta_data->level),
7331         static_cast<jlong>(level_meta_data->size),
7332         jfiles
7333     );
7334 
7335     if (env->ExceptionCheck()) {
7336       env->DeleteLocalRef(jfiles);
7337       return nullptr;
7338     }
7339 
7340     // cleanup
7341     env->DeleteLocalRef(jfiles);
7342 
7343     return jlevel_meta_data;
7344   }
7345 
getJClass(JNIEnv * env)7346   static jclass getJClass(JNIEnv* env) {
7347     return JavaClass::getJClass(env, "org/rocksdb/LevelMetaData");
7348   }
7349 };
7350 
7351 class ColumnFamilyMetaDataJni : public JavaClass {
7352  public:
7353   /**
7354    * Create a new Java org.rocksdb.ColumnFamilyMetaData object.
7355    *
7356    * @param env A pointer to the Java environment
7357    * @param column_famly_meta_data A Cpp live file meta data object
7358    *
7359    * @return A reference to a Java org.rocksdb.ColumnFamilyMetaData object, or
7360    * nullptr if an an exception occurs
7361    */
fromCppColumnFamilyMetaData(JNIEnv * env,const ROCKSDB_NAMESPACE::ColumnFamilyMetaData * column_famly_meta_data)7362   static jobject fromCppColumnFamilyMetaData(
7363       JNIEnv* env,
7364       const ROCKSDB_NAMESPACE::ColumnFamilyMetaData* column_famly_meta_data) {
7365     jclass jclazz = getJClass(env);
7366     if (jclazz == nullptr) {
7367       // exception occurred accessing class
7368       return nullptr;
7369     }
7370 
7371     jmethodID mid = env->GetMethodID(jclazz, "<init>", "(JJ[B[Lorg/rocksdb/LevelMetaData;)V");
7372     if (mid == nullptr) {
7373       // exception thrown: NoSuchMethodException or OutOfMemoryError
7374       return nullptr;
7375     }
7376 
7377     jbyteArray jname = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
7378         env, column_famly_meta_data->name);
7379     if (jname == nullptr) {
7380       // exception occurred creating java byte array
7381       return nullptr;
7382     }
7383 
7384     const jsize jlen =
7385         static_cast<jsize>(column_famly_meta_data->levels.size());
7386     jobjectArray jlevels = env->NewObjectArray(jlen, LevelMetaDataJni::getJClass(env), nullptr);
7387     if(jlevels == nullptr) {
7388       // exception thrown: OutOfMemoryError
7389       env->DeleteLocalRef(jname);
7390       return nullptr;
7391     }
7392 
7393     jsize i = 0;
7394     for (auto it = column_famly_meta_data->levels.begin();
7395         it != column_famly_meta_data->levels.end(); ++it) {
7396       jobject jlevel = LevelMetaDataJni::fromCppLevelMetaData(env, &(*it));
7397       if (jlevel == nullptr) {
7398         // exception occurred
7399         env->DeleteLocalRef(jname);
7400         env->DeleteLocalRef(jlevels);
7401         return nullptr;
7402       }
7403       env->SetObjectArrayElement(jlevels, i++, jlevel);
7404     }
7405 
7406     jobject jcolumn_family_meta_data = env->NewObject(jclazz, mid,
7407         static_cast<jlong>(column_famly_meta_data->size),
7408         static_cast<jlong>(column_famly_meta_data->file_count),
7409         jname,
7410         jlevels
7411     );
7412 
7413     if (env->ExceptionCheck()) {
7414       env->DeleteLocalRef(jname);
7415       env->DeleteLocalRef(jlevels);
7416       return nullptr;
7417     }
7418 
7419     // cleanup
7420     env->DeleteLocalRef(jname);
7421     env->DeleteLocalRef(jlevels);
7422 
7423     return jcolumn_family_meta_data;
7424   }
7425 
getJClass(JNIEnv * env)7426   static jclass getJClass(JNIEnv* env) {
7427     return JavaClass::getJClass(env, "org/rocksdb/ColumnFamilyMetaData");
7428   }
7429 };
7430 
7431 // The portal class for org.rocksdb.AbstractTraceWriter
7432 class AbstractTraceWriterJni
7433     : public RocksDBNativeClass<
7434           const ROCKSDB_NAMESPACE::TraceWriterJniCallback*,
7435           AbstractTraceWriterJni> {
7436  public:
7437   /**
7438    * Get the Java Class org.rocksdb.AbstractTraceWriter
7439    *
7440    * @param env A pointer to the Java environment
7441    *
7442    * @return The Java Class or nullptr if one of the
7443    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
7444    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7445    */
getJClass(JNIEnv * env)7446   static jclass getJClass(JNIEnv* env) {
7447     return RocksDBNativeClass::getJClass(env,
7448         "org/rocksdb/AbstractTraceWriter");
7449   }
7450 
7451   /**
7452    * Get the Java Method: AbstractTraceWriter#write
7453    *
7454    * @param env A pointer to the Java environment
7455    *
7456    * @return The Java Method ID or nullptr if the class or method id could not
7457    *     be retrieved
7458    */
getWriteProxyMethodId(JNIEnv * env)7459   static jmethodID getWriteProxyMethodId(JNIEnv* env) {
7460     jclass jclazz = getJClass(env);
7461     if(jclazz == nullptr) {
7462       // exception occurred accessing class
7463       return nullptr;
7464     }
7465 
7466     static jmethodID mid = env->GetMethodID(
7467         jclazz, "writeProxy", "(J)S");
7468     assert(mid != nullptr);
7469     return mid;
7470   }
7471 
7472   /**
7473    * Get the Java Method: AbstractTraceWriter#closeWriter
7474    *
7475    * @param env A pointer to the Java environment
7476    *
7477    * @return The Java Method ID or nullptr if the class or method id could not
7478    *     be retrieved
7479    */
getCloseWriterProxyMethodId(JNIEnv * env)7480   static jmethodID getCloseWriterProxyMethodId(JNIEnv* env) {
7481     jclass jclazz = getJClass(env);
7482     if(jclazz == nullptr) {
7483       // exception occurred accessing class
7484       return nullptr;
7485     }
7486 
7487     static jmethodID mid = env->GetMethodID(
7488         jclazz, "closeWriterProxy", "()S");
7489     assert(mid != nullptr);
7490     return mid;
7491   }
7492 
7493   /**
7494    * Get the Java Method: AbstractTraceWriter#getFileSize
7495    *
7496    * @param env A pointer to the Java environment
7497    *
7498    * @return The Java Method ID or nullptr if the class or method id could not
7499    *     be retrieved
7500    */
getGetFileSizeMethodId(JNIEnv * env)7501   static jmethodID getGetFileSizeMethodId(JNIEnv* env) {
7502     jclass jclazz = getJClass(env);
7503     if(jclazz == nullptr) {
7504       // exception occurred accessing class
7505       return nullptr;
7506     }
7507 
7508     static jmethodID mid = env->GetMethodID(
7509         jclazz, "getFileSize", "()J");
7510     assert(mid != nullptr);
7511     return mid;
7512   }
7513 };
7514 
7515 // The portal class for org.rocksdb.AbstractWalFilter
7516 class AbstractWalFilterJni
7517     : public RocksDBNativeClass<const ROCKSDB_NAMESPACE::WalFilterJniCallback*,
7518                                 AbstractWalFilterJni> {
7519  public:
7520   /**
7521    * Get the Java Class org.rocksdb.AbstractWalFilter
7522    *
7523    * @param env A pointer to the Java environment
7524    *
7525    * @return The Java Class or nullptr if one of the
7526    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
7527    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7528    */
getJClass(JNIEnv * env)7529   static jclass getJClass(JNIEnv* env) {
7530     return RocksDBNativeClass::getJClass(env,
7531         "org/rocksdb/AbstractWalFilter");
7532   }
7533 
7534   /**
7535    * Get the Java Method: AbstractWalFilter#columnFamilyLogNumberMap
7536    *
7537    * @param env A pointer to the Java environment
7538    *
7539    * @return The Java Method ID or nullptr if the class or method id could not
7540    *     be retrieved
7541    */
getColumnFamilyLogNumberMapMethodId(JNIEnv * env)7542   static jmethodID getColumnFamilyLogNumberMapMethodId(JNIEnv* env) {
7543     jclass jclazz = getJClass(env);
7544     if(jclazz == nullptr) {
7545       // exception occurred accessing class
7546       return nullptr;
7547     }
7548 
7549     static jmethodID mid = env->GetMethodID(
7550         jclazz, "columnFamilyLogNumberMap",
7551         "(Ljava/util/Map;Ljava/util/Map;)V");
7552     assert(mid != nullptr);
7553     return mid;
7554   }
7555 
7556   /**
7557    * Get the Java Method: AbstractTraceWriter#logRecordFoundProxy
7558    *
7559    * @param env A pointer to the Java environment
7560    *
7561    * @return The Java Method ID or nullptr if the class or method id could not
7562    *     be retrieved
7563    */
getLogRecordFoundProxyMethodId(JNIEnv * env)7564   static jmethodID getLogRecordFoundProxyMethodId(JNIEnv* env) {
7565     jclass jclazz = getJClass(env);
7566     if(jclazz == nullptr) {
7567       // exception occurred accessing class
7568       return nullptr;
7569     }
7570 
7571     static jmethodID mid = env->GetMethodID(
7572         jclazz, "logRecordFoundProxy", "(JLjava/lang/String;JJ)S");
7573     assert(mid != nullptr);
7574     return mid;
7575   }
7576 
7577   /**
7578    * Get the Java Method: AbstractTraceWriter#name
7579    *
7580    * @param env A pointer to the Java environment
7581    *
7582    * @return The Java Method ID or nullptr if the class or method id could not
7583    *     be retrieved
7584    */
getNameMethodId(JNIEnv * env)7585   static jmethodID getNameMethodId(JNIEnv* env) {
7586     jclass jclazz = getJClass(env);
7587     if(jclazz == nullptr) {
7588       // exception occurred accessing class
7589       return nullptr;
7590     }
7591 
7592     static jmethodID mid = env->GetMethodID(
7593         jclazz, "name", "()Ljava/lang/String;");
7594     assert(mid != nullptr);
7595     return mid;
7596   }
7597 };
7598 
7599 // The portal class for org.rocksdb.WalProcessingOption
7600 class WalProcessingOptionJni {
7601  public:
7602   // Returns the equivalent org.rocksdb.WalProcessingOption for the provided
7603   // C++ ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption enum
toJavaWalProcessingOption(const ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption & wal_processing_option)7604   static jbyte toJavaWalProcessingOption(
7605       const ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption&
7606           wal_processing_option) {
7607     switch (wal_processing_option) {
7608       case ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::
7609           kContinueProcessing:
7610         return 0x0;
7611       case ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::
7612           kIgnoreCurrentRecord:
7613         return 0x1;
7614       case ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::kStopReplay:
7615         return 0x2;
7616       case ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::kCorruptedRecord:
7617         return 0x3;
7618       default:
7619         return 0x7F;  // undefined
7620     }
7621   }
7622 
7623   // Returns the equivalent C++
7624   // ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption enum for the provided
7625   // Java org.rocksdb.WalProcessingOption
7626   static ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption
toCppWalProcessingOption(jbyte jwal_processing_option)7627   toCppWalProcessingOption(jbyte jwal_processing_option) {
7628     switch (jwal_processing_option) {
7629       case 0x0:
7630         return ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::
7631             kContinueProcessing;
7632       case 0x1:
7633         return ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::
7634             kIgnoreCurrentRecord;
7635       case 0x2:
7636         return ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::kStopReplay;
7637       case 0x3:
7638         return ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::
7639             kCorruptedRecord;
7640       default:
7641         // undefined/default
7642         return ROCKSDB_NAMESPACE::WalFilter::WalProcessingOption::
7643             kCorruptedRecord;
7644     }
7645   }
7646 };
7647 
7648 // The portal class for org.rocksdb.ReusedSynchronisationType
7649 class ReusedSynchronisationTypeJni {
7650  public:
7651   // Returns the equivalent org.rocksdb.ReusedSynchronisationType for the
7652   // provided C++ ROCKSDB_NAMESPACE::ReusedSynchronisationType enum
toJavaReusedSynchronisationType(const ROCKSDB_NAMESPACE::ReusedSynchronisationType & reused_synchronisation_type)7653   static jbyte toJavaReusedSynchronisationType(
7654       const ROCKSDB_NAMESPACE::ReusedSynchronisationType&
7655           reused_synchronisation_type) {
7656     switch(reused_synchronisation_type) {
7657       case ROCKSDB_NAMESPACE::ReusedSynchronisationType::MUTEX:
7658         return 0x0;
7659       case ROCKSDB_NAMESPACE::ReusedSynchronisationType::ADAPTIVE_MUTEX:
7660         return 0x1;
7661       case ROCKSDB_NAMESPACE::ReusedSynchronisationType::THREAD_LOCAL:
7662         return 0x2;
7663       default:
7664         return 0x7F;  // undefined
7665     }
7666   }
7667 
7668   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ReusedSynchronisationType
7669   // enum for the provided Java org.rocksdb.ReusedSynchronisationType
7670   static ROCKSDB_NAMESPACE::ReusedSynchronisationType
toCppReusedSynchronisationType(jbyte reused_synchronisation_type)7671   toCppReusedSynchronisationType(jbyte reused_synchronisation_type) {
7672     switch(reused_synchronisation_type) {
7673       case 0x0:
7674         return ROCKSDB_NAMESPACE::ReusedSynchronisationType::MUTEX;
7675       case 0x1:
7676         return ROCKSDB_NAMESPACE::ReusedSynchronisationType::ADAPTIVE_MUTEX;
7677       case 0x2:
7678         return ROCKSDB_NAMESPACE::ReusedSynchronisationType::THREAD_LOCAL;
7679       default:
7680         // undefined/default
7681         return ROCKSDB_NAMESPACE::ReusedSynchronisationType::ADAPTIVE_MUTEX;
7682     }
7683   }
7684 };
7685 // The portal class for org.rocksdb.SanityLevel
7686 class SanityLevelJni {
7687  public:
7688   // Returns the equivalent org.rocksdb.SanityLevel for the provided
7689   // C++ ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel enum
toJavaSanityLevel(const ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel & sanity_level)7690   static jbyte toJavaSanityLevel(
7691       const ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel &sanity_level) {
7692     switch (sanity_level) {
7693       case ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel::kSanityLevelNone:
7694         return 0x0;
7695       case ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel::
7696           kSanityLevelLooselyCompatible:
7697         return 0x1;
7698       case ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel::
7699           kSanityLevelExactMatch:
7700         return -0x01;
7701       default:
7702         return -0x01;  // undefined
7703     }
7704   }
7705 
7706   // Returns the equivalent C++ ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel enum for
7707   // the provided Java org.rocksdb.SanityLevel
toCppSanityLevel(jbyte sanity_level)7708   static ROCKSDB_NAMESPACE::ConfigOptions::SanityLevel toCppSanityLevel(
7709       jbyte sanity_level) {
7710     switch (sanity_level) {
7711       case 0x0:
7712         return ROCKSDB_NAMESPACE::ConfigOptions::kSanityLevelNone;
7713       case 0x1:
7714         return ROCKSDB_NAMESPACE::ConfigOptions::kSanityLevelLooselyCompatible;
7715       default:
7716         // undefined/default
7717         return ROCKSDB_NAMESPACE::ConfigOptions::kSanityLevelExactMatch;
7718     }
7719   }
7720 };
7721 
7722 // The portal class for org.rocksdb.AbstractListener.EnabledEventCallback
7723 class EnabledEventCallbackJni {
7724  public:
7725   // Returns the set of equivalent C++
7726   // rocksdb::EnabledEventCallbackJni::EnabledEventCallback enums for
7727   // the provided Java jenabled_event_callback_values
toCppEnabledEventCallbacks(jlong jenabled_event_callback_values)7728   static std::set<EnabledEventCallback> toCppEnabledEventCallbacks(
7729       jlong jenabled_event_callback_values) {
7730     std::set<EnabledEventCallback> enabled_event_callbacks;
7731     for (size_t i = 0; i < EnabledEventCallback::NUM_ENABLED_EVENT_CALLBACK;
7732          ++i) {
7733       if (((1ULL << i) & jenabled_event_callback_values) > 0) {
7734         enabled_event_callbacks.emplace(static_cast<EnabledEventCallback>(i));
7735       }
7736     }
7737     return enabled_event_callbacks;
7738   }
7739 };
7740 
7741 // The portal class for org.rocksdb.AbstractEventListener
7742 class AbstractEventListenerJni
7743     : public RocksDBNativeClass<
7744           const ROCKSDB_NAMESPACE::EventListenerJniCallback*,
7745           AbstractEventListenerJni> {
7746  public:
7747   /**
7748    * Get the Java Class org.rocksdb.AbstractEventListener
7749    *
7750    * @param env A pointer to the Java environment
7751    *
7752    * @return The Java Class or nullptr if one of the
7753    *     ClassFormatError, ClassCircularityError, NoClassDefFoundError,
7754    *     OutOfMemoryError or ExceptionInInitializerError exceptions is thrown
7755    */
getJClass(JNIEnv * env)7756   static jclass getJClass(JNIEnv* env) {
7757     return RocksDBNativeClass::getJClass(env,
7758                                          "org/rocksdb/AbstractEventListener");
7759   }
7760 
7761   /**
7762    * Get the Java Method: AbstractEventListener#onFlushCompletedProxy
7763    *
7764    * @param env A pointer to the Java environment
7765    *
7766    * @return The Java Method ID
7767    */
getOnFlushCompletedProxyMethodId(JNIEnv * env)7768   static jmethodID getOnFlushCompletedProxyMethodId(JNIEnv* env) {
7769     jclass jclazz = getJClass(env);
7770     assert(jclazz != nullptr);
7771     static jmethodID mid = env->GetMethodID(jclazz, "onFlushCompletedProxy",
7772                                             "(JLorg/rocksdb/FlushJobInfo;)V");
7773     assert(mid != nullptr);
7774     return mid;
7775   }
7776 
7777   /**
7778    * Get the Java Method: AbstractEventListener#onFlushBeginProxy
7779    *
7780    * @param env A pointer to the Java environment
7781    *
7782    * @return The Java Method ID
7783    */
getOnFlushBeginProxyMethodId(JNIEnv * env)7784   static jmethodID getOnFlushBeginProxyMethodId(JNIEnv* env) {
7785     jclass jclazz = getJClass(env);
7786     assert(jclazz != nullptr);
7787     static jmethodID mid = env->GetMethodID(jclazz, "onFlushBeginProxy",
7788                                             "(JLorg/rocksdb/FlushJobInfo;)V");
7789     assert(mid != nullptr);
7790     return mid;
7791   }
7792 
7793   /**
7794    * Get the Java Method: AbstractEventListener#onTableFileDeleted
7795    *
7796    * @param env A pointer to the Java environment
7797    *
7798    * @return The Java Method ID
7799    */
getOnTableFileDeletedMethodId(JNIEnv * env)7800   static jmethodID getOnTableFileDeletedMethodId(JNIEnv* env) {
7801     jclass jclazz = getJClass(env);
7802     assert(jclazz != nullptr);
7803     static jmethodID mid = env->GetMethodID(
7804         jclazz, "onTableFileDeleted", "(Lorg/rocksdb/TableFileDeletionInfo;)V");
7805     assert(mid != nullptr);
7806     return mid;
7807   }
7808 
7809   /**
7810    * Get the Java Method: AbstractEventListener#onCompactionBeginProxy
7811    *
7812    * @param env A pointer to the Java environment
7813    *
7814    * @return The Java Method ID
7815    */
getOnCompactionBeginProxyMethodId(JNIEnv * env)7816   static jmethodID getOnCompactionBeginProxyMethodId(JNIEnv* env) {
7817     jclass jclazz = getJClass(env);
7818     assert(jclazz != nullptr);
7819     static jmethodID mid =
7820         env->GetMethodID(jclazz, "onCompactionBeginProxy",
7821                          "(JLorg/rocksdb/CompactionJobInfo;)V");
7822     assert(mid != nullptr);
7823     return mid;
7824   }
7825 
7826   /**
7827    * Get the Java Method: AbstractEventListener#onCompactionCompletedProxy
7828    *
7829    * @param env A pointer to the Java environment
7830    *
7831    * @return The Java Method ID
7832    */
getOnCompactionCompletedProxyMethodId(JNIEnv * env)7833   static jmethodID getOnCompactionCompletedProxyMethodId(JNIEnv* env) {
7834     jclass jclazz = getJClass(env);
7835     assert(jclazz != nullptr);
7836     static jmethodID mid =
7837         env->GetMethodID(jclazz, "onCompactionCompletedProxy",
7838                          "(JLorg/rocksdb/CompactionJobInfo;)V");
7839     assert(mid != nullptr);
7840     return mid;
7841   }
7842 
7843   /**
7844    * Get the Java Method: AbstractEventListener#onTableFileCreated
7845    *
7846    * @param env A pointer to the Java environment
7847    *
7848    * @return The Java Method ID
7849    */
getOnTableFileCreatedMethodId(JNIEnv * env)7850   static jmethodID getOnTableFileCreatedMethodId(JNIEnv* env) {
7851     jclass jclazz = getJClass(env);
7852     assert(jclazz != nullptr);
7853     static jmethodID mid = env->GetMethodID(
7854         jclazz, "onTableFileCreated", "(Lorg/rocksdb/TableFileCreationInfo;)V");
7855     assert(mid != nullptr);
7856     return mid;
7857   }
7858 
7859   /**
7860    * Get the Java Method: AbstractEventListener#onTableFileCreationStarted
7861    *
7862    * @param env A pointer to the Java environment
7863    *
7864    * @return The Java Method ID
7865    */
getOnTableFileCreationStartedMethodId(JNIEnv * env)7866   static jmethodID getOnTableFileCreationStartedMethodId(JNIEnv* env) {
7867     jclass jclazz = getJClass(env);
7868     assert(jclazz != nullptr);
7869     static jmethodID mid =
7870         env->GetMethodID(jclazz, "onTableFileCreationStarted",
7871                          "(Lorg/rocksdb/TableFileCreationBriefInfo;)V");
7872     assert(mid != nullptr);
7873     return mid;
7874   }
7875 
7876   /**
7877    * Get the Java Method: AbstractEventListener#onMemTableSealed
7878    *
7879    * @param env A pointer to the Java environment
7880    *
7881    * @return The Java Method ID
7882    */
getOnMemTableSealedMethodId(JNIEnv * env)7883   static jmethodID getOnMemTableSealedMethodId(JNIEnv* env) {
7884     jclass jclazz = getJClass(env);
7885     assert(jclazz != nullptr);
7886     static jmethodID mid = env->GetMethodID(jclazz, "onMemTableSealed",
7887                                             "(Lorg/rocksdb/MemTableInfo;)V");
7888     assert(mid != nullptr);
7889     return mid;
7890   }
7891 
7892   /**
7893    * Get the Java Method:
7894    * AbstractEventListener#onColumnFamilyHandleDeletionStarted
7895    *
7896    * @param env A pointer to the Java environment
7897    *
7898    * @return The Java Method ID
7899    */
getOnColumnFamilyHandleDeletionStartedMethodId(JNIEnv * env)7900   static jmethodID getOnColumnFamilyHandleDeletionStartedMethodId(JNIEnv* env) {
7901     jclass jclazz = getJClass(env);
7902     assert(jclazz != nullptr);
7903     static jmethodID mid =
7904         env->GetMethodID(jclazz, "onColumnFamilyHandleDeletionStarted",
7905                          "(Lorg/rocksdb/ColumnFamilyHandle;)V");
7906     assert(mid != nullptr);
7907     return mid;
7908   }
7909 
7910   /**
7911    * Get the Java Method: AbstractEventListener#onExternalFileIngestedProxy
7912    *
7913    * @param env A pointer to the Java environment
7914    *
7915    * @return The Java Method ID
7916    */
getOnExternalFileIngestedProxyMethodId(JNIEnv * env)7917   static jmethodID getOnExternalFileIngestedProxyMethodId(JNIEnv* env) {
7918     jclass jclazz = getJClass(env);
7919     assert(jclazz != nullptr);
7920     static jmethodID mid =
7921         env->GetMethodID(jclazz, "onExternalFileIngestedProxy",
7922                          "(JLorg/rocksdb/ExternalFileIngestionInfo;)V");
7923     assert(mid != nullptr);
7924     return mid;
7925   }
7926 
7927   /**
7928    * Get the Java Method: AbstractEventListener#onBackgroundError
7929    *
7930    * @param env A pointer to the Java environment
7931    *
7932    * @return The Java Method ID
7933    */
getOnBackgroundErrorProxyMethodId(JNIEnv * env)7934   static jmethodID getOnBackgroundErrorProxyMethodId(JNIEnv* env) {
7935     jclass jclazz = getJClass(env);
7936     assert(jclazz != nullptr);
7937     static jmethodID mid = env->GetMethodID(jclazz, "onBackgroundErrorProxy",
7938                                             "(BLorg/rocksdb/Status;)V");
7939     assert(mid != nullptr);
7940     return mid;
7941   }
7942 
7943   /**
7944    * Get the Java Method: AbstractEventListener#onStallConditionsChanged
7945    *
7946    * @param env A pointer to the Java environment
7947    *
7948    * @return The Java Method ID
7949    */
getOnStallConditionsChangedMethodId(JNIEnv * env)7950   static jmethodID getOnStallConditionsChangedMethodId(JNIEnv* env) {
7951     jclass jclazz = getJClass(env);
7952     assert(jclazz != nullptr);
7953     static jmethodID mid = env->GetMethodID(jclazz, "onStallConditionsChanged",
7954                                             "(Lorg/rocksdb/WriteStallInfo;)V");
7955     assert(mid != nullptr);
7956     return mid;
7957   }
7958 
7959   /**
7960    * Get the Java Method: AbstractEventListener#onFileReadFinish
7961    *
7962    * @param env A pointer to the Java environment
7963    *
7964    * @return The Java Method ID
7965    */
getOnFileReadFinishMethodId(JNIEnv * env)7966   static jmethodID getOnFileReadFinishMethodId(JNIEnv* env) {
7967     jclass jclazz = getJClass(env);
7968     assert(jclazz != nullptr);
7969     static jmethodID mid = env->GetMethodID(
7970         jclazz, "onFileReadFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
7971     assert(mid != nullptr);
7972     return mid;
7973   }
7974 
7975   /**
7976    * Get the Java Method: AbstractEventListener#onFileWriteFinish
7977    *
7978    * @param env A pointer to the Java environment
7979    *
7980    * @return The Java Method ID
7981    */
getOnFileWriteFinishMethodId(JNIEnv * env)7982   static jmethodID getOnFileWriteFinishMethodId(JNIEnv* env) {
7983     jclass jclazz = getJClass(env);
7984     assert(jclazz != nullptr);
7985     static jmethodID mid = env->GetMethodID(
7986         jclazz, "onFileWriteFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
7987     assert(mid != nullptr);
7988     return mid;
7989   }
7990 
7991   /**
7992    * Get the Java Method: AbstractEventListener#onFileFlushFinish
7993    *
7994    * @param env A pointer to the Java environment
7995    *
7996    * @return The Java Method ID
7997    */
getOnFileFlushFinishMethodId(JNIEnv * env)7998   static jmethodID getOnFileFlushFinishMethodId(JNIEnv* env) {
7999     jclass jclazz = getJClass(env);
8000     assert(jclazz != nullptr);
8001     static jmethodID mid = env->GetMethodID(
8002         jclazz, "onFileFlushFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
8003     assert(mid != nullptr);
8004     return mid;
8005   }
8006 
8007   /**
8008    * Get the Java Method: AbstractEventListener#onFileSyncFinish
8009    *
8010    * @param env A pointer to the Java environment
8011    *
8012    * @return The Java Method ID
8013    */
getOnFileSyncFinishMethodId(JNIEnv * env)8014   static jmethodID getOnFileSyncFinishMethodId(JNIEnv* env) {
8015     jclass jclazz = getJClass(env);
8016     assert(jclazz != nullptr);
8017     static jmethodID mid = env->GetMethodID(
8018         jclazz, "onFileSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
8019     assert(mid != nullptr);
8020     return mid;
8021   }
8022 
8023   /**
8024    * Get the Java Method: AbstractEventListener#onFileRangeSyncFinish
8025    *
8026    * @param env A pointer to the Java environment
8027    *
8028    * @return The Java Method ID
8029    */
getOnFileRangeSyncFinishMethodId(JNIEnv * env)8030   static jmethodID getOnFileRangeSyncFinishMethodId(JNIEnv* env) {
8031     jclass jclazz = getJClass(env);
8032     assert(jclazz != nullptr);
8033     static jmethodID mid = env->GetMethodID(
8034         jclazz, "onFileRangeSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
8035     assert(mid != nullptr);
8036     return mid;
8037   }
8038 
8039   /**
8040    * Get the Java Method: AbstractEventListener#onFileTruncateFinish
8041    *
8042    * @param env A pointer to the Java environment
8043    *
8044    * @return The Java Method ID
8045    */
getOnFileTruncateFinishMethodId(JNIEnv * env)8046   static jmethodID getOnFileTruncateFinishMethodId(JNIEnv* env) {
8047     jclass jclazz = getJClass(env);
8048     assert(jclazz != nullptr);
8049     static jmethodID mid = env->GetMethodID(
8050         jclazz, "onFileTruncateFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
8051     assert(mid != nullptr);
8052     return mid;
8053   }
8054 
8055   /**
8056    * Get the Java Method: AbstractEventListener#onFileCloseFinish
8057    *
8058    * @param env A pointer to the Java environment
8059    *
8060    * @return The Java Method ID
8061    */
getOnFileCloseFinishMethodId(JNIEnv * env)8062   static jmethodID getOnFileCloseFinishMethodId(JNIEnv* env) {
8063     jclass jclazz = getJClass(env);
8064     assert(jclazz != nullptr);
8065     static jmethodID mid = env->GetMethodID(
8066         jclazz, "onFileCloseFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
8067     assert(mid != nullptr);
8068     return mid;
8069   }
8070 
8071   /**
8072    * Get the Java Method: AbstractEventListener#shouldBeNotifiedOnFileIO
8073    *
8074    * @param env A pointer to the Java environment
8075    *
8076    * @return The Java Method ID
8077    */
getShouldBeNotifiedOnFileIOMethodId(JNIEnv * env)8078   static jmethodID getShouldBeNotifiedOnFileIOMethodId(JNIEnv* env) {
8079     jclass jclazz = getJClass(env);
8080     assert(jclazz != nullptr);
8081     static jmethodID mid =
8082         env->GetMethodID(jclazz, "shouldBeNotifiedOnFileIO", "()Z");
8083     assert(mid != nullptr);
8084     return mid;
8085   }
8086 
8087   /**
8088    * Get the Java Method: AbstractEventListener#onErrorRecoveryBeginProxy
8089    *
8090    * @param env A pointer to the Java environment
8091    *
8092    * @return The Java Method ID
8093    */
getOnErrorRecoveryBeginProxyMethodId(JNIEnv * env)8094   static jmethodID getOnErrorRecoveryBeginProxyMethodId(JNIEnv* env) {
8095     jclass jclazz = getJClass(env);
8096     assert(jclazz != nullptr);
8097     static jmethodID mid = env->GetMethodID(jclazz, "onErrorRecoveryBeginProxy",
8098                                             "(BLorg/rocksdb/Status;)Z");
8099     assert(mid != nullptr);
8100     return mid;
8101   }
8102 
8103   /**
8104    * Get the Java Method: AbstractEventListener#onErrorRecoveryCompleted
8105    *
8106    * @param env A pointer to the Java environment
8107    *
8108    * @return The Java Method ID
8109    */
getOnErrorRecoveryCompletedMethodId(JNIEnv * env)8110   static jmethodID getOnErrorRecoveryCompletedMethodId(JNIEnv* env) {
8111     jclass jclazz = getJClass(env);
8112     assert(jclazz != nullptr);
8113     static jmethodID mid = env->GetMethodID(jclazz, "onErrorRecoveryCompleted",
8114                                             "(Lorg/rocksdb/Status;)V");
8115     assert(mid != nullptr);
8116     return mid;
8117   }
8118 };
8119 
8120 class FlushJobInfoJni : public JavaClass {
8121  public:
8122   /**
8123    * Create a new Java org.rocksdb.FlushJobInfo object.
8124    *
8125    * @param env A pointer to the Java environment
8126    * @param flush_job_info A Cpp flush job info object
8127    *
8128    * @return A reference to a Java org.rocksdb.FlushJobInfo object, or
8129    * nullptr if an an exception occurs
8130    */
fromCppFlushJobInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::FlushJobInfo * flush_job_info)8131   static jobject fromCppFlushJobInfo(
8132       JNIEnv* env, const ROCKSDB_NAMESPACE::FlushJobInfo* flush_job_info) {
8133     jclass jclazz = getJClass(env);
8134     if (jclazz == nullptr) {
8135       // exception occurred accessing class
8136       return nullptr;
8137     }
8138     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8139     assert(ctor != nullptr);
8140     jstring jcf_name = JniUtil::toJavaString(env, &flush_job_info->cf_name);
8141     if (env->ExceptionCheck()) {
8142       return nullptr;
8143     }
8144     jstring jfile_path = JniUtil::toJavaString(env, &flush_job_info->file_path);
8145     if (env->ExceptionCheck()) {
8146       env->DeleteLocalRef(jfile_path);
8147       return nullptr;
8148     }
8149     jobject jtable_properties = TablePropertiesJni::fromCppTableProperties(
8150         env, flush_job_info->table_properties);
8151     if (jtable_properties == nullptr) {
8152       env->DeleteLocalRef(jcf_name);
8153       env->DeleteLocalRef(jfile_path);
8154       return nullptr;
8155     }
8156     return env->NewObject(
8157         jclazz, ctor, static_cast<jlong>(flush_job_info->cf_id), jcf_name,
8158         jfile_path, static_cast<jlong>(flush_job_info->thread_id),
8159         static_cast<jint>(flush_job_info->job_id),
8160         static_cast<jboolean>(flush_job_info->triggered_writes_slowdown),
8161         static_cast<jboolean>(flush_job_info->triggered_writes_stop),
8162         static_cast<jlong>(flush_job_info->smallest_seqno),
8163         static_cast<jlong>(flush_job_info->largest_seqno), jtable_properties,
8164         static_cast<jbyte>(flush_job_info->flush_reason));
8165   }
8166 
getJClass(JNIEnv * env)8167   static jclass getJClass(JNIEnv* env) {
8168     return JavaClass::getJClass(env, "org/rocksdb/FlushJobInfo");
8169   }
8170 
getConstructorMethodId(JNIEnv * env,jclass clazz)8171   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8172     return env->GetMethodID(clazz, "<init>",
8173                             "(JLjava/lang/String;Ljava/lang/String;JIZZJJLorg/"
8174                             "rocksdb/TableProperties;B)V");
8175   }
8176 };
8177 
8178 class TableFileDeletionInfoJni : public JavaClass {
8179  public:
8180   /**
8181    * Create a new Java org.rocksdb.TableFileDeletionInfo object.
8182    *
8183    * @param env A pointer to the Java environment
8184    * @param file_del_info A Cpp table file deletion info object
8185    *
8186    * @return A reference to a Java org.rocksdb.TableFileDeletionInfo object, or
8187    * nullptr if an an exception occurs
8188    */
fromCppTableFileDeletionInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::TableFileDeletionInfo * file_del_info)8189   static jobject fromCppTableFileDeletionInfo(
8190       JNIEnv* env,
8191       const ROCKSDB_NAMESPACE::TableFileDeletionInfo* file_del_info) {
8192     jclass jclazz = getJClass(env);
8193     if (jclazz == nullptr) {
8194       // exception occurred accessing class
8195       return nullptr;
8196     }
8197     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8198     assert(ctor != nullptr);
8199     jstring jdb_name = JniUtil::toJavaString(env, &file_del_info->db_name);
8200     if (env->ExceptionCheck()) {
8201       return nullptr;
8202     }
8203     jobject jstatus = StatusJni::construct(env, file_del_info->status);
8204     if (jstatus == nullptr) {
8205       env->DeleteLocalRef(jdb_name);
8206       return nullptr;
8207     }
8208     return env->NewObject(jclazz, ctor, jdb_name,
8209                           JniUtil::toJavaString(env, &file_del_info->file_path),
8210                           static_cast<jint>(file_del_info->job_id), jstatus);
8211   }
8212 
getJClass(JNIEnv * env)8213   static jclass getJClass(JNIEnv* env) {
8214     return JavaClass::getJClass(env, "org/rocksdb/TableFileDeletionInfo");
8215   }
8216 
getConstructorMethodId(JNIEnv * env,jclass clazz)8217   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8218     return env->GetMethodID(
8219         clazz, "<init>",
8220         "(Ljava/lang/String;Ljava/lang/String;ILorg/rocksdb/Status;)V");
8221   }
8222 };
8223 
8224 class CompactionJobInfoJni : public JavaClass {
8225  public:
fromCppCompactionJobInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::CompactionJobInfo * compaction_job_info)8226   static jobject fromCppCompactionJobInfo(
8227       JNIEnv* env,
8228       const ROCKSDB_NAMESPACE::CompactionJobInfo* compaction_job_info) {
8229     jclass jclazz = getJClass(env);
8230     assert(jclazz != nullptr);
8231     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8232     assert(ctor != nullptr);
8233     return env->NewObject(jclazz, ctor,
8234                           reinterpret_cast<jlong>(compaction_job_info));
8235   }
8236 
getJClass(JNIEnv * env)8237   static jclass getJClass(JNIEnv* env) {
8238     return JavaClass::getJClass(env, "org/rocksdb/CompactionJobInfo");
8239   }
8240 
getConstructorMethodId(JNIEnv * env,jclass clazz)8241   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8242     return env->GetMethodID(clazz, "<init>", "(J)V");
8243   }
8244 };
8245 
8246 class TableFileCreationInfoJni : public JavaClass {
8247  public:
fromCppTableFileCreationInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::TableFileCreationInfo * info)8248   static jobject fromCppTableFileCreationInfo(
8249       JNIEnv* env, const ROCKSDB_NAMESPACE::TableFileCreationInfo* info) {
8250     jclass jclazz = getJClass(env);
8251     assert(jclazz != nullptr);
8252     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8253     assert(ctor != nullptr);
8254     jstring jdb_name = JniUtil::toJavaString(env, &info->db_name);
8255     if (env->ExceptionCheck()) {
8256       return nullptr;
8257     }
8258     jstring jcf_name = JniUtil::toJavaString(env, &info->cf_name);
8259     if (env->ExceptionCheck()) {
8260       env->DeleteLocalRef(jdb_name);
8261       return nullptr;
8262     }
8263     jstring jfile_path = JniUtil::toJavaString(env, &info->file_path);
8264     if (env->ExceptionCheck()) {
8265       env->DeleteLocalRef(jdb_name);
8266       env->DeleteLocalRef(jcf_name);
8267       return nullptr;
8268     }
8269     jobject jtable_properties =
8270         TablePropertiesJni::fromCppTableProperties(env, info->table_properties);
8271     if (jtable_properties == nullptr) {
8272       env->DeleteLocalRef(jdb_name);
8273       env->DeleteLocalRef(jcf_name);
8274       return nullptr;
8275     }
8276     jobject jstatus = StatusJni::construct(env, info->status);
8277     if (jstatus == nullptr) {
8278       env->DeleteLocalRef(jdb_name);
8279       env->DeleteLocalRef(jcf_name);
8280       env->DeleteLocalRef(jtable_properties);
8281       return nullptr;
8282     }
8283     return env->NewObject(jclazz, ctor, static_cast<jlong>(info->file_size),
8284                           jtable_properties, jstatus, jdb_name, jcf_name,
8285                           jfile_path, static_cast<jint>(info->job_id),
8286                           static_cast<jbyte>(info->reason));
8287   }
8288 
getJClass(JNIEnv * env)8289   static jclass getJClass(JNIEnv* env) {
8290     return JavaClass::getJClass(env, "org/rocksdb/TableFileCreationInfo");
8291   }
8292 
getConstructorMethodId(JNIEnv * env,jclass clazz)8293   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8294     return env->GetMethodID(
8295         clazz, "<init>",
8296         "(JLorg/rocksdb/TableProperties;Lorg/rocksdb/Status;Ljava/lang/"
8297         "String;Ljava/lang/String;Ljava/lang/String;IB)V");
8298   }
8299 };
8300 
8301 class TableFileCreationBriefInfoJni : public JavaClass {
8302  public:
fromCppTableFileCreationBriefInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::TableFileCreationBriefInfo * info)8303   static jobject fromCppTableFileCreationBriefInfo(
8304       JNIEnv* env, const ROCKSDB_NAMESPACE::TableFileCreationBriefInfo* info) {
8305     jclass jclazz = getJClass(env);
8306     assert(jclazz != nullptr);
8307     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8308     assert(ctor != nullptr);
8309     jstring jdb_name = JniUtil::toJavaString(env, &info->db_name);
8310     if (env->ExceptionCheck()) {
8311       return nullptr;
8312     }
8313     jstring jcf_name = JniUtil::toJavaString(env, &info->cf_name);
8314     if (env->ExceptionCheck()) {
8315       env->DeleteLocalRef(jdb_name);
8316       return nullptr;
8317     }
8318     jstring jfile_path = JniUtil::toJavaString(env, &info->file_path);
8319     if (env->ExceptionCheck()) {
8320       env->DeleteLocalRef(jdb_name);
8321       env->DeleteLocalRef(jcf_name);
8322       return nullptr;
8323     }
8324     return env->NewObject(jclazz, ctor, jdb_name, jcf_name, jfile_path,
8325                           static_cast<jint>(info->job_id),
8326                           static_cast<jbyte>(info->reason));
8327   }
8328 
getJClass(JNIEnv * env)8329   static jclass getJClass(JNIEnv* env) {
8330     return JavaClass::getJClass(env, "org/rocksdb/TableFileCreationBriefInfo");
8331   }
8332 
getConstructorMethodId(JNIEnv * env,jclass clazz)8333   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8334     return env->GetMethodID(
8335         clazz, "<init>",
8336         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IB)V");
8337   }
8338 };
8339 
8340 class MemTableInfoJni : public JavaClass {
8341  public:
fromCppMemTableInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::MemTableInfo * info)8342   static jobject fromCppMemTableInfo(
8343       JNIEnv* env, const ROCKSDB_NAMESPACE::MemTableInfo* info) {
8344     jclass jclazz = getJClass(env);
8345     assert(jclazz != nullptr);
8346     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8347     assert(ctor != nullptr);
8348     jstring jcf_name = JniUtil::toJavaString(env, &info->cf_name);
8349     if (env->ExceptionCheck()) {
8350       return nullptr;
8351     }
8352     return env->NewObject(jclazz, ctor, jcf_name,
8353                           static_cast<jlong>(info->first_seqno),
8354                           static_cast<jlong>(info->earliest_seqno),
8355                           static_cast<jlong>(info->num_entries),
8356                           static_cast<jlong>(info->num_deletes));
8357   }
8358 
getJClass(JNIEnv * env)8359   static jclass getJClass(JNIEnv* env) {
8360     return JavaClass::getJClass(env, "org/rocksdb/MemTableInfo");
8361   }
8362 
getConstructorMethodId(JNIEnv * env,jclass clazz)8363   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8364     return env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;JJJJ)V");
8365   }
8366 };
8367 
8368 class ExternalFileIngestionInfoJni : public JavaClass {
8369  public:
fromCppExternalFileIngestionInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::ExternalFileIngestionInfo * info)8370   static jobject fromCppExternalFileIngestionInfo(
8371       JNIEnv* env, const ROCKSDB_NAMESPACE::ExternalFileIngestionInfo* info) {
8372     jclass jclazz = getJClass(env);
8373     assert(jclazz != nullptr);
8374     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8375     assert(ctor != nullptr);
8376     jstring jcf_name = JniUtil::toJavaString(env, &info->cf_name);
8377     if (env->ExceptionCheck()) {
8378       return nullptr;
8379     }
8380     jstring jexternal_file_path =
8381         JniUtil::toJavaString(env, &info->external_file_path);
8382     if (env->ExceptionCheck()) {
8383       env->DeleteLocalRef(jcf_name);
8384       return nullptr;
8385     }
8386     jstring jinternal_file_path =
8387         JniUtil::toJavaString(env, &info->internal_file_path);
8388     if (env->ExceptionCheck()) {
8389       env->DeleteLocalRef(jcf_name);
8390       env->DeleteLocalRef(jexternal_file_path);
8391       return nullptr;
8392     }
8393     jobject jtable_properties =
8394         TablePropertiesJni::fromCppTableProperties(env, info->table_properties);
8395     if (jtable_properties == nullptr) {
8396       env->DeleteLocalRef(jcf_name);
8397       env->DeleteLocalRef(jexternal_file_path);
8398       env->DeleteLocalRef(jinternal_file_path);
8399       return nullptr;
8400     }
8401     return env->NewObject(
8402         jclazz, ctor, jcf_name, jexternal_file_path, jinternal_file_path,
8403         static_cast<jlong>(info->global_seqno), jtable_properties);
8404   }
8405 
getJClass(JNIEnv * env)8406   static jclass getJClass(JNIEnv* env) {
8407     return JavaClass::getJClass(env, "org/rocksdb/ExternalFileIngestionInfo");
8408   }
8409 
getConstructorMethodId(JNIEnv * env,jclass clazz)8410   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8411     return env->GetMethodID(clazz, "<init>",
8412                             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
8413                             "String;JLorg/rocksdb/TableProperties;)V");
8414   }
8415 };
8416 
8417 class WriteStallInfoJni : public JavaClass {
8418  public:
fromCppWriteStallInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::WriteStallInfo * info)8419   static jobject fromCppWriteStallInfo(
8420       JNIEnv* env, const ROCKSDB_NAMESPACE::WriteStallInfo* info) {
8421     jclass jclazz = getJClass(env);
8422     assert(jclazz != nullptr);
8423     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8424     assert(ctor != nullptr);
8425     jstring jcf_name = JniUtil::toJavaString(env, &info->cf_name);
8426     if (env->ExceptionCheck()) {
8427       return nullptr;
8428     }
8429     return env->NewObject(jclazz, ctor, jcf_name,
8430                           static_cast<jbyte>(info->condition.cur),
8431                           static_cast<jbyte>(info->condition.prev));
8432   }
8433 
getJClass(JNIEnv * env)8434   static jclass getJClass(JNIEnv* env) {
8435     return JavaClass::getJClass(env, "org/rocksdb/WriteStallInfo");
8436   }
8437 
getConstructorMethodId(JNIEnv * env,jclass clazz)8438   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8439     return env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;BB)V");
8440   }
8441 };
8442 
8443 class FileOperationInfoJni : public JavaClass {
8444  public:
fromCppFileOperationInfo(JNIEnv * env,const ROCKSDB_NAMESPACE::FileOperationInfo * info)8445   static jobject fromCppFileOperationInfo(
8446       JNIEnv* env, const ROCKSDB_NAMESPACE::FileOperationInfo* info) {
8447     jclass jclazz = getJClass(env);
8448     assert(jclazz != nullptr);
8449     static jmethodID ctor = getConstructorMethodId(env, jclazz);
8450     assert(ctor != nullptr);
8451     jstring jpath = JniUtil::toJavaString(env, &info->path);
8452     if (env->ExceptionCheck()) {
8453       return nullptr;
8454     }
8455     jobject jstatus = StatusJni::construct(env, info->status);
8456     if (jstatus == nullptr) {
8457       env->DeleteLocalRef(jpath);
8458       return nullptr;
8459     }
8460     return env->NewObject(
8461         jclazz, ctor, jpath, static_cast<jlong>(info->offset),
8462         static_cast<jlong>(info->length),
8463         static_cast<jlong>(info->start_ts.time_since_epoch().count()),
8464         static_cast<jlong>(info->duration.count()), jstatus);
8465   }
8466 
getJClass(JNIEnv * env)8467   static jclass getJClass(JNIEnv* env) {
8468     return JavaClass::getJClass(env, "org/rocksdb/FileOperationInfo");
8469   }
8470 
getConstructorMethodId(JNIEnv * env,jclass clazz)8471   static jmethodID getConstructorMethodId(JNIEnv* env, jclass clazz) {
8472     return env->GetMethodID(clazz, "<init>",
8473                             "(Ljava/lang/String;JJJJLorg/rocksdb/Status;)V");
8474   }
8475 };
8476 }  // namespace ROCKSDB_NAMESPACE
8477 #endif  // JAVA_ROCKSJNI_PORTAL_H_
8478