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