]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / rocksdb / java / rocksjni / writebatchhandlerjnicallback.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
5 //
6 // This file implements the callback "bridge" between Java and C++ for
7 // rocksdb::Comparator.
8
9 #include "rocksjni/writebatchhandlerjnicallback.h"
10 #include "rocksjni/portal.h"
11
12 namespace rocksdb {
13 WriteBatchHandlerJniCallback::WriteBatchHandlerJniCallback(
14 JNIEnv* env, jobject jWriteBatchHandler)
15 : m_env(env) {
16
17 // Note: we want to access the Java WriteBatchHandler instance
18 // across multiple method calls, so we create a global ref
19 assert(jWriteBatchHandler != nullptr);
20 m_jWriteBatchHandler = env->NewGlobalRef(jWriteBatchHandler);
21 if(m_jWriteBatchHandler == nullptr) {
22 // exception thrown: OutOfMemoryError
23 return;
24 }
25
26 m_jPutMethodId = WriteBatchHandlerJni::getPutMethodId(env);
27 if(m_jPutMethodId == nullptr) {
28 // exception thrown
29 return;
30 }
31
32 m_jMergeMethodId = WriteBatchHandlerJni::getMergeMethodId(env);
33 if(m_jMergeMethodId == nullptr) {
34 // exception thrown
35 return;
36 }
37
38 m_jDeleteMethodId = WriteBatchHandlerJni::getDeleteMethodId(env);
39 if(m_jDeleteMethodId == nullptr) {
40 // exception thrown
41 return;
42 }
43
44 m_jDeleteRangeMethodId = WriteBatchHandlerJni::getDeleteRangeMethodId(env);
45 if (m_jDeleteRangeMethodId == nullptr) {
46 // exception thrown
47 return;
48 }
49
50 m_jLogDataMethodId = WriteBatchHandlerJni::getLogDataMethodId(env);
51 if(m_jLogDataMethodId == nullptr) {
52 // exception thrown
53 return;
54 }
55
56 m_jContinueMethodId = WriteBatchHandlerJni::getContinueMethodId(env);
57 if(m_jContinueMethodId == nullptr) {
58 // exception thrown
59 return;
60 }
61 }
62
63 void WriteBatchHandlerJniCallback::Put(const Slice& key, const Slice& value) {
64 const jbyteArray j_key = sliceToJArray(key);
65 if(j_key == nullptr) {
66 // exception thrown
67 if(m_env->ExceptionCheck()) {
68 m_env->ExceptionDescribe();
69 }
70 return;
71 }
72
73 const jbyteArray j_value = sliceToJArray(value);
74 if(j_value == nullptr) {
75 // exception thrown
76 if(m_env->ExceptionCheck()) {
77 m_env->ExceptionDescribe();
78 }
79 if(j_key != nullptr) {
80 m_env->DeleteLocalRef(j_key);
81 }
82 return;
83 }
84
85 m_env->CallVoidMethod(
86 m_jWriteBatchHandler,
87 m_jPutMethodId,
88 j_key,
89 j_value);
90 if(m_env->ExceptionCheck()) {
91 // exception thrown
92 m_env->ExceptionDescribe();
93 if(j_value != nullptr) {
94 m_env->DeleteLocalRef(j_value);
95 }
96 if(j_key != nullptr) {
97 m_env->DeleteLocalRef(j_key);
98 }
99 return;
100 }
101
102 if(j_value != nullptr) {
103 m_env->DeleteLocalRef(j_value);
104 }
105 if(j_key != nullptr) {
106 m_env->DeleteLocalRef(j_key);
107 }
108 }
109
110 void WriteBatchHandlerJniCallback::Merge(const Slice& key, const Slice& value) {
111 const jbyteArray j_key = sliceToJArray(key);
112 if(j_key == nullptr) {
113 // exception thrown
114 if(m_env->ExceptionCheck()) {
115 m_env->ExceptionDescribe();
116 }
117 return;
118 }
119
120 const jbyteArray j_value = sliceToJArray(value);
121 if(j_value == nullptr) {
122 // exception thrown
123 if(m_env->ExceptionCheck()) {
124 m_env->ExceptionDescribe();
125 }
126 if(j_key != nullptr) {
127 m_env->DeleteLocalRef(j_key);
128 }
129 return;
130 }
131
132 m_env->CallVoidMethod(
133 m_jWriteBatchHandler,
134 m_jMergeMethodId,
135 j_key,
136 j_value);
137 if(m_env->ExceptionCheck()) {
138 // exception thrown
139 m_env->ExceptionDescribe();
140 if(j_value != nullptr) {
141 m_env->DeleteLocalRef(j_value);
142 }
143 if(j_key != nullptr) {
144 m_env->DeleteLocalRef(j_key);
145 }
146 return;
147 }
148
149 if(j_value != nullptr) {
150 m_env->DeleteLocalRef(j_value);
151 }
152 if(j_key != nullptr) {
153 m_env->DeleteLocalRef(j_key);
154 }
155 }
156
157 void WriteBatchHandlerJniCallback::Delete(const Slice& key) {
158 const jbyteArray j_key = sliceToJArray(key);
159 if(j_key == nullptr) {
160 // exception thrown
161 if(m_env->ExceptionCheck()) {
162 m_env->ExceptionDescribe();
163 }
164 return;
165 }
166
167 m_env->CallVoidMethod(
168 m_jWriteBatchHandler,
169 m_jDeleteMethodId,
170 j_key);
171 if(m_env->ExceptionCheck()) {
172 // exception thrown
173 m_env->ExceptionDescribe();
174 if(j_key != nullptr) {
175 m_env->DeleteLocalRef(j_key);
176 }
177 return;
178 }
179
180 if(j_key != nullptr) {
181 m_env->DeleteLocalRef(j_key);
182 }
183 }
184
185 void WriteBatchHandlerJniCallback::DeleteRange(const Slice& beginKey,
186 const Slice& endKey) {
187 const jbyteArray j_beginKey = sliceToJArray(beginKey);
188 if (j_beginKey == nullptr) {
189 // exception thrown
190 if (m_env->ExceptionCheck()) {
191 m_env->ExceptionDescribe();
192 }
193 return;
194 }
195
196 const jbyteArray j_endKey = sliceToJArray(beginKey);
197 if (j_endKey == nullptr) {
198 // exception thrown
199 if (m_env->ExceptionCheck()) {
200 m_env->ExceptionDescribe();
201 }
202 return;
203 }
204
205 m_env->CallVoidMethod(m_jWriteBatchHandler, m_jDeleteRangeMethodId,
206 j_beginKey, j_endKey);
207 if (m_env->ExceptionCheck()) {
208 // exception thrown
209 m_env->ExceptionDescribe();
210 if (j_beginKey != nullptr) {
211 m_env->DeleteLocalRef(j_beginKey);
212 }
213 if (j_endKey != nullptr) {
214 m_env->DeleteLocalRef(j_endKey);
215 }
216 return;
217 }
218
219 if (j_beginKey != nullptr) {
220 m_env->DeleteLocalRef(j_beginKey);
221 }
222
223 if (j_endKey != nullptr) {
224 m_env->DeleteLocalRef(j_endKey);
225 }
226 }
227
228 void WriteBatchHandlerJniCallback::LogData(const Slice& blob) {
229 const jbyteArray j_blob = sliceToJArray(blob);
230 if(j_blob == nullptr) {
231 // exception thrown
232 if(m_env->ExceptionCheck()) {
233 m_env->ExceptionDescribe();
234 }
235 return;
236 }
237
238 m_env->CallVoidMethod(
239 m_jWriteBatchHandler,
240 m_jLogDataMethodId,
241 j_blob);
242 if(m_env->ExceptionCheck()) {
243 // exception thrown
244 m_env->ExceptionDescribe();
245 if(j_blob != nullptr) {
246 m_env->DeleteLocalRef(j_blob);
247 }
248 return;
249 }
250
251 if(j_blob != nullptr) {
252 m_env->DeleteLocalRef(j_blob);
253 }
254 }
255
256 bool WriteBatchHandlerJniCallback::Continue() {
257 jboolean jContinue = m_env->CallBooleanMethod(
258 m_jWriteBatchHandler,
259 m_jContinueMethodId);
260 if(m_env->ExceptionCheck()) {
261 // exception thrown
262 m_env->ExceptionDescribe();
263 }
264
265 return static_cast<bool>(jContinue == JNI_TRUE);
266 }
267
268 /*
269 * Creates a Java Byte Array from the data in a Slice
270 *
271 * When calling this function
272 * you must remember to call env->DeleteLocalRef
273 * on the result after you have finished with it
274 *
275 * @param s A Slice to convery to a Java byte array
276 *
277 * @return A reference to a Java byte array, or a nullptr if an
278 * exception occurs
279 */
280 jbyteArray WriteBatchHandlerJniCallback::sliceToJArray(const Slice& s) {
281 jbyteArray ja = m_env->NewByteArray(static_cast<jsize>(s.size()));
282 if(ja == nullptr) {
283 // exception thrown: OutOfMemoryError
284 return nullptr;
285 }
286
287 m_env->SetByteArrayRegion(
288 ja, 0, static_cast<jsize>(s.size()),
289 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(s.data())));
290 if(m_env->ExceptionCheck()) {
291 if(ja != nullptr) {
292 m_env->DeleteLocalRef(ja);
293 }
294 // exception thrown: ArrayIndexOutOfBoundsException
295 return nullptr;
296 }
297
298 return ja;
299 }
300
301 WriteBatchHandlerJniCallback::~WriteBatchHandlerJniCallback() {
302 if(m_jWriteBatchHandler != nullptr) {
303 m_env->DeleteGlobalRef(m_jWriteBatchHandler);
304 }
305 }
306 } // namespace rocksdb