]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/java/rocksjni/writebatchhandlerjnicallback.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / rocksdb / java / rocksjni / writebatchhandlerjnicallback.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
7c673cae
FG
5//
6// This file implements the callback "bridge" between Java and C++ for
7// rocksdb::Comparator.
8
9#include "rocksjni/writebatchhandlerjnicallback.h"
10#include "rocksjni/portal.h"
11
12namespace rocksdb {
13WriteBatchHandlerJniCallback::WriteBatchHandlerJniCallback(
14 JNIEnv* env, jobject jWriteBatchHandler)
11fdf7f2
TL
15 : JniCallback(env, jWriteBatchHandler), m_env(env) {
16
17 m_jPutCfMethodId = WriteBatchHandlerJni::getPutCfMethodId(env);
18 if(m_jPutCfMethodId == nullptr) {
19 // exception thrown
7c673cae
FG
20 return;
21 }
22
23 m_jPutMethodId = WriteBatchHandlerJni::getPutMethodId(env);
24 if(m_jPutMethodId == nullptr) {
25 // exception thrown
26 return;
27 }
28
11fdf7f2
TL
29 m_jMergeCfMethodId = WriteBatchHandlerJni::getMergeCfMethodId(env);
30 if(m_jMergeCfMethodId == nullptr) {
31 // exception thrown
32 return;
33 }
34
7c673cae
FG
35 m_jMergeMethodId = WriteBatchHandlerJni::getMergeMethodId(env);
36 if(m_jMergeMethodId == nullptr) {
37 // exception thrown
38 return;
39 }
40
11fdf7f2
TL
41 m_jDeleteCfMethodId = WriteBatchHandlerJni::getDeleteCfMethodId(env);
42 if(m_jDeleteCfMethodId == nullptr) {
43 // exception thrown
44 return;
45 }
46
7c673cae
FG
47 m_jDeleteMethodId = WriteBatchHandlerJni::getDeleteMethodId(env);
48 if(m_jDeleteMethodId == nullptr) {
49 // exception thrown
50 return;
51 }
52
11fdf7f2
TL
53 m_jSingleDeleteCfMethodId =
54 WriteBatchHandlerJni::getSingleDeleteCfMethodId(env);
55 if(m_jSingleDeleteCfMethodId == nullptr) {
56 // exception thrown
57 return;
58 }
59
60 m_jSingleDeleteMethodId = WriteBatchHandlerJni::getSingleDeleteMethodId(env);
61 if(m_jSingleDeleteMethodId == nullptr) {
62 // exception thrown
63 return;
64 }
65
66 m_jDeleteRangeCfMethodId =
67 WriteBatchHandlerJni::getDeleteRangeCfMethodId(env);
68 if (m_jDeleteRangeCfMethodId == nullptr) {
69 // exception thrown
70 return;
71 }
72
7c673cae
FG
73 m_jDeleteRangeMethodId = WriteBatchHandlerJni::getDeleteRangeMethodId(env);
74 if (m_jDeleteRangeMethodId == nullptr) {
75 // exception thrown
76 return;
77 }
78
79 m_jLogDataMethodId = WriteBatchHandlerJni::getLogDataMethodId(env);
80 if(m_jLogDataMethodId == nullptr) {
81 // exception thrown
82 return;
83 }
84
11fdf7f2
TL
85 m_jPutBlobIndexCfMethodId =
86 WriteBatchHandlerJni::getPutBlobIndexCfMethodId(env);
87 if(m_jPutBlobIndexCfMethodId == nullptr) {
7c673cae
FG
88 // exception thrown
89 return;
90 }
7c673cae 91
11fdf7f2
TL
92 m_jMarkBeginPrepareMethodId =
93 WriteBatchHandlerJni::getMarkBeginPrepareMethodId(env);
94 if(m_jMarkBeginPrepareMethodId == nullptr) {
7c673cae 95 // exception thrown
7c673cae
FG
96 return;
97 }
98
11fdf7f2
TL
99 m_jMarkEndPrepareMethodId =
100 WriteBatchHandlerJni::getMarkEndPrepareMethodId(env);
101 if(m_jMarkEndPrepareMethodId == nullptr) {
7c673cae 102 // exception thrown
7c673cae
FG
103 return;
104 }
105
11fdf7f2
TL
106 m_jMarkNoopMethodId = WriteBatchHandlerJni::getMarkNoopMethodId(env);
107 if(m_jMarkNoopMethodId == nullptr) {
7c673cae 108 // exception thrown
7c673cae
FG
109 return;
110 }
11fdf7f2
TL
111
112 m_jMarkRollbackMethodId = WriteBatchHandlerJni::getMarkRollbackMethodId(env);
113 if(m_jMarkRollbackMethodId == nullptr) {
114 // exception thrown
115 return;
7c673cae 116 }
7c673cae 117
11fdf7f2
TL
118 m_jMarkCommitMethodId = WriteBatchHandlerJni::getMarkCommitMethodId(env);
119 if(m_jMarkCommitMethodId == nullptr) {
7c673cae 120 // exception thrown
7c673cae
FG
121 return;
122 }
123
11fdf7f2
TL
124 m_jContinueMethodId = WriteBatchHandlerJni::getContinueMethodId(env);
125 if(m_jContinueMethodId == nullptr) {
7c673cae 126 // exception thrown
7c673cae
FG
127 return;
128 }
11fdf7f2 129}
7c673cae 130
11fdf7f2
TL
131rocksdb::Status WriteBatchHandlerJniCallback::PutCF(uint32_t column_family_id,
132 const Slice& key, const Slice& value) {
133 auto put = [this, column_family_id] (
134 jbyteArray j_key, jbyteArray j_value) {
135 m_env->CallVoidMethod(
136 m_jcallback_obj,
137 m_jPutCfMethodId,
138 static_cast<jint>(column_family_id),
7c673cae
FG
139 j_key,
140 j_value);
11fdf7f2
TL
141 };
142 auto status = WriteBatchHandlerJniCallback::kv_op(key, value, put);
143 if(status == nullptr) {
144 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
145 } else {
146 return rocksdb::Status(*status);
7c673cae 147 }
11fdf7f2 148}
7c673cae 149
11fdf7f2
TL
150void WriteBatchHandlerJniCallback::Put(const Slice& key, const Slice& value) {
151 auto put = [this] (
152 jbyteArray j_key, jbyteArray j_value) {
153 m_env->CallVoidMethod(
154 m_jcallback_obj,
155 m_jPutMethodId,
156 j_key,
157 j_value);
158 };
159 WriteBatchHandlerJniCallback::kv_op(key, value, put);
160}
161
162rocksdb::Status WriteBatchHandlerJniCallback::MergeCF(uint32_t column_family_id,
163 const Slice& key, const Slice& value) {
164 auto merge = [this, column_family_id] (
165 jbyteArray j_key, jbyteArray j_value) {
166 m_env->CallVoidMethod(
167 m_jcallback_obj,
168 m_jMergeCfMethodId,
169 static_cast<jint>(column_family_id),
170 j_key,
171 j_value);
172 };
173 auto status = WriteBatchHandlerJniCallback::kv_op(key, value, merge);
174 if(status == nullptr) {
175 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
176 } else {
177 return rocksdb::Status(*status);
7c673cae
FG
178 }
179}
180
11fdf7f2
TL
181void WriteBatchHandlerJniCallback::Merge(const Slice& key, const Slice& value) {
182 auto merge = [this] (
183 jbyteArray j_key, jbyteArray j_value) {
184 m_env->CallVoidMethod(
185 m_jcallback_obj,
186 m_jMergeMethodId,
187 j_key,
188 j_value);
189 };
190 WriteBatchHandlerJniCallback::kv_op(key, value, merge);
191}
192
193rocksdb::Status WriteBatchHandlerJniCallback::DeleteCF(uint32_t column_family_id,
194 const Slice& key) {
195 auto remove = [this, column_family_id] (jbyteArray j_key) {
196 m_env->CallVoidMethod(
197 m_jcallback_obj,
198 m_jDeleteCfMethodId,
199 static_cast<jint>(column_family_id),
200 j_key);
201 };
202 auto status = WriteBatchHandlerJniCallback::k_op(key, remove);
203 if(status == nullptr) {
204 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
205 } else {
206 return rocksdb::Status(*status);
7c673cae 207 }
11fdf7f2 208}
7c673cae 209
11fdf7f2
TL
210void WriteBatchHandlerJniCallback::Delete(const Slice& key) {
211 auto remove = [this] (jbyteArray j_key) {
212 m_env->CallVoidMethod(
213 m_jcallback_obj,
7c673cae
FG
214 m_jDeleteMethodId,
215 j_key);
11fdf7f2
TL
216 };
217 WriteBatchHandlerJniCallback::k_op(key, remove);
218}
219
220rocksdb::Status WriteBatchHandlerJniCallback::SingleDeleteCF(uint32_t column_family_id,
221 const Slice& key) {
222 auto singleDelete = [this, column_family_id] (jbyteArray j_key) {
223 m_env->CallVoidMethod(
224 m_jcallback_obj,
225 m_jSingleDeleteCfMethodId,
226 static_cast<jint>(column_family_id),
227 j_key);
228 };
229 auto status = WriteBatchHandlerJniCallback::k_op(key, singleDelete);
230 if(status == nullptr) {
231 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
232 } else {
233 return rocksdb::Status(*status);
7c673cae 234 }
11fdf7f2 235}
7c673cae 236
11fdf7f2
TL
237void WriteBatchHandlerJniCallback::SingleDelete(const Slice& key) {
238 auto singleDelete = [this] (jbyteArray j_key) {
239 m_env->CallVoidMethod(
240 m_jcallback_obj,
241 m_jSingleDeleteMethodId,
242 j_key);
243 };
244 WriteBatchHandlerJniCallback::k_op(key, singleDelete);
245}
246
247rocksdb::Status WriteBatchHandlerJniCallback::DeleteRangeCF(uint32_t column_family_id,
248 const Slice& beginKey, const Slice& endKey) {
249 auto deleteRange = [this, column_family_id] (
250 jbyteArray j_beginKey, jbyteArray j_endKey) {
251 m_env->CallVoidMethod(
252 m_jcallback_obj,
253 m_jDeleteRangeCfMethodId,
254 static_cast<jint>(column_family_id),
255 j_beginKey,
256 j_endKey);
257 };
258 auto status = WriteBatchHandlerJniCallback::kv_op(beginKey, endKey, deleteRange);
259 if(status == nullptr) {
260 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
261 } else {
262 return rocksdb::Status(*status);
7c673cae
FG
263 }
264}
265
266void WriteBatchHandlerJniCallback::DeleteRange(const Slice& beginKey,
11fdf7f2
TL
267 const Slice& endKey) {
268 auto deleteRange = [this] (
269 jbyteArray j_beginKey, jbyteArray j_endKey) {
270 m_env->CallVoidMethod(
271 m_jcallback_obj,
272 m_jDeleteRangeMethodId,
273 j_beginKey,
274 j_endKey);
275 };
276 WriteBatchHandlerJniCallback::kv_op(beginKey, endKey, deleteRange);
277}
7c673cae 278
11fdf7f2
TL
279void WriteBatchHandlerJniCallback::LogData(const Slice& blob) {
280 auto logData = [this] (jbyteArray j_blob) {
281 m_env->CallVoidMethod(
282 m_jcallback_obj,
283 m_jLogDataMethodId,
284 j_blob);
285 };
286 WriteBatchHandlerJniCallback::k_op(blob, logData);
287}
288
289rocksdb::Status WriteBatchHandlerJniCallback::PutBlobIndexCF(uint32_t column_family_id,
290 const Slice& key, const Slice& value) {
291 auto putBlobIndex = [this, column_family_id] (
292 jbyteArray j_key, jbyteArray j_value) {
293 m_env->CallVoidMethod(
294 m_jcallback_obj,
295 m_jPutBlobIndexCfMethodId,
296 static_cast<jint>(column_family_id),
297 j_key,
298 j_value);
299 };
300 auto status = WriteBatchHandlerJniCallback::kv_op(key, value, putBlobIndex);
301 if(status == nullptr) {
302 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
303 } else {
304 return rocksdb::Status(*status);
7c673cae 305 }
11fdf7f2
TL
306}
307
308rocksdb::Status WriteBatchHandlerJniCallback::MarkBeginPrepare(bool unprepare) {
309#ifndef DEBUG
310 (void) unprepare;
311#else
312 assert(!unprepare);
313#endif
314 m_env->CallVoidMethod(m_jcallback_obj, m_jMarkBeginPrepareMethodId);
7c673cae 315
11fdf7f2 316 // check for Exception, in-particular RocksDBException
7c673cae
FG
317 if (m_env->ExceptionCheck()) {
318 // exception thrown
11fdf7f2
TL
319 jthrowable exception = m_env->ExceptionOccurred();
320 std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
321 if (status == nullptr) {
322 // unkown status or exception occurred extracting status
323 m_env->ExceptionDescribe();
324 return rocksdb::Status::OK(); // TODO(AR) probably need a better error code here
325
326 } else {
327 m_env->ExceptionClear(); // clear the exception, as we have extracted the status
328 return rocksdb::Status(*status);
7c673cae 329 }
7c673cae
FG
330 }
331
11fdf7f2
TL
332 return rocksdb::Status::OK();
333}
7c673cae 334
11fdf7f2
TL
335rocksdb::Status WriteBatchHandlerJniCallback::MarkEndPrepare(const Slice& xid) {
336 auto markEndPrepare = [this] (
337 jbyteArray j_xid) {
338 m_env->CallVoidMethod(
339 m_jcallback_obj,
340 m_jMarkEndPrepareMethodId,
341 j_xid);
342 };
343 auto status = WriteBatchHandlerJniCallback::k_op(xid, markEndPrepare);
344 if(status == nullptr) {
345 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
346 } else {
347 return rocksdb::Status(*status);
7c673cae
FG
348 }
349}
350
11fdf7f2
TL
351rocksdb::Status WriteBatchHandlerJniCallback::MarkNoop(bool empty_batch) {
352 m_env->CallVoidMethod(m_jcallback_obj, m_jMarkNoopMethodId, static_cast<jboolean>(empty_batch));
353
354 // check for Exception, in-particular RocksDBException
355 if (m_env->ExceptionCheck()) {
7c673cae 356 // exception thrown
11fdf7f2
TL
357 jthrowable exception = m_env->ExceptionOccurred();
358 std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
359 if (status == nullptr) {
360 // unkown status or exception occurred extracting status
7c673cae 361 m_env->ExceptionDescribe();
11fdf7f2
TL
362 return rocksdb::Status::OK(); // TODO(AR) probably need a better error code here
363
364 } else {
365 m_env->ExceptionClear(); // clear the exception, as we have extracted the status
366 return rocksdb::Status(*status);
7c673cae 367 }
7c673cae
FG
368 }
369
11fdf7f2
TL
370 return rocksdb::Status::OK();
371}
372
373rocksdb::Status WriteBatchHandlerJniCallback::MarkRollback(const Slice& xid) {
374 auto markRollback = [this] (
375 jbyteArray j_xid) {
376 m_env->CallVoidMethod(
377 m_jcallback_obj,
378 m_jMarkRollbackMethodId,
379 j_xid);
380 };
381 auto status = WriteBatchHandlerJniCallback::k_op(xid, markRollback);
382 if(status == nullptr) {
383 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
384 } else {
385 return rocksdb::Status(*status);
7c673cae 386 }
11fdf7f2 387}
7c673cae 388
11fdf7f2
TL
389rocksdb::Status WriteBatchHandlerJniCallback::MarkCommit(const Slice& xid) {
390 auto markCommit = [this] (
391 jbyteArray j_xid) {
392 m_env->CallVoidMethod(
393 m_jcallback_obj,
394 m_jMarkCommitMethodId,
395 j_xid);
396 };
397 auto status = WriteBatchHandlerJniCallback::k_op(xid, markCommit);
398 if(status == nullptr) {
399 return rocksdb::Status::OK(); // TODO(AR) what to do if there is an Exception but we don't know the rocksdb::Status?
400 } else {
401 return rocksdb::Status(*status);
7c673cae
FG
402 }
403}
404
405bool WriteBatchHandlerJniCallback::Continue() {
406 jboolean jContinue = m_env->CallBooleanMethod(
11fdf7f2 407 m_jcallback_obj,
7c673cae
FG
408 m_jContinueMethodId);
409 if(m_env->ExceptionCheck()) {
410 // exception thrown
411 m_env->ExceptionDescribe();
412 }
413
414 return static_cast<bool>(jContinue == JNI_TRUE);
415}
416
11fdf7f2
TL
417std::unique_ptr<rocksdb::Status> WriteBatchHandlerJniCallback::kv_op(const Slice& key, const Slice& value, std::function<void(jbyteArray, jbyteArray)> kvFn) {
418 const jbyteArray j_key = JniUtil::copyBytes(m_env, key);
419 if (j_key == nullptr) {
420 // exception thrown
421 if (m_env->ExceptionCheck()) {
422 m_env->ExceptionDescribe();
423 }
7c673cae
FG
424 return nullptr;
425 }
426
11fdf7f2
TL
427 const jbyteArray j_value = JniUtil::copyBytes(m_env, value);
428 if (j_value == nullptr) {
429 // exception thrown
430 if (m_env->ExceptionCheck()) {
431 m_env->ExceptionDescribe();
432 }
433 if (j_key != nullptr) {
434 m_env->DeleteLocalRef(j_key);
7c673cae 435 }
7c673cae
FG
436 return nullptr;
437 }
438
11fdf7f2
TL
439 kvFn(j_key, j_value);
440
441 // check for Exception, in-particular RocksDBException
442 if (m_env->ExceptionCheck()) {
443 if (j_value != nullptr) {
444 m_env->DeleteLocalRef(j_value);
445 }
446 if (j_key != nullptr) {
447 m_env->DeleteLocalRef(j_key);
448 }
449
450 // exception thrown
451 jthrowable exception = m_env->ExceptionOccurred();
452 std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
453 if (status == nullptr) {
454 // unkown status or exception occurred extracting status
455 m_env->ExceptionDescribe();
456 return nullptr;
457
458 } else {
459 m_env->ExceptionClear(); // clear the exception, as we have extracted the status
460 return status;
461 }
462 }
463
464 if (j_value != nullptr) {
465 m_env->DeleteLocalRef(j_value);
466 }
467 if (j_key != nullptr) {
468 m_env->DeleteLocalRef(j_key);
469 }
470
471 // all OK
472 return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::OK()));
7c673cae
FG
473}
474
11fdf7f2
TL
475std::unique_ptr<rocksdb::Status> WriteBatchHandlerJniCallback::k_op(const Slice& key, std::function<void(jbyteArray)> kFn) {
476 const jbyteArray j_key = JniUtil::copyBytes(m_env, key);
477 if (j_key == nullptr) {
478 // exception thrown
479 if (m_env->ExceptionCheck()) {
480 m_env->ExceptionDescribe();
481 }
482 return nullptr;
483 }
484
485 kFn(j_key);
486
487 // check for Exception, in-particular RocksDBException
488 if (m_env->ExceptionCheck()) {
489 if (j_key != nullptr) {
490 m_env->DeleteLocalRef(j_key);
491 }
492
493 // exception thrown
494 jthrowable exception = m_env->ExceptionOccurred();
495 std::unique_ptr<rocksdb::Status> status = rocksdb::RocksDBExceptionJni::toCppStatus(m_env, exception);
496 if (status == nullptr) {
497 // unkown status or exception occurred extracting status
498 m_env->ExceptionDescribe();
499 return nullptr;
500
501 } else {
502 m_env->ExceptionClear(); // clear the exception, as we have extracted the status
503 return status;
504 }
505 }
506
507 if (j_key != nullptr) {
508 m_env->DeleteLocalRef(j_key);
7c673cae 509 }
11fdf7f2
TL
510
511 // all OK
512 return std::unique_ptr<rocksdb::Status>(new rocksdb::Status(rocksdb::Status::OK()));
7c673cae
FG
513}
514} // namespace rocksdb