1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 // This file implements the "bridge" between Java and C++ and enables
7 // calling c++ ROCKSDB_NAMESPACE::Statistics methods from Java side.
8 
9 #include <jni.h>
10 #include <memory>
11 #include <set>
12 
13 #include "include/org_rocksdb_Statistics.h"
14 #include "rocksdb/statistics.h"
15 #include "rocksjni/portal.h"
16 #include "rocksjni/statisticsjni.h"
17 
18 /*
19  * Class:     org_rocksdb_Statistics
20  * Method:    newStatistics
21  * Signature: ()J
22  */
Java_org_rocksdb_Statistics_newStatistics__(JNIEnv * env,jclass jcls)23 jlong Java_org_rocksdb_Statistics_newStatistics__(
24     JNIEnv* env, jclass jcls) {
25   return Java_org_rocksdb_Statistics_newStatistics___3BJ(
26       env, jcls, nullptr, 0);
27 }
28 
29 /*
30  * Class:     org_rocksdb_Statistics
31  * Method:    newStatistics
32  * Signature: (J)J
33  */
Java_org_rocksdb_Statistics_newStatistics__J(JNIEnv * env,jclass jcls,jlong jother_statistics_handle)34 jlong Java_org_rocksdb_Statistics_newStatistics__J(
35     JNIEnv* env, jclass jcls, jlong jother_statistics_handle) {
36   return Java_org_rocksdb_Statistics_newStatistics___3BJ(
37       env, jcls, nullptr, jother_statistics_handle);
38 }
39 
40 /*
41  * Class:     org_rocksdb_Statistics
42  * Method:    newStatistics
43  * Signature: ([B)J
44  */
Java_org_rocksdb_Statistics_newStatistics___3B(JNIEnv * env,jclass jcls,jbyteArray jhistograms)45 jlong Java_org_rocksdb_Statistics_newStatistics___3B(
46     JNIEnv* env, jclass jcls, jbyteArray jhistograms) {
47   return Java_org_rocksdb_Statistics_newStatistics___3BJ(
48       env, jcls, jhistograms, 0);
49 }
50 
51 /*
52  * Class:     org_rocksdb_Statistics
53  * Method:    newStatistics
54  * Signature: ([BJ)J
55  */
Java_org_rocksdb_Statistics_newStatistics___3BJ(JNIEnv * env,jclass,jbyteArray jhistograms,jlong jother_statistics_handle)56 jlong Java_org_rocksdb_Statistics_newStatistics___3BJ(
57     JNIEnv* env, jclass, jbyteArray jhistograms, jlong jother_statistics_handle) {
58   std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>* pSptr_other_statistics =
59       nullptr;
60   if (jother_statistics_handle > 0) {
61     pSptr_other_statistics =
62         reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
63             jother_statistics_handle);
64   }
65 
66   std::set<uint32_t> histograms;
67   if (jhistograms != nullptr) {
68     const jsize len = env->GetArrayLength(jhistograms);
69     if (len > 0) {
70       jbyte* jhistogram = env->GetByteArrayElements(jhistograms, nullptr);
71       if (jhistogram == nullptr) {
72         // exception thrown: OutOfMemoryError
73         return 0;
74       }
75 
76       for (jsize i = 0; i < len; i++) {
77         const ROCKSDB_NAMESPACE::Histograms histogram =
78             ROCKSDB_NAMESPACE::HistogramTypeJni::toCppHistograms(jhistogram[i]);
79         histograms.emplace(histogram);
80       }
81 
82       env->ReleaseByteArrayElements(jhistograms, jhistogram, JNI_ABORT);
83     }
84   }
85 
86   std::shared_ptr<ROCKSDB_NAMESPACE::Statistics> sptr_other_statistics =
87       nullptr;
88   if (pSptr_other_statistics != nullptr) {
89     sptr_other_statistics = *pSptr_other_statistics;
90   }
91 
92   auto* pSptr_statistics =
93       new std::shared_ptr<ROCKSDB_NAMESPACE::StatisticsJni>(
94           new ROCKSDB_NAMESPACE::StatisticsJni(sptr_other_statistics,
95                                                histograms));
96 
97   return reinterpret_cast<jlong>(pSptr_statistics);
98 }
99 
100 /*
101  * Class:     org_rocksdb_Statistics
102  * Method:    disposeInternal
103  * Signature: (J)V
104  */
Java_org_rocksdb_Statistics_disposeInternal(JNIEnv *,jobject,jlong jhandle)105 void Java_org_rocksdb_Statistics_disposeInternal(
106     JNIEnv*, jobject, jlong jhandle) {
107   if (jhandle > 0) {
108     auto* pSptr_statistics =
109         reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
110             jhandle);
111     delete pSptr_statistics;
112   }
113 }
114 
115 /*
116  * Class:     org_rocksdb_Statistics
117  * Method:    statsLevel
118  * Signature: (J)B
119  */
Java_org_rocksdb_Statistics_statsLevel(JNIEnv *,jobject,jlong jhandle)120 jbyte Java_org_rocksdb_Statistics_statsLevel(
121     JNIEnv*, jobject, jlong jhandle) {
122   auto* pSptr_statistics =
123       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
124           jhandle);
125   assert(pSptr_statistics != nullptr);
126   return ROCKSDB_NAMESPACE::StatsLevelJni::toJavaStatsLevel(
127       pSptr_statistics->get()->get_stats_level());
128 }
129 
130 /*
131  * Class:     org_rocksdb_Statistics
132  * Method:    setStatsLevel
133  * Signature: (JB)V
134  */
Java_org_rocksdb_Statistics_setStatsLevel(JNIEnv *,jobject,jlong jhandle,jbyte jstats_level)135 void Java_org_rocksdb_Statistics_setStatsLevel(
136     JNIEnv*, jobject, jlong jhandle, jbyte jstats_level) {
137   auto* pSptr_statistics =
138       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
139           jhandle);
140   assert(pSptr_statistics != nullptr);
141   auto stats_level =
142       ROCKSDB_NAMESPACE::StatsLevelJni::toCppStatsLevel(jstats_level);
143   pSptr_statistics->get()->set_stats_level(stats_level);
144 }
145 
146 /*
147  * Class:     org_rocksdb_Statistics
148  * Method:    getTickerCount
149  * Signature: (JB)J
150  */
Java_org_rocksdb_Statistics_getTickerCount(JNIEnv *,jobject,jlong jhandle,jbyte jticker_type)151 jlong Java_org_rocksdb_Statistics_getTickerCount(
152     JNIEnv*, jobject, jlong jhandle, jbyte jticker_type) {
153   auto* pSptr_statistics =
154       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
155           jhandle);
156   assert(pSptr_statistics != nullptr);
157   auto ticker = ROCKSDB_NAMESPACE::TickerTypeJni::toCppTickers(jticker_type);
158   uint64_t count = pSptr_statistics->get()->getTickerCount(ticker);
159   return static_cast<jlong>(count);
160 }
161 
162 /*
163  * Class:     org_rocksdb_Statistics
164  * Method:    getAndResetTickerCount
165  * Signature: (JB)J
166  */
Java_org_rocksdb_Statistics_getAndResetTickerCount(JNIEnv *,jobject,jlong jhandle,jbyte jticker_type)167 jlong Java_org_rocksdb_Statistics_getAndResetTickerCount(
168     JNIEnv*, jobject, jlong jhandle, jbyte jticker_type) {
169   auto* pSptr_statistics =
170       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
171           jhandle);
172   assert(pSptr_statistics != nullptr);
173   auto ticker = ROCKSDB_NAMESPACE::TickerTypeJni::toCppTickers(jticker_type);
174   return pSptr_statistics->get()->getAndResetTickerCount(ticker);
175 }
176 
177 /*
178  * Class:     org_rocksdb_Statistics
179  * Method:    getHistogramData
180  * Signature: (JB)Lorg/rocksdb/HistogramData;
181  */
Java_org_rocksdb_Statistics_getHistogramData(JNIEnv * env,jobject,jlong jhandle,jbyte jhistogram_type)182 jobject Java_org_rocksdb_Statistics_getHistogramData(
183     JNIEnv* env, jobject, jlong jhandle, jbyte jhistogram_type) {
184   auto* pSptr_statistics =
185       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
186           jhandle);
187   assert(pSptr_statistics != nullptr);
188 
189   // TODO(AR) perhaps better to construct a Java Object Wrapper that
190   //    uses ptr to C++ `new HistogramData`
191   ROCKSDB_NAMESPACE::HistogramData data;
192 
193   auto histogram =
194       ROCKSDB_NAMESPACE::HistogramTypeJni::toCppHistograms(jhistogram_type);
195   pSptr_statistics->get()->histogramData(
196       static_cast<ROCKSDB_NAMESPACE::Histograms>(histogram), &data);
197 
198   jclass jclazz = ROCKSDB_NAMESPACE::HistogramDataJni::getJClass(env);
199   if (jclazz == nullptr) {
200     // exception occurred accessing class
201     return nullptr;
202   }
203 
204   jmethodID mid =
205       ROCKSDB_NAMESPACE::HistogramDataJni::getConstructorMethodId(env);
206   if (mid == nullptr) {
207     // exception occurred accessing method
208     return nullptr;
209   }
210 
211   return env->NewObject(jclazz, mid, data.median, data.percentile95,
212                         data.percentile99, data.average,
213                         data.standard_deviation, data.max, data.count,
214                         data.sum, data.min);
215 }
216 
217 /*
218  * Class:     org_rocksdb_Statistics
219  * Method:    getHistogramString
220  * Signature: (JB)Ljava/lang/String;
221  */
Java_org_rocksdb_Statistics_getHistogramString(JNIEnv * env,jobject,jlong jhandle,jbyte jhistogram_type)222 jstring Java_org_rocksdb_Statistics_getHistogramString(
223     JNIEnv* env, jobject, jlong jhandle, jbyte jhistogram_type) {
224   auto* pSptr_statistics =
225       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
226           jhandle);
227   assert(pSptr_statistics != nullptr);
228   auto histogram =
229       ROCKSDB_NAMESPACE::HistogramTypeJni::toCppHistograms(jhistogram_type);
230   auto str = pSptr_statistics->get()->getHistogramString(histogram);
231   return env->NewStringUTF(str.c_str());
232 }
233 
234 /*
235  * Class:     org_rocksdb_Statistics
236  * Method:    reset
237  * Signature: (J)V
238  */
Java_org_rocksdb_Statistics_reset(JNIEnv * env,jobject,jlong jhandle)239 void Java_org_rocksdb_Statistics_reset(
240     JNIEnv* env, jobject, jlong jhandle) {
241   auto* pSptr_statistics =
242       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
243           jhandle);
244   assert(pSptr_statistics != nullptr);
245   ROCKSDB_NAMESPACE::Status s = pSptr_statistics->get()->Reset();
246   if (!s.ok()) {
247     ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
248   }
249 }
250 
251 /*
252  * Class:     org_rocksdb_Statistics
253  * Method:    toString
254  * Signature: (J)Ljava/lang/String;
255  */
Java_org_rocksdb_Statistics_toString(JNIEnv * env,jobject,jlong jhandle)256 jstring Java_org_rocksdb_Statistics_toString(
257     JNIEnv* env, jobject, jlong jhandle) {
258   auto* pSptr_statistics =
259       reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Statistics>*>(
260           jhandle);
261   assert(pSptr_statistics != nullptr);
262   auto str = pSptr_statistics->get()->ToString();
263   return env->NewStringUTF(str.c_str());
264 }
265