]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/java/rocksjni/transaction.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / java / rocksjni / transaction.cc
CommitLineData
11fdf7f2
TL
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++
f67539c2 7// for ROCKSDB_NAMESPACE::Transaction.
11fdf7f2 8
1e59de90
TL
9#include "rocksdb/utilities/transaction.h"
10
11fdf7f2 11#include <jni.h>
1e59de90 12
11fdf7f2
TL
13#include <functional>
14
15#include "include/org_rocksdb_Transaction.h"
1e59de90 16#include "rocksjni/cplusplus_to_java_convert.h"
11fdf7f2
TL
17#include "rocksjni/portal.h"
18
11fdf7f2
TL
19#if defined(_MSC_VER)
20#pragma warning(push)
21#pragma warning(disable : 4503) // identifier' : decorated name length
22 // exceeded, name was truncated
23#endif
24
25/*
26 * Class: org_rocksdb_Transaction
27 * Method: setSnapshot
28 * Signature: (J)V
29 */
30void Java_org_rocksdb_Transaction_setSnapshot(JNIEnv* /*env*/, jobject /*jobj*/,
31 jlong jhandle) {
f67539c2 32 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
33 txn->SetSnapshot();
34}
35
36/*
37 * Class: org_rocksdb_Transaction
38 * Method: setSnapshotOnNextOperation
39 * Signature: (J)V
40 */
41void Java_org_rocksdb_Transaction_setSnapshotOnNextOperation__J(
42 JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle) {
f67539c2 43 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
44 txn->SetSnapshotOnNextOperation(nullptr);
45}
46
47/*
48 * Class: org_rocksdb_Transaction
49 * Method: setSnapshotOnNextOperation
50 * Signature: (JJ)V
51 */
52void Java_org_rocksdb_Transaction_setSnapshotOnNextOperation__JJ(
53 JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
54 jlong jtxn_notifier_handle) {
f67539c2
TL
55 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
56 auto* txn_notifier = reinterpret_cast<
57 std::shared_ptr<ROCKSDB_NAMESPACE::TransactionNotifierJniCallback>*>(
58 jtxn_notifier_handle);
11fdf7f2
TL
59 txn->SetSnapshotOnNextOperation(*txn_notifier);
60}
61
62/*
63 * Class: org_rocksdb_Transaction
64 * Method: getSnapshot
65 * Signature: (J)J
66 */
67jlong Java_org_rocksdb_Transaction_getSnapshot(JNIEnv* /*env*/,
68 jobject /*jobj*/,
69 jlong jhandle) {
f67539c2
TL
70 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
71 const ROCKSDB_NAMESPACE::Snapshot* snapshot = txn->GetSnapshot();
1e59de90 72 return GET_CPLUSPLUS_POINTER(snapshot);
11fdf7f2
TL
73}
74
75/*
76 * Class: org_rocksdb_Transaction
77 * Method: clearSnapshot
78 * Signature: (J)V
79 */
80void Java_org_rocksdb_Transaction_clearSnapshot(JNIEnv* /*env*/,
81 jobject /*jobj*/,
82 jlong jhandle) {
f67539c2 83 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
84 txn->ClearSnapshot();
85}
86
87/*
88 * Class: org_rocksdb_Transaction
89 * Method: prepare
90 * Signature: (J)V
91 */
92void Java_org_rocksdb_Transaction_prepare(JNIEnv* env, jobject /*jobj*/,
93 jlong jhandle) {
f67539c2
TL
94 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
95 ROCKSDB_NAMESPACE::Status s = txn->Prepare();
11fdf7f2 96 if (!s.ok()) {
f67539c2 97 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
98 }
99}
100
101/*
102 * Class: org_rocksdb_Transaction
103 * Method: commit
104 * Signature: (J)V
105 */
106void Java_org_rocksdb_Transaction_commit(JNIEnv* env, jobject /*jobj*/,
107 jlong jhandle) {
f67539c2
TL
108 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
109 ROCKSDB_NAMESPACE::Status s = txn->Commit();
11fdf7f2 110 if (!s.ok()) {
f67539c2 111 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
112 }
113}
114
115/*
116 * Class: org_rocksdb_Transaction
117 * Method: rollback
118 * Signature: (J)V
119 */
120void Java_org_rocksdb_Transaction_rollback(JNIEnv* env, jobject /*jobj*/,
121 jlong jhandle) {
f67539c2
TL
122 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
123 ROCKSDB_NAMESPACE::Status s = txn->Rollback();
11fdf7f2 124 if (!s.ok()) {
f67539c2 125 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
126 }
127}
128
129/*
130 * Class: org_rocksdb_Transaction
131 * Method: setSavePoint
132 * Signature: (J)V
133 */
134void Java_org_rocksdb_Transaction_setSavePoint(JNIEnv* /*env*/,
135 jobject /*jobj*/,
136 jlong jhandle) {
f67539c2 137 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
138 txn->SetSavePoint();
139}
140
141/*
142 * Class: org_rocksdb_Transaction
143 * Method: rollbackToSavePoint
144 * Signature: (J)V
145 */
146void Java_org_rocksdb_Transaction_rollbackToSavePoint(JNIEnv* env,
147 jobject /*jobj*/,
148 jlong jhandle) {
f67539c2
TL
149 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
150 ROCKSDB_NAMESPACE::Status s = txn->RollbackToSavePoint();
11fdf7f2 151 if (!s.ok()) {
f67539c2 152 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
153 }
154}
155
f67539c2
TL
156typedef std::function<ROCKSDB_NAMESPACE::Status(
157 const ROCKSDB_NAMESPACE::ReadOptions&, const ROCKSDB_NAMESPACE::Slice&,
158 std::string*)>
11fdf7f2
TL
159 FnGet;
160
161// TODO(AR) consider refactoring to share this between here and rocksjni.cc
162jbyteArray txn_get_helper(JNIEnv* env, const FnGet& fn_get,
163 const jlong& jread_options_handle,
164 const jbyteArray& jkey, const jint& jkey_part_len) {
165 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
166 if (key == nullptr) {
167 // exception thrown: OutOfMemoryError
168 return nullptr;
169 }
f67539c2
TL
170 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
171 jkey_part_len);
11fdf7f2
TL
172
173 auto* read_options =
f67539c2 174 reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
11fdf7f2 175 std::string value;
f67539c2 176 ROCKSDB_NAMESPACE::Status s = fn_get(*read_options, key_slice, &value);
11fdf7f2
TL
177
178 // trigger java unref on key.
179 // by passing JNI_ABORT, it will simply release the reference without
180 // copying the result back to the java byte array.
181 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
182
183 if (s.IsNotFound()) {
184 return nullptr;
185 }
186
187 if (s.ok()) {
188 jbyteArray jret_value = env->NewByteArray(static_cast<jsize>(value.size()));
189 if (jret_value == nullptr) {
190 // exception thrown: OutOfMemoryError
191 return nullptr;
192 }
1e59de90
TL
193 env->SetByteArrayRegion(
194 jret_value, 0, static_cast<jsize>(value.size()),
195 const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value.c_str())));
11fdf7f2
TL
196 if (env->ExceptionCheck()) {
197 // exception thrown: ArrayIndexOutOfBoundsException
198 return nullptr;
199 }
200 return jret_value;
201 }
202
f67539c2 203 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
204 return nullptr;
205}
206
207/*
208 * Class: org_rocksdb_Transaction
209 * Method: get
210 * Signature: (JJ[BIJ)[B
211 */
212jbyteArray Java_org_rocksdb_Transaction_get__JJ_3BIJ(
213 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
214 jbyteArray jkey, jint jkey_part_len, jlong jcolumn_family_handle) {
f67539c2 215 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 216 auto* column_family_handle =
f67539c2
TL
217 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
218 jcolumn_family_handle);
219 FnGet fn_get =
220 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
221 const ROCKSDB_NAMESPACE::ReadOptions&,
222 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
223 const ROCKSDB_NAMESPACE::Slice&, std::string*)>(
1e59de90
TL
224 &ROCKSDB_NAMESPACE::Transaction::Get, txn, std::placeholders::_1,
225 column_family_handle, std::placeholders::_2, std::placeholders::_3);
11fdf7f2
TL
226 return txn_get_helper(env, fn_get, jread_options_handle, jkey, jkey_part_len);
227}
228
229/*
230 * Class: org_rocksdb_Transaction
231 * Method: get
232 * Signature: (JJ[BI)[B
233 */
234jbyteArray Java_org_rocksdb_Transaction_get__JJ_3BI(
235 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
236 jbyteArray jkey, jint jkey_part_len) {
f67539c2
TL
237 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
238 FnGet fn_get =
239 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
240 const ROCKSDB_NAMESPACE::ReadOptions&,
241 const ROCKSDB_NAMESPACE::Slice&, std::string*)>(
1e59de90
TL
242 &ROCKSDB_NAMESPACE::Transaction::Get, txn, std::placeholders::_1,
243 std::placeholders::_2, std::placeholders::_3);
11fdf7f2
TL
244 return txn_get_helper(env, fn_get, jread_options_handle, jkey, jkey_part_len);
245}
246
247// TODO(AR) consider refactoring to share this between here and rocksjni.cc
248// used by txn_multi_get_helper below
f67539c2 249std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> txn_column_families_helper(
11fdf7f2 250 JNIEnv* env, jlongArray jcolumn_family_handles, bool* has_exception) {
f67539c2 251 std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> cf_handles;
11fdf7f2
TL
252 if (jcolumn_family_handles != nullptr) {
253 const jsize len_cols = env->GetArrayLength(jcolumn_family_handles);
254 if (len_cols > 0) {
11fdf7f2
TL
255 jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr);
256 if (jcfh == nullptr) {
257 // exception thrown: OutOfMemoryError
258 *has_exception = JNI_TRUE;
f67539c2 259 return std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>();
11fdf7f2
TL
260 }
261 for (int i = 0; i < len_cols; i++) {
262 auto* cf_handle =
f67539c2 263 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(jcfh[i]);
11fdf7f2
TL
264 cf_handles.push_back(cf_handle);
265 }
266 env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT);
267 }
268 }
269 return cf_handles;
270}
271
f67539c2
TL
272typedef std::function<std::vector<ROCKSDB_NAMESPACE::Status>(
273 const ROCKSDB_NAMESPACE::ReadOptions&,
274 const std::vector<ROCKSDB_NAMESPACE::Slice>&, std::vector<std::string>*)>
11fdf7f2
TL
275 FnMultiGet;
276
277void free_parts(
278 JNIEnv* env,
279 std::vector<std::tuple<jbyteArray, jbyte*, jobject>>& parts_to_free) {
280 for (auto& value : parts_to_free) {
281 jobject jk;
282 jbyteArray jk_ba;
283 jbyte* jk_val;
284 std::tie(jk_ba, jk_val, jk) = value;
285 env->ReleaseByteArrayElements(jk_ba, jk_val, JNI_ABORT);
286 env->DeleteLocalRef(jk);
287 }
288}
289
1e59de90
TL
290void free_key_values(std::vector<jbyte*>& keys_to_free) {
291 for (auto& key : keys_to_free) {
292 delete[] key;
293 }
294}
295
11fdf7f2
TL
296// TODO(AR) consider refactoring to share this between here and rocksjni.cc
297// cf multi get
298jobjectArray txn_multi_get_helper(JNIEnv* env, const FnMultiGet& fn_multi_get,
299 const jlong& jread_options_handle,
300 const jobjectArray& jkey_parts) {
301 const jsize len_key_parts = env->GetArrayLength(jkey_parts);
11fdf7f2 302
f67539c2 303 std::vector<ROCKSDB_NAMESPACE::Slice> key_parts;
1e59de90 304 std::vector<jbyte*> keys_to_free;
11fdf7f2
TL
305 for (int i = 0; i < len_key_parts; i++) {
306 const jobject jk = env->GetObjectArrayElement(jkey_parts, i);
307 if (env->ExceptionCheck()) {
308 // exception thrown: ArrayIndexOutOfBoundsException
1e59de90 309 free_key_values(keys_to_free);
11fdf7f2
TL
310 return nullptr;
311 }
312 jbyteArray jk_ba = reinterpret_cast<jbyteArray>(jk);
313 const jsize len_key = env->GetArrayLength(jk_ba);
1e59de90 314 jbyte* jk_val = new jbyte[len_key];
11fdf7f2
TL
315 if (jk_val == nullptr) {
316 // exception thrown: OutOfMemoryError
317 env->DeleteLocalRef(jk);
1e59de90
TL
318 free_key_values(keys_to_free);
319
320 jclass exception_cls = (env)->FindClass("java/lang/OutOfMemoryError");
321 (env)->ThrowNew(exception_cls,
322 "Insufficient Memory for CF handle array.");
11fdf7f2
TL
323 return nullptr;
324 }
1e59de90 325 env->GetByteArrayRegion(jk_ba, 0, len_key, jk_val);
11fdf7f2 326
f67539c2
TL
327 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(jk_val),
328 len_key);
11fdf7f2 329 key_parts.push_back(key_slice);
1e59de90
TL
330 keys_to_free.push_back(jk_val);
331 env->DeleteLocalRef(jk);
11fdf7f2
TL
332 }
333
334 auto* read_options =
f67539c2 335 reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
11fdf7f2 336 std::vector<std::string> value_parts;
f67539c2 337 std::vector<ROCKSDB_NAMESPACE::Status> s =
11fdf7f2
TL
338 fn_multi_get(*read_options, key_parts, &value_parts);
339
340 // free up allocated byte arrays
1e59de90 341 free_key_values(keys_to_free);
11fdf7f2
TL
342
343 // prepare the results
344 const jclass jcls_ba = env->FindClass("[B");
345 jobjectArray jresults =
346 env->NewObjectArray(static_cast<jsize>(s.size()), jcls_ba, nullptr);
347 if (jresults == nullptr) {
348 // exception thrown: OutOfMemoryError
349 return nullptr;
350 }
351
352 // add to the jresults
f67539c2
TL
353 for (std::vector<ROCKSDB_NAMESPACE::Status>::size_type i = 0; i != s.size();
354 i++) {
11fdf7f2
TL
355 if (s[i].ok()) {
356 jbyteArray jentry_value =
357 env->NewByteArray(static_cast<jsize>(value_parts[i].size()));
358 if (jentry_value == nullptr) {
359 // exception thrown: OutOfMemoryError
360 return nullptr;
361 }
362
363 env->SetByteArrayRegion(
364 jentry_value, 0, static_cast<jsize>(value_parts[i].size()),
1e59de90
TL
365 const_cast<jbyte*>(
366 reinterpret_cast<const jbyte*>(value_parts[i].c_str())));
11fdf7f2
TL
367 if (env->ExceptionCheck()) {
368 // exception thrown: ArrayIndexOutOfBoundsException
369 env->DeleteLocalRef(jentry_value);
370 return nullptr;
371 }
372
373 env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jentry_value);
374 env->DeleteLocalRef(jentry_value);
375 }
376 }
377
378 return jresults;
379}
380
381/*
382 * Class: org_rocksdb_Transaction
383 * Method: multiGet
384 * Signature: (JJ[[B[J)[[B
385 */
386jobjectArray Java_org_rocksdb_Transaction_multiGet__JJ_3_3B_3J(
387 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
388 jobjectArray jkey_parts, jlongArray jcolumn_family_handles) {
389 bool has_exception = false;
f67539c2
TL
390 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>
391 column_family_handles = txn_column_families_helper(
392 env, jcolumn_family_handles, &has_exception);
11fdf7f2
TL
393 if (has_exception) {
394 // exception thrown: OutOfMemoryError
395 return nullptr;
396 }
f67539c2
TL
397 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
398 FnMultiGet fn_multi_get = std::bind<std::vector<ROCKSDB_NAMESPACE::Status> (
399 ROCKSDB_NAMESPACE::Transaction::*)(
400 const ROCKSDB_NAMESPACE::ReadOptions&,
401 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>&,
402 const std::vector<ROCKSDB_NAMESPACE::Slice>&, std::vector<std::string>*)>(
1e59de90
TL
403 &ROCKSDB_NAMESPACE::Transaction::MultiGet, txn, std::placeholders::_1,
404 column_family_handles, std::placeholders::_2, std::placeholders::_3);
11fdf7f2
TL
405 return txn_multi_get_helper(env, fn_multi_get, jread_options_handle,
406 jkey_parts);
407}
408
409/*
410 * Class: org_rocksdb_Transaction
411 * Method: multiGet
412 * Signature: (JJ[[B)[[B
413 */
414jobjectArray Java_org_rocksdb_Transaction_multiGet__JJ_3_3B(
415 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
416 jobjectArray jkey_parts) {
f67539c2
TL
417 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
418 FnMultiGet fn_multi_get = std::bind<std::vector<ROCKSDB_NAMESPACE::Status> (
419 ROCKSDB_NAMESPACE::Transaction::*)(
420 const ROCKSDB_NAMESPACE::ReadOptions&,
421 const std::vector<ROCKSDB_NAMESPACE::Slice>&, std::vector<std::string>*)>(
1e59de90
TL
422 &ROCKSDB_NAMESPACE::Transaction::MultiGet, txn, std::placeholders::_1,
423 std::placeholders::_2, std::placeholders::_3);
11fdf7f2
TL
424 return txn_multi_get_helper(env, fn_multi_get, jread_options_handle,
425 jkey_parts);
426}
427
428/*
429 * Class: org_rocksdb_Transaction
430 * Method: getForUpdate
494da23a 431 * Signature: (JJ[BIJZZ)[B
11fdf7f2 432 */
494da23a 433jbyteArray Java_org_rocksdb_Transaction_getForUpdate__JJ_3BIJZZ(
11fdf7f2
TL
434 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
435 jbyteArray jkey, jint jkey_part_len, jlong jcolumn_family_handle,
494da23a 436 jboolean jexclusive, jboolean jdo_validate) {
11fdf7f2 437 auto* column_family_handle =
f67539c2
TL
438 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
439 jcolumn_family_handle);
440 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
441 FnGet fn_get_for_update =
442 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
443 const ROCKSDB_NAMESPACE::ReadOptions&,
444 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
445 const ROCKSDB_NAMESPACE::Slice&, std::string*, bool, bool)>(
1e59de90
TL
446 &ROCKSDB_NAMESPACE::Transaction::GetForUpdate, txn,
447 std::placeholders::_1, column_family_handle, std::placeholders::_2,
448 std::placeholders::_3, jexclusive, jdo_validate);
11fdf7f2
TL
449 return txn_get_helper(env, fn_get_for_update, jread_options_handle, jkey,
450 jkey_part_len);
451}
452
453/*
454 * Class: org_rocksdb_Transaction
455 * Method: getForUpdate
494da23a 456 * Signature: (JJ[BIZZ)[B
11fdf7f2 457 */
494da23a 458jbyteArray Java_org_rocksdb_Transaction_getForUpdate__JJ_3BIZZ(
11fdf7f2 459 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
494da23a
TL
460 jbyteArray jkey, jint jkey_part_len, jboolean jexclusive,
461 jboolean jdo_validate) {
f67539c2
TL
462 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
463 FnGet fn_get_for_update =
464 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
465 const ROCKSDB_NAMESPACE::ReadOptions&,
466 const ROCKSDB_NAMESPACE::Slice&, std::string*, bool, bool)>(
1e59de90
TL
467 &ROCKSDB_NAMESPACE::Transaction::GetForUpdate, txn,
468 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
f67539c2 469 jexclusive, jdo_validate);
11fdf7f2
TL
470 return txn_get_helper(env, fn_get_for_update, jread_options_handle, jkey,
471 jkey_part_len);
472}
473
474/*
475 * Class: org_rocksdb_Transaction
476 * Method: multiGetForUpdate
477 * Signature: (JJ[[B[J)[[B
478 */
479jobjectArray Java_org_rocksdb_Transaction_multiGetForUpdate__JJ_3_3B_3J(
480 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
481 jobjectArray jkey_parts, jlongArray jcolumn_family_handles) {
482 bool has_exception = false;
f67539c2
TL
483 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>
484 column_family_handles = txn_column_families_helper(
485 env, jcolumn_family_handles, &has_exception);
11fdf7f2
TL
486 if (has_exception) {
487 // exception thrown: OutOfMemoryError
488 return nullptr;
489 }
f67539c2
TL
490 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
491 FnMultiGet fn_multi_get_for_update = std::bind<std::vector<
492 ROCKSDB_NAMESPACE::Status> (ROCKSDB_NAMESPACE::Transaction::*)(
493 const ROCKSDB_NAMESPACE::ReadOptions&,
494 const std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>&,
495 const std::vector<ROCKSDB_NAMESPACE::Slice>&, std::vector<std::string>*)>(
1e59de90
TL
496 &ROCKSDB_NAMESPACE::Transaction::MultiGetForUpdate, txn,
497 std::placeholders::_1, column_family_handles, std::placeholders::_2,
498 std::placeholders::_3);
11fdf7f2
TL
499 return txn_multi_get_helper(env, fn_multi_get_for_update,
500 jread_options_handle, jkey_parts);
501}
502
503/*
504 * Class: org_rocksdb_Transaction
505 * Method: multiGetForUpdate
506 * Signature: (JJ[[B)[[B
507 */
508jobjectArray Java_org_rocksdb_Transaction_multiGetForUpdate__JJ_3_3B(
509 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jread_options_handle,
510 jobjectArray jkey_parts) {
f67539c2
TL
511 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
512 FnMultiGet fn_multi_get_for_update = std::bind<std::vector<
513 ROCKSDB_NAMESPACE::Status> (ROCKSDB_NAMESPACE::Transaction::*)(
514 const ROCKSDB_NAMESPACE::ReadOptions&,
515 const std::vector<ROCKSDB_NAMESPACE::Slice>&, std::vector<std::string>*)>(
1e59de90
TL
516 &ROCKSDB_NAMESPACE::Transaction::MultiGetForUpdate, txn,
517 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
11fdf7f2
TL
518 return txn_multi_get_helper(env, fn_multi_get_for_update,
519 jread_options_handle, jkey_parts);
520}
521
522/*
523 * Class: org_rocksdb_Transaction
524 * Method: getIterator
525 * Signature: (JJ)J
526 */
527jlong Java_org_rocksdb_Transaction_getIterator__JJ(JNIEnv* /*env*/,
528 jobject /*jobj*/,
529 jlong jhandle,
530 jlong jread_options_handle) {
f67539c2 531 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 532 auto* read_options =
f67539c2 533 reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
1e59de90 534 return GET_CPLUSPLUS_POINTER(txn->GetIterator(*read_options));
11fdf7f2
TL
535}
536
537/*
538 * Class: org_rocksdb_Transaction
539 * Method: getIterator
540 * Signature: (JJJ)J
541 */
542jlong Java_org_rocksdb_Transaction_getIterator__JJJ(
543 JNIEnv* /*env*/, jobject /*jobj*/, jlong jhandle,
544 jlong jread_options_handle, jlong jcolumn_family_handle) {
f67539c2 545 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 546 auto* read_options =
f67539c2 547 reinterpret_cast<ROCKSDB_NAMESPACE::ReadOptions*>(jread_options_handle);
11fdf7f2 548 auto* column_family_handle =
f67539c2
TL
549 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
550 jcolumn_family_handle);
1e59de90 551 return GET_CPLUSPLUS_POINTER(
11fdf7f2
TL
552 txn->GetIterator(*read_options, column_family_handle));
553}
554
f67539c2
TL
555typedef std::function<ROCKSDB_NAMESPACE::Status(
556 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>
11fdf7f2
TL
557 FnWriteKV;
558
559// TODO(AR) consider refactoring to share this between here and rocksjni.cc
560void txn_write_kv_helper(JNIEnv* env, const FnWriteKV& fn_write_kv,
561 const jbyteArray& jkey, const jint& jkey_part_len,
562 const jbyteArray& jval, const jint& jval_len) {
563 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
564 if (key == nullptr) {
565 // exception thrown: OutOfMemoryError
566 return;
567 }
568 jbyte* value = env->GetByteArrayElements(jval, nullptr);
569 if (value == nullptr) {
570 // exception thrown: OutOfMemoryError
571 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
572 return;
573 }
f67539c2
TL
574 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
575 jkey_part_len);
576 ROCKSDB_NAMESPACE::Slice value_slice(reinterpret_cast<char*>(value),
577 jval_len);
11fdf7f2 578
f67539c2 579 ROCKSDB_NAMESPACE::Status s = fn_write_kv(key_slice, value_slice);
11fdf7f2
TL
580
581 // trigger java unref on key.
582 // by passing JNI_ABORT, it will simply release the reference without
583 // copying the result back to the java byte array.
584 env->ReleaseByteArrayElements(jval, value, JNI_ABORT);
585 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
586
587 if (s.ok()) {
588 return;
589 }
f67539c2 590 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
591}
592
593/*
594 * Class: org_rocksdb_Transaction
595 * Method: put
494da23a 596 * Signature: (J[BI[BIJZ)V
11fdf7f2 597 */
494da23a 598void Java_org_rocksdb_Transaction_put__J_3BI_3BIJZ(
11fdf7f2
TL
599 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
600 jint jkey_part_len, jbyteArray jval, jint jval_len,
494da23a 601 jlong jcolumn_family_handle, jboolean jassume_tracked) {
f67539c2 602 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 603 auto* column_family_handle =
f67539c2
TL
604 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
605 jcolumn_family_handle);
606 FnWriteKV fn_put =
607 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
608 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
609 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&,
610 bool)>(&ROCKSDB_NAMESPACE::Transaction::Put, txn,
1e59de90
TL
611 column_family_handle, std::placeholders::_1,
612 std::placeholders::_2, jassume_tracked);
11fdf7f2
TL
613 txn_write_kv_helper(env, fn_put, jkey, jkey_part_len, jval, jval_len);
614}
615
616/*
617 * Class: org_rocksdb_Transaction
618 * Method: put
619 * Signature: (J[BI[BI)V
620 */
621void Java_org_rocksdb_Transaction_put__J_3BI_3BI(JNIEnv* env, jobject /*jobj*/,
622 jlong jhandle, jbyteArray jkey,
623 jint jkey_part_len,
624 jbyteArray jval,
625 jint jval_len) {
f67539c2
TL
626 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
627 FnWriteKV fn_put =
628 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
629 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90
TL
630 &ROCKSDB_NAMESPACE::Transaction::Put, txn, std::placeholders::_1,
631 std::placeholders::_2);
11fdf7f2
TL
632 txn_write_kv_helper(env, fn_put, jkey, jkey_part_len, jval, jval_len);
633}
634
f67539c2
TL
635typedef std::function<ROCKSDB_NAMESPACE::Status(
636 const ROCKSDB_NAMESPACE::SliceParts&, const ROCKSDB_NAMESPACE::SliceParts&)>
11fdf7f2
TL
637 FnWriteKVParts;
638
639// TODO(AR) consider refactoring to share this between here and rocksjni.cc
640void txn_write_kv_parts_helper(JNIEnv* env,
641 const FnWriteKVParts& fn_write_kv_parts,
642 const jobjectArray& jkey_parts,
643 const jint& jkey_parts_len,
644 const jobjectArray& jvalue_parts,
645 const jint& jvalue_parts_len) {
646#ifndef DEBUG
1e59de90 647 (void)jvalue_parts_len;
11fdf7f2
TL
648#else
649 assert(jkey_parts_len == jvalue_parts_len);
650#endif
651
f67539c2
TL
652 auto key_parts = std::vector<ROCKSDB_NAMESPACE::Slice>();
653 auto value_parts = std::vector<ROCKSDB_NAMESPACE::Slice>();
11fdf7f2
TL
654 auto jparts_to_free = std::vector<std::tuple<jbyteArray, jbyte*, jobject>>();
655
1e59de90
TL
656 // Since this is fundamentally a gather write at the RocksDB level,
657 // it seems wrong to refactor it by copying (gathering) keys and data here,
658 // in order to avoid the local reference limit.
659 // The user needs to be a aware that there is a limit to the number of parts
660 // which can be gathered.
661 if (env->EnsureLocalCapacity(jkey_parts_len + jvalue_parts_len) != 0) {
662 // no space for all the jobjects we store up
663 env->ExceptionClear();
664 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
665 env, "Insufficient JNI local references for " +
666 std::to_string(jkey_parts_len) + " key/value parts");
667 return;
668 }
669
11fdf7f2
TL
670 // convert java key_parts/value_parts byte[][] to Slice(s)
671 for (jsize i = 0; i < jkey_parts_len; ++i) {
672 const jobject jobj_key_part = env->GetObjectArrayElement(jkey_parts, i);
673 if (env->ExceptionCheck()) {
674 // exception thrown: ArrayIndexOutOfBoundsException
675 free_parts(env, jparts_to_free);
676 return;
677 }
678 const jobject jobj_value_part = env->GetObjectArrayElement(jvalue_parts, i);
679 if (env->ExceptionCheck()) {
680 // exception thrown: ArrayIndexOutOfBoundsException
681 env->DeleteLocalRef(jobj_key_part);
682 free_parts(env, jparts_to_free);
683 return;
684 }
685
686 const jbyteArray jba_key_part = reinterpret_cast<jbyteArray>(jobj_key_part);
687 const jsize jkey_part_len = env->GetArrayLength(jba_key_part);
11fdf7f2
TL
688 jbyte* jkey_part = env->GetByteArrayElements(jba_key_part, nullptr);
689 if (jkey_part == nullptr) {
690 // exception thrown: OutOfMemoryError
691 env->DeleteLocalRef(jobj_value_part);
692 env->DeleteLocalRef(jobj_key_part);
693 free_parts(env, jparts_to_free);
694 return;
695 }
696
697 const jbyteArray jba_value_part =
698 reinterpret_cast<jbyteArray>(jobj_value_part);
699 const jsize jvalue_part_len = env->GetArrayLength(jba_value_part);
11fdf7f2
TL
700 jbyte* jvalue_part = env->GetByteArrayElements(jba_value_part, nullptr);
701 if (jvalue_part == nullptr) {
702 // exception thrown: OutOfMemoryError
11fdf7f2
TL
703 env->DeleteLocalRef(jobj_value_part);
704 env->DeleteLocalRef(jobj_key_part);
20effc67 705 env->ReleaseByteArrayElements(jba_key_part, jkey_part, JNI_ABORT);
11fdf7f2
TL
706 free_parts(env, jparts_to_free);
707 return;
708 }
709
710 jparts_to_free.push_back(
711 std::make_tuple(jba_key_part, jkey_part, jobj_key_part));
712 jparts_to_free.push_back(
713 std::make_tuple(jba_value_part, jvalue_part, jobj_value_part));
714
f67539c2
TL
715 key_parts.push_back(ROCKSDB_NAMESPACE::Slice(
716 reinterpret_cast<char*>(jkey_part), jkey_part_len));
717 value_parts.push_back(ROCKSDB_NAMESPACE::Slice(
718 reinterpret_cast<char*>(jvalue_part), jvalue_part_len));
11fdf7f2
TL
719 }
720
721 // call the write_multi function
f67539c2
TL
722 ROCKSDB_NAMESPACE::Status s = fn_write_kv_parts(
723 ROCKSDB_NAMESPACE::SliceParts(key_parts.data(), (int)key_parts.size()),
724 ROCKSDB_NAMESPACE::SliceParts(value_parts.data(),
725 (int)value_parts.size()));
11fdf7f2
TL
726
727 // cleanup temporary memory
728 free_parts(env, jparts_to_free);
729
730 // return
731 if (s.ok()) {
732 return;
733 }
734
f67539c2 735 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
736}
737
738/*
739 * Class: org_rocksdb_Transaction
740 * Method: put
494da23a 741 * Signature: (J[[BI[[BIJZ)V
11fdf7f2 742 */
494da23a 743void Java_org_rocksdb_Transaction_put__J_3_3BI_3_3BIJZ(
11fdf7f2
TL
744 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
745 jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len,
494da23a 746 jlong jcolumn_family_handle, jboolean jassume_tracked) {
f67539c2 747 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 748 auto* column_family_handle =
f67539c2
TL
749 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
750 jcolumn_family_handle);
11fdf7f2 751 FnWriteKVParts fn_put_parts =
f67539c2
TL
752 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
753 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
754 const ROCKSDB_NAMESPACE::SliceParts&,
755 const ROCKSDB_NAMESPACE::SliceParts&, bool)>(
1e59de90
TL
756 &ROCKSDB_NAMESPACE::Transaction::Put, txn, column_family_handle,
757 std::placeholders::_1, std::placeholders::_2, jassume_tracked);
11fdf7f2
TL
758 txn_write_kv_parts_helper(env, fn_put_parts, jkey_parts, jkey_parts_len,
759 jvalue_parts, jvalue_parts_len);
760}
761
762/*
763 * Class: org_rocksdb_Transaction
764 * Method: put
765 * Signature: (J[[BI[[BI)V
766 */
767void Java_org_rocksdb_Transaction_put__J_3_3BI_3_3BI(
768 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
769 jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len) {
f67539c2
TL
770 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
771 FnWriteKVParts fn_put_parts = std::bind<ROCKSDB_NAMESPACE::Status (
772 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::SliceParts&,
773 const ROCKSDB_NAMESPACE::SliceParts&)>(
1e59de90
TL
774 &ROCKSDB_NAMESPACE::Transaction::Put, txn, std::placeholders::_1,
775 std::placeholders::_2);
11fdf7f2
TL
776 txn_write_kv_parts_helper(env, fn_put_parts, jkey_parts, jkey_parts_len,
777 jvalue_parts, jvalue_parts_len);
778}
779
780/*
781 * Class: org_rocksdb_Transaction
782 * Method: merge
494da23a 783 * Signature: (J[BI[BIJZ)V
11fdf7f2 784 */
494da23a 785void Java_org_rocksdb_Transaction_merge__J_3BI_3BIJZ(
11fdf7f2
TL
786 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
787 jint jkey_part_len, jbyteArray jval, jint jval_len,
494da23a 788 jlong jcolumn_family_handle, jboolean jassume_tracked) {
f67539c2 789 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 790 auto* column_family_handle =
f67539c2
TL
791 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
792 jcolumn_family_handle);
793 FnWriteKV fn_merge =
794 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
795 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
796 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&,
797 bool)>(&ROCKSDB_NAMESPACE::Transaction::Merge, txn,
1e59de90
TL
798 column_family_handle, std::placeholders::_1,
799 std::placeholders::_2, jassume_tracked);
11fdf7f2
TL
800 txn_write_kv_helper(env, fn_merge, jkey, jkey_part_len, jval, jval_len);
801}
802
803/*
804 * Class: org_rocksdb_Transaction
805 * Method: merge
806 * Signature: (J[BI[BI)V
807 */
808void Java_org_rocksdb_Transaction_merge__J_3BI_3BI(
809 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
810 jint jkey_part_len, jbyteArray jval, jint jval_len) {
f67539c2
TL
811 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
812 FnWriteKV fn_merge =
813 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
814 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90
TL
815 &ROCKSDB_NAMESPACE::Transaction::Merge, txn, std::placeholders::_1,
816 std::placeholders::_2);
11fdf7f2
TL
817 txn_write_kv_helper(env, fn_merge, jkey, jkey_part_len, jval, jval_len);
818}
819
f67539c2
TL
820typedef std::function<ROCKSDB_NAMESPACE::Status(
821 const ROCKSDB_NAMESPACE::Slice&)>
822 FnWriteK;
11fdf7f2
TL
823
824// TODO(AR) consider refactoring to share this between here and rocksjni.cc
825void txn_write_k_helper(JNIEnv* env, const FnWriteK& fn_write_k,
826 const jbyteArray& jkey, const jint& jkey_part_len) {
827 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
828 if (key == nullptr) {
829 // exception thrown: OutOfMemoryError
830 return;
831 }
f67539c2
TL
832 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
833 jkey_part_len);
11fdf7f2 834
f67539c2 835 ROCKSDB_NAMESPACE::Status s = fn_write_k(key_slice);
11fdf7f2
TL
836
837 // trigger java unref on key.
838 // by passing JNI_ABORT, it will simply release the reference without
839 // copying the result back to the java byte array.
840 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
841
842 if (s.ok()) {
843 return;
844 }
f67539c2 845 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
846}
847
848/*
849 * Class: org_rocksdb_Transaction
850 * Method: delete
494da23a 851 * Signature: (J[BIJZ)V
11fdf7f2 852 */
494da23a
TL
853void Java_org_rocksdb_Transaction_delete__J_3BIJZ(
854 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
855 jint jkey_part_len, jlong jcolumn_family_handle, jboolean jassume_tracked) {
f67539c2 856 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 857 auto* column_family_handle =
f67539c2
TL
858 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
859 jcolumn_family_handle);
860 FnWriteK fn_delete =
861 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
862 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
863 const ROCKSDB_NAMESPACE::Slice&, bool)>(
864 &ROCKSDB_NAMESPACE::Transaction::Delete, txn, column_family_handle,
1e59de90 865 std::placeholders::_1, jassume_tracked);
11fdf7f2
TL
866 txn_write_k_helper(env, fn_delete, jkey, jkey_part_len);
867}
868
869/*
870 * Class: org_rocksdb_Transaction
871 * Method: delete
872 * Signature: (J[BI)V
873 */
874void Java_org_rocksdb_Transaction_delete__J_3BI(JNIEnv* env, jobject /*jobj*/,
875 jlong jhandle, jbyteArray jkey,
876 jint jkey_part_len) {
f67539c2
TL
877 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
878 FnWriteK fn_delete = std::bind<ROCKSDB_NAMESPACE::Status (
879 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90 880 &ROCKSDB_NAMESPACE::Transaction::Delete, txn, std::placeholders::_1);
11fdf7f2
TL
881 txn_write_k_helper(env, fn_delete, jkey, jkey_part_len);
882}
883
f67539c2
TL
884typedef std::function<ROCKSDB_NAMESPACE::Status(
885 const ROCKSDB_NAMESPACE::SliceParts&)>
11fdf7f2
TL
886 FnWriteKParts;
887
888// TODO(AR) consider refactoring to share this between here and rocksjni.cc
889void txn_write_k_parts_helper(JNIEnv* env,
890 const FnWriteKParts& fn_write_k_parts,
891 const jobjectArray& jkey_parts,
892 const jint& jkey_parts_len) {
f67539c2 893 std::vector<ROCKSDB_NAMESPACE::Slice> key_parts;
11fdf7f2
TL
894 std::vector<std::tuple<jbyteArray, jbyte*, jobject>> jkey_parts_to_free;
895
896 // convert java key_parts byte[][] to Slice(s)
897 for (jint i = 0; i < jkey_parts_len; ++i) {
898 const jobject jobj_key_part = env->GetObjectArrayElement(jkey_parts, i);
899 if (env->ExceptionCheck()) {
900 // exception thrown: ArrayIndexOutOfBoundsException
901 free_parts(env, jkey_parts_to_free);
902 return;
903 }
904
905 const jbyteArray jba_key_part = reinterpret_cast<jbyteArray>(jobj_key_part);
906 const jsize jkey_part_len = env->GetArrayLength(jba_key_part);
11fdf7f2
TL
907 jbyte* jkey_part = env->GetByteArrayElements(jba_key_part, nullptr);
908 if (jkey_part == nullptr) {
909 // exception thrown: OutOfMemoryError
910 env->DeleteLocalRef(jobj_key_part);
911 free_parts(env, jkey_parts_to_free);
912 return;
913 }
914
915 jkey_parts_to_free.push_back(std::tuple<jbyteArray, jbyte*, jobject>(
916 jba_key_part, jkey_part, jobj_key_part));
917
f67539c2
TL
918 key_parts.push_back(ROCKSDB_NAMESPACE::Slice(
919 reinterpret_cast<char*>(jkey_part), jkey_part_len));
11fdf7f2
TL
920 }
921
922 // call the write_multi function
f67539c2
TL
923 ROCKSDB_NAMESPACE::Status s = fn_write_k_parts(
924 ROCKSDB_NAMESPACE::SliceParts(key_parts.data(), (int)key_parts.size()));
11fdf7f2
TL
925
926 // cleanup temporary memory
927 free_parts(env, jkey_parts_to_free);
928
929 // return
930 if (s.ok()) {
931 return;
932 }
f67539c2 933 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
934}
935
936/*
937 * Class: org_rocksdb_Transaction
938 * Method: delete
494da23a 939 * Signature: (J[[BIJZ)V
11fdf7f2 940 */
494da23a 941void Java_org_rocksdb_Transaction_delete__J_3_3BIJZ(
11fdf7f2 942 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
494da23a
TL
943 jint jkey_parts_len, jlong jcolumn_family_handle,
944 jboolean jassume_tracked) {
f67539c2 945 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 946 auto* column_family_handle =
f67539c2
TL
947 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
948 jcolumn_family_handle);
11fdf7f2 949 FnWriteKParts fn_delete_parts =
f67539c2
TL
950 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
951 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
952 const ROCKSDB_NAMESPACE::SliceParts&, bool)>(
953 &ROCKSDB_NAMESPACE::Transaction::Delete, txn, column_family_handle,
1e59de90 954 std::placeholders::_1, jassume_tracked);
11fdf7f2
TL
955 txn_write_k_parts_helper(env, fn_delete_parts, jkey_parts, jkey_parts_len);
956}
957
958/*
959 * Class: org_rocksdb_Transaction
960 * Method: delete
961 * Signature: (J[[BI)V
962 */
963void Java_org_rocksdb_Transaction_delete__J_3_3BI(JNIEnv* env, jobject /*jobj*/,
964 jlong jhandle,
965 jobjectArray jkey_parts,
966 jint jkey_parts_len) {
f67539c2
TL
967 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
968 FnWriteKParts fn_delete_parts = std::bind<ROCKSDB_NAMESPACE::Status (
969 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::SliceParts&)>(
1e59de90 970 &ROCKSDB_NAMESPACE::Transaction::Delete, txn, std::placeholders::_1);
11fdf7f2
TL
971 txn_write_k_parts_helper(env, fn_delete_parts, jkey_parts, jkey_parts_len);
972}
973
974/*
975 * Class: org_rocksdb_Transaction
976 * Method: singleDelete
494da23a 977 * Signature: (J[BIJZ)V
11fdf7f2 978 */
494da23a 979void Java_org_rocksdb_Transaction_singleDelete__J_3BIJZ(
11fdf7f2 980 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
494da23a 981 jint jkey_part_len, jlong jcolumn_family_handle, jboolean jassume_tracked) {
f67539c2 982 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 983 auto* column_family_handle =
f67539c2
TL
984 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
985 jcolumn_family_handle);
11fdf7f2 986 FnWriteK fn_single_delete =
f67539c2
TL
987 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
988 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
989 const ROCKSDB_NAMESPACE::Slice&, bool)>(
990 &ROCKSDB_NAMESPACE::Transaction::SingleDelete, txn,
1e59de90 991 column_family_handle, std::placeholders::_1, jassume_tracked);
11fdf7f2
TL
992 txn_write_k_helper(env, fn_single_delete, jkey, jkey_part_len);
993}
994
995/*
996 * Class: org_rocksdb_Transaction
997 * Method: singleDelete
998 * Signature: (J[BI)V
999 */
1000void Java_org_rocksdb_Transaction_singleDelete__J_3BI(JNIEnv* env,
1001 jobject /*jobj*/,
1002 jlong jhandle,
1003 jbyteArray jkey,
1004 jint jkey_part_len) {
f67539c2
TL
1005 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1006 FnWriteK fn_single_delete = std::bind<ROCKSDB_NAMESPACE::Status (
1007 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90
TL
1008 &ROCKSDB_NAMESPACE::Transaction::SingleDelete, txn,
1009 std::placeholders::_1);
11fdf7f2
TL
1010 txn_write_k_helper(env, fn_single_delete, jkey, jkey_part_len);
1011}
1012
1013/*
1014 * Class: org_rocksdb_Transaction
1015 * Method: singleDelete
494da23a 1016 * Signature: (J[[BIJZ)V
11fdf7f2 1017 */
494da23a 1018void Java_org_rocksdb_Transaction_singleDelete__J_3_3BIJZ(
11fdf7f2 1019 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
494da23a
TL
1020 jint jkey_parts_len, jlong jcolumn_family_handle,
1021 jboolean jassume_tracked) {
f67539c2 1022 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1023 auto* column_family_handle =
f67539c2
TL
1024 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1025 jcolumn_family_handle);
11fdf7f2 1026 FnWriteKParts fn_single_delete_parts =
f67539c2
TL
1027 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1028 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
1029 const ROCKSDB_NAMESPACE::SliceParts&, bool)>(
1030 &ROCKSDB_NAMESPACE::Transaction::SingleDelete, txn,
1e59de90 1031 column_family_handle, std::placeholders::_1, jassume_tracked);
11fdf7f2
TL
1032 txn_write_k_parts_helper(env, fn_single_delete_parts, jkey_parts,
1033 jkey_parts_len);
1034}
1035
1036/*
1037 * Class: org_rocksdb_Transaction
1038 * Method: singleDelete
1039 * Signature: (J[[BI)V
1040 */
1041void Java_org_rocksdb_Transaction_singleDelete__J_3_3BI(JNIEnv* env,
1042 jobject /*jobj*/,
1043 jlong jhandle,
1044 jobjectArray jkey_parts,
1045 jint jkey_parts_len) {
f67539c2
TL
1046 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1047 FnWriteKParts fn_single_delete_parts = std::bind<ROCKSDB_NAMESPACE::Status (
1048 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::SliceParts&)>(
1e59de90
TL
1049 &ROCKSDB_NAMESPACE::Transaction::SingleDelete, txn,
1050 std::placeholders::_1);
11fdf7f2
TL
1051 txn_write_k_parts_helper(env, fn_single_delete_parts, jkey_parts,
1052 jkey_parts_len);
1053}
1054
1055/*
1056 * Class: org_rocksdb_Transaction
1057 * Method: putUntracked
1058 * Signature: (J[BI[BIJ)V
1059 */
1060void Java_org_rocksdb_Transaction_putUntracked__J_3BI_3BIJ(
1061 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
1062 jint jkey_part_len, jbyteArray jval, jint jval_len,
1063 jlong jcolumn_family_handle) {
f67539c2 1064 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1065 auto* column_family_handle =
f67539c2
TL
1066 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1067 jcolumn_family_handle);
1068 FnWriteKV fn_put_untracked =
1069 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1070 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
1071 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>(
1072 &ROCKSDB_NAMESPACE::Transaction::PutUntracked, txn,
1e59de90 1073 column_family_handle, std::placeholders::_1, std::placeholders::_2);
11fdf7f2
TL
1074 txn_write_kv_helper(env, fn_put_untracked, jkey, jkey_part_len, jval,
1075 jval_len);
1076}
1077
1078/*
1079 * Class: org_rocksdb_Transaction
1080 * Method: putUntracked
1081 * Signature: (J[BI[BI)V
1082 */
1083void Java_org_rocksdb_Transaction_putUntracked__J_3BI_3BI(
1084 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
1085 jint jkey_part_len, jbyteArray jval, jint jval_len) {
f67539c2
TL
1086 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1087 FnWriteKV fn_put_untracked =
1088 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1089 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90
TL
1090 &ROCKSDB_NAMESPACE::Transaction::PutUntracked, txn,
1091 std::placeholders::_1, std::placeholders::_2);
11fdf7f2
TL
1092 txn_write_kv_helper(env, fn_put_untracked, jkey, jkey_part_len, jval,
1093 jval_len);
1094}
1095
1096/*
1097 * Class: org_rocksdb_Transaction
1098 * Method: putUntracked
1099 * Signature: (J[[BI[[BIJ)V
1100 */
1101void Java_org_rocksdb_Transaction_putUntracked__J_3_3BI_3_3BIJ(
1102 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
1103 jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len,
1104 jlong jcolumn_family_handle) {
f67539c2 1105 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1106 auto* column_family_handle =
f67539c2
TL
1107 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1108 jcolumn_family_handle);
1109 FnWriteKVParts fn_put_parts_untracked = std::bind<ROCKSDB_NAMESPACE::Status (
1110 ROCKSDB_NAMESPACE::Transaction::*)(ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
1111 const ROCKSDB_NAMESPACE::SliceParts&,
1112 const ROCKSDB_NAMESPACE::SliceParts&)>(
1113 &ROCKSDB_NAMESPACE::Transaction::PutUntracked, txn, column_family_handle,
1e59de90 1114 std::placeholders::_1, std::placeholders::_2);
11fdf7f2
TL
1115 txn_write_kv_parts_helper(env, fn_put_parts_untracked, jkey_parts,
1116 jkey_parts_len, jvalue_parts, jvalue_parts_len);
1117}
1118
1119/*
1120 * Class: org_rocksdb_Transaction
1121 * Method: putUntracked
1122 * Signature: (J[[BI[[BI)V
1123 */
1124void Java_org_rocksdb_Transaction_putUntracked__J_3_3BI_3_3BI(
1125 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
1126 jint jkey_parts_len, jobjectArray jvalue_parts, jint jvalue_parts_len) {
f67539c2
TL
1127 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1128 FnWriteKVParts fn_put_parts_untracked = std::bind<ROCKSDB_NAMESPACE::Status (
1129 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::SliceParts&,
1130 const ROCKSDB_NAMESPACE::SliceParts&)>(
1e59de90
TL
1131 &ROCKSDB_NAMESPACE::Transaction::PutUntracked, txn, std::placeholders::_1,
1132 std::placeholders::_2);
11fdf7f2
TL
1133 txn_write_kv_parts_helper(env, fn_put_parts_untracked, jkey_parts,
1134 jkey_parts_len, jvalue_parts, jvalue_parts_len);
1135}
1136
1137/*
1138 * Class: org_rocksdb_Transaction
1139 * Method: mergeUntracked
1140 * Signature: (J[BI[BIJ)V
1141 */
1142void Java_org_rocksdb_Transaction_mergeUntracked__J_3BI_3BIJ(
1143 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
1144 jint jkey_part_len, jbyteArray jval, jint jval_len,
1145 jlong jcolumn_family_handle) {
f67539c2 1146 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1147 auto* column_family_handle =
f67539c2
TL
1148 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1149 jcolumn_family_handle);
1150 FnWriteKV fn_merge_untracked =
1151 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1152 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
1153 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>(
1154 &ROCKSDB_NAMESPACE::Transaction::MergeUntracked, txn,
1e59de90 1155 column_family_handle, std::placeholders::_1, std::placeholders::_2);
11fdf7f2
TL
1156 txn_write_kv_helper(env, fn_merge_untracked, jkey, jkey_part_len, jval,
1157 jval_len);
1158}
1159
1160/*
1161 * Class: org_rocksdb_Transaction
1162 * Method: mergeUntracked
1163 * Signature: (J[BI[BI)V
1164 */
1165void Java_org_rocksdb_Transaction_mergeUntracked__J_3BI_3BI(
1166 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
1167 jint jkey_part_len, jbyteArray jval, jint jval_len) {
f67539c2
TL
1168 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1169 FnWriteKV fn_merge_untracked =
1170 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1171 const ROCKSDB_NAMESPACE::Slice&, const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90
TL
1172 &ROCKSDB_NAMESPACE::Transaction::MergeUntracked, txn,
1173 std::placeholders::_1, std::placeholders::_2);
11fdf7f2
TL
1174 txn_write_kv_helper(env, fn_merge_untracked, jkey, jkey_part_len, jval,
1175 jval_len);
1176}
1177
1178/*
1179 * Class: org_rocksdb_Transaction
1180 * Method: deleteUntracked
1181 * Signature: (J[BIJ)V
1182 */
1183void Java_org_rocksdb_Transaction_deleteUntracked__J_3BIJ(
1184 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
1185 jint jkey_part_len, jlong jcolumn_family_handle) {
f67539c2 1186 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1187 auto* column_family_handle =
f67539c2
TL
1188 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1189 jcolumn_family_handle);
1190 FnWriteK fn_delete_untracked = std::bind<ROCKSDB_NAMESPACE::Status (
1191 ROCKSDB_NAMESPACE::Transaction::*)(ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
1192 const ROCKSDB_NAMESPACE::Slice&)>(
1193 &ROCKSDB_NAMESPACE::Transaction::DeleteUntracked, txn,
1e59de90 1194 column_family_handle, std::placeholders::_1);
11fdf7f2
TL
1195 txn_write_k_helper(env, fn_delete_untracked, jkey, jkey_part_len);
1196}
1197
1198/*
1199 * Class: org_rocksdb_Transaction
1200 * Method: deleteUntracked
1201 * Signature: (J[BI)V
1202 */
1203void Java_org_rocksdb_Transaction_deleteUntracked__J_3BI(JNIEnv* env,
1204 jobject /*jobj*/,
1205 jlong jhandle,
1206 jbyteArray jkey,
1207 jint jkey_part_len) {
f67539c2
TL
1208 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1209 FnWriteK fn_delete_untracked = std::bind<ROCKSDB_NAMESPACE::Status (
1210 ROCKSDB_NAMESPACE::Transaction::*)(const ROCKSDB_NAMESPACE::Slice&)>(
1e59de90
TL
1211 &ROCKSDB_NAMESPACE::Transaction::DeleteUntracked, txn,
1212 std::placeholders::_1);
11fdf7f2
TL
1213 txn_write_k_helper(env, fn_delete_untracked, jkey, jkey_part_len);
1214}
1215
1216/*
1217 * Class: org_rocksdb_Transaction
1218 * Method: deleteUntracked
1219 * Signature: (J[[BIJ)V
1220 */
1221void Java_org_rocksdb_Transaction_deleteUntracked__J_3_3BIJ(
1222 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
1223 jint jkey_parts_len, jlong jcolumn_family_handle) {
f67539c2 1224 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1225 auto* column_family_handle =
f67539c2
TL
1226 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1227 jcolumn_family_handle);
11fdf7f2 1228 FnWriteKParts fn_delete_untracked_parts =
f67539c2
TL
1229 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1230 ROCKSDB_NAMESPACE::ColumnFamilyHandle*,
1231 const ROCKSDB_NAMESPACE::SliceParts&)>(
1232 &ROCKSDB_NAMESPACE::Transaction::DeleteUntracked, txn,
1e59de90 1233 column_family_handle, std::placeholders::_1);
11fdf7f2
TL
1234 txn_write_k_parts_helper(env, fn_delete_untracked_parts, jkey_parts,
1235 jkey_parts_len);
1236}
1237
1238/*
1239 * Class: org_rocksdb_Transaction
1240 * Method: deleteUntracked
1241 * Signature: (J[[BI)V
1242 */
1243void Java_org_rocksdb_Transaction_deleteUntracked__J_3_3BI(
1244 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jobjectArray jkey_parts,
1245 jint jkey_parts_len) {
f67539c2
TL
1246 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1247 FnWriteKParts fn_delete_untracked_parts =
1248 std::bind<ROCKSDB_NAMESPACE::Status (ROCKSDB_NAMESPACE::Transaction::*)(
1249 const ROCKSDB_NAMESPACE::SliceParts&)>(
1e59de90
TL
1250 &ROCKSDB_NAMESPACE::Transaction::DeleteUntracked, txn,
1251 std::placeholders::_1);
11fdf7f2
TL
1252 txn_write_k_parts_helper(env, fn_delete_untracked_parts, jkey_parts,
1253 jkey_parts_len);
1254}
1255
1256/*
1257 * Class: org_rocksdb_Transaction
1258 * Method: putLogData
1259 * Signature: (J[BI)V
1260 */
1261void Java_org_rocksdb_Transaction_putLogData(JNIEnv* env, jobject /*jobj*/,
1262 jlong jhandle, jbyteArray jkey,
1263 jint jkey_part_len) {
f67539c2 1264 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1265
1266 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
1267 if (key == nullptr) {
1268 // exception thrown: OutOfMemoryError
1269 return;
1270 }
1271
f67539c2
TL
1272 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
1273 jkey_part_len);
11fdf7f2
TL
1274 txn->PutLogData(key_slice);
1275
1276 // trigger java unref on key.
1277 // by passing JNI_ABORT, it will simply release the reference without
1278 // copying the result back to the java byte array.
1279 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
1280}
1281
1282/*
1283 * Class: org_rocksdb_Transaction
1284 * Method: disableIndexing
1285 * Signature: (J)V
1286 */
1287void Java_org_rocksdb_Transaction_disableIndexing(JNIEnv* /*env*/,
1288 jobject /*jobj*/,
1289 jlong jhandle) {
f67539c2 1290 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1291 txn->DisableIndexing();
1292}
1293
1294/*
1295 * Class: org_rocksdb_Transaction
1296 * Method: enableIndexing
1297 * Signature: (J)V
1298 */
1299void Java_org_rocksdb_Transaction_enableIndexing(JNIEnv* /*env*/,
1300 jobject /*jobj*/,
1301 jlong jhandle) {
f67539c2 1302 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1303 txn->EnableIndexing();
1304}
1305
1306/*
1307 * Class: org_rocksdb_Transaction
1308 * Method: getNumKeys
1309 * Signature: (J)J
1310 */
1311jlong Java_org_rocksdb_Transaction_getNumKeys(JNIEnv* /*env*/, jobject /*jobj*/,
1312 jlong jhandle) {
f67539c2 1313 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1314 return txn->GetNumKeys();
1315}
1316
1317/*
1318 * Class: org_rocksdb_Transaction
1319 * Method: getNumPuts
1320 * Signature: (J)J
1321 */
1322jlong Java_org_rocksdb_Transaction_getNumPuts(JNIEnv* /*env*/, jobject /*jobj*/,
1323 jlong jhandle) {
f67539c2 1324 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1325 return txn->GetNumPuts();
1326}
1327
1328/*
1329 * Class: org_rocksdb_Transaction
1330 * Method: getNumDeletes
1331 * Signature: (J)J
1332 */
1333jlong Java_org_rocksdb_Transaction_getNumDeletes(JNIEnv* /*env*/,
1334 jobject /*jobj*/,
1335 jlong jhandle) {
f67539c2 1336 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1337 return txn->GetNumDeletes();
1338}
1339
1340/*
1341 * Class: org_rocksdb_Transaction
1342 * Method: getNumMerges
1343 * Signature: (J)J
1344 */
1345jlong Java_org_rocksdb_Transaction_getNumMerges(JNIEnv* /*env*/,
1346 jobject /*jobj*/,
1347 jlong jhandle) {
f67539c2 1348 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1349 return txn->GetNumMerges();
1350}
1351
1352/*
1353 * Class: org_rocksdb_Transaction
1354 * Method: getElapsedTime
1355 * Signature: (J)J
1356 */
1357jlong Java_org_rocksdb_Transaction_getElapsedTime(JNIEnv* /*env*/,
1358 jobject /*jobj*/,
1359 jlong jhandle) {
f67539c2 1360 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1361 return txn->GetElapsedTime();
1362}
1363
1364/*
1365 * Class: org_rocksdb_Transaction
1366 * Method: getWriteBatch
1367 * Signature: (J)J
1368 */
1369jlong Java_org_rocksdb_Transaction_getWriteBatch(JNIEnv* /*env*/,
1370 jobject /*jobj*/,
1371 jlong jhandle) {
f67539c2 1372 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1e59de90 1373 return GET_CPLUSPLUS_POINTER(txn->GetWriteBatch());
11fdf7f2
TL
1374}
1375
1376/*
1377 * Class: org_rocksdb_Transaction
1378 * Method: setLockTimeout
1379 * Signature: (JJ)V
1380 */
1381void Java_org_rocksdb_Transaction_setLockTimeout(JNIEnv* /*env*/,
1382 jobject /*jobj*/,
1383 jlong jhandle,
1384 jlong jlock_timeout) {
f67539c2 1385 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1386 txn->SetLockTimeout(jlock_timeout);
1387}
1388
1389/*
1390 * Class: org_rocksdb_Transaction
1391 * Method: getWriteOptions
1392 * Signature: (J)J
1393 */
1394jlong Java_org_rocksdb_Transaction_getWriteOptions(JNIEnv* /*env*/,
1395 jobject /*jobj*/,
1396 jlong jhandle) {
f67539c2 1397 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1e59de90 1398 return GET_CPLUSPLUS_POINTER(txn->GetWriteOptions());
11fdf7f2
TL
1399}
1400
1401/*
1402 * Class: org_rocksdb_Transaction
1403 * Method: setWriteOptions
1404 * Signature: (JJ)V
1405 */
1406void Java_org_rocksdb_Transaction_setWriteOptions(JNIEnv* /*env*/,
1407 jobject /*jobj*/,
1408 jlong jhandle,
1409 jlong jwrite_options_handle) {
f67539c2 1410 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1411 auto* write_options =
f67539c2 1412 reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
11fdf7f2
TL
1413 txn->SetWriteOptions(*write_options);
1414}
1415
1416/*
1417 * Class: org_rocksdb_Transaction
1418 * Method: undo
1419 * Signature: (J[BIJ)V
1420 */
1421void Java_org_rocksdb_Transaction_undoGetForUpdate__J_3BIJ(
1422 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jbyteArray jkey,
1423 jint jkey_part_len, jlong jcolumn_family_handle) {
f67539c2 1424 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1425 auto* column_family_handle =
f67539c2
TL
1426 reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyHandle*>(
1427 jcolumn_family_handle);
11fdf7f2
TL
1428 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
1429 if (key == nullptr) {
1430 // exception thrown: OutOfMemoryError
1431 return;
1432 }
1433
f67539c2
TL
1434 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
1435 jkey_part_len);
11fdf7f2
TL
1436 txn->UndoGetForUpdate(column_family_handle, key_slice);
1437
1438 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
1439}
1440
1441/*
1442 * Class: org_rocksdb_Transaction
1443 * Method: undoGetForUpdate
1444 * Signature: (J[BI)V
1445 */
1446void Java_org_rocksdb_Transaction_undoGetForUpdate__J_3BI(JNIEnv* env,
1447 jobject /*jobj*/,
1448 jlong jhandle,
1449 jbyteArray jkey,
1450 jint jkey_part_len) {
f67539c2 1451 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1452 jbyte* key = env->GetByteArrayElements(jkey, nullptr);
1453 if (key == nullptr) {
1454 // exception thrown: OutOfMemoryError
1455 return;
1456 }
1457
f67539c2
TL
1458 ROCKSDB_NAMESPACE::Slice key_slice(reinterpret_cast<char*>(key),
1459 jkey_part_len);
11fdf7f2
TL
1460 txn->UndoGetForUpdate(key_slice);
1461
1462 env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
1463}
1464
1465/*
1466 * Class: org_rocksdb_Transaction
1467 * Method: rebuildFromWriteBatch
1468 * Signature: (JJ)V
1469 */
1470void Java_org_rocksdb_Transaction_rebuildFromWriteBatch(
1471 JNIEnv* env, jobject /*jobj*/, jlong jhandle, jlong jwrite_batch_handle) {
f67539c2 1472 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1473 auto* write_batch =
f67539c2
TL
1474 reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwrite_batch_handle);
1475 ROCKSDB_NAMESPACE::Status s = txn->RebuildFromWriteBatch(write_batch);
11fdf7f2 1476 if (!s.ok()) {
f67539c2 1477 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
1478 }
1479}
1480
1481/*
1482 * Class: org_rocksdb_Transaction
1483 * Method: getCommitTimeWriteBatch
1484 * Signature: (J)J
1485 */
1486jlong Java_org_rocksdb_Transaction_getCommitTimeWriteBatch(JNIEnv* /*env*/,
1487 jobject /*jobj*/,
1488 jlong jhandle) {
f67539c2 1489 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1e59de90 1490 return GET_CPLUSPLUS_POINTER(txn->GetCommitTimeWriteBatch());
11fdf7f2
TL
1491}
1492
1493/*
1494 * Class: org_rocksdb_Transaction
1495 * Method: setLogNumber
1496 * Signature: (JJ)V
1497 */
1498void Java_org_rocksdb_Transaction_setLogNumber(JNIEnv* /*env*/,
1499 jobject /*jobj*/, jlong jhandle,
1500 jlong jlog_number) {
f67539c2 1501 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1502 txn->SetLogNumber(jlog_number);
1503}
1504
1505/*
1506 * Class: org_rocksdb_Transaction
1507 * Method: getLogNumber
1508 * Signature: (J)J
1509 */
1510jlong Java_org_rocksdb_Transaction_getLogNumber(JNIEnv* /*env*/,
1511 jobject /*jobj*/,
1512 jlong jhandle) {
f67539c2 1513 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1514 return txn->GetLogNumber();
1515}
1516
1517/*
1518 * Class: org_rocksdb_Transaction
1519 * Method: setName
1520 * Signature: (JLjava/lang/String;)V
1521 */
1522void Java_org_rocksdb_Transaction_setName(JNIEnv* env, jobject /*jobj*/,
1523 jlong jhandle, jstring jname) {
f67539c2 1524 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1525 const char* name = env->GetStringUTFChars(jname, nullptr);
1526 if (name == nullptr) {
1527 // exception thrown: OutOfMemoryError
1528 return;
1529 }
1530
f67539c2 1531 ROCKSDB_NAMESPACE::Status s = txn->SetName(name);
11fdf7f2
TL
1532
1533 env->ReleaseStringUTFChars(jname, name);
1534
1535 if (!s.ok()) {
f67539c2 1536 ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
11fdf7f2
TL
1537 }
1538}
1539
1540/*
1541 * Class: org_rocksdb_Transaction
1542 * Method: getName
1543 * Signature: (J)Ljava/lang/String;
1544 */
1545jstring Java_org_rocksdb_Transaction_getName(JNIEnv* env, jobject /*jobj*/,
1546 jlong jhandle) {
f67539c2
TL
1547 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1548 ROCKSDB_NAMESPACE::TransactionName name = txn->GetName();
11fdf7f2
TL
1549 return env->NewStringUTF(name.data());
1550}
1551
1552/*
1553 * Class: org_rocksdb_Transaction
1554 * Method: getID
1555 * Signature: (J)J
1556 */
1557jlong Java_org_rocksdb_Transaction_getID(JNIEnv* /*env*/, jobject /*jobj*/,
1558 jlong jhandle) {
f67539c2
TL
1559 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1560 ROCKSDB_NAMESPACE::TransactionID id = txn->GetID();
11fdf7f2
TL
1561 return static_cast<jlong>(id);
1562}
1563
1564/*
1565 * Class: org_rocksdb_Transaction
1566 * Method: isDeadlockDetect
1567 * Signature: (J)Z
1568 */
1569jboolean Java_org_rocksdb_Transaction_isDeadlockDetect(JNIEnv* /*env*/,
1570 jobject /*jobj*/,
1571 jlong jhandle) {
f67539c2 1572 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1573 return static_cast<jboolean>(txn->IsDeadlockDetect());
1574}
1575
1576/*
1577 * Class: org_rocksdb_Transaction
1578 * Method: getWaitingTxns
1579 * Signature: (J)Lorg/rocksdb/Transaction/WaitingTransactions;
1580 */
1581jobject Java_org_rocksdb_Transaction_getWaitingTxns(JNIEnv* env,
1582 jobject jtransaction_obj,
1583 jlong jhandle) {
f67539c2 1584 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1585 uint32_t column_family_id;
1586 std::string key;
f67539c2 1587 std::vector<ROCKSDB_NAMESPACE::TransactionID> waiting_txns =
11fdf7f2 1588 txn->GetWaitingTxns(&column_family_id, &key);
f67539c2
TL
1589 jobject jwaiting_txns =
1590 ROCKSDB_NAMESPACE::TransactionJni::newWaitingTransactions(
1591 env, jtransaction_obj, column_family_id, key, waiting_txns);
11fdf7f2
TL
1592 return jwaiting_txns;
1593}
1594
1595/*
1596 * Class: org_rocksdb_Transaction
1597 * Method: getState
1598 * Signature: (J)B
1599 */
1600jbyte Java_org_rocksdb_Transaction_getState(JNIEnv* /*env*/, jobject /*jobj*/,
1601 jlong jhandle) {
f67539c2
TL
1602 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
1603 ROCKSDB_NAMESPACE::Transaction::TransactionState txn_status = txn->GetState();
11fdf7f2 1604 switch (txn_status) {
f67539c2 1605 case ROCKSDB_NAMESPACE::Transaction::TransactionState::STARTED:
11fdf7f2
TL
1606 return 0x0;
1607
f67539c2 1608 case ROCKSDB_NAMESPACE::Transaction::TransactionState::AWAITING_PREPARE:
11fdf7f2
TL
1609 return 0x1;
1610
f67539c2 1611 case ROCKSDB_NAMESPACE::Transaction::TransactionState::PREPARED:
11fdf7f2
TL
1612 return 0x2;
1613
f67539c2 1614 case ROCKSDB_NAMESPACE::Transaction::TransactionState::AWAITING_COMMIT:
11fdf7f2
TL
1615 return 0x3;
1616
20effc67 1617 case ROCKSDB_NAMESPACE::Transaction::TransactionState::COMMITTED:
11fdf7f2
TL
1618 return 0x4;
1619
f67539c2 1620 case ROCKSDB_NAMESPACE::Transaction::TransactionState::AWAITING_ROLLBACK:
11fdf7f2
TL
1621 return 0x5;
1622
f67539c2 1623 case ROCKSDB_NAMESPACE::Transaction::TransactionState::ROLLEDBACK:
11fdf7f2
TL
1624 return 0x6;
1625
f67539c2 1626 case ROCKSDB_NAMESPACE::Transaction::TransactionState::LOCKS_STOLEN:
11fdf7f2
TL
1627 return 0x7;
1628 }
1629
1630 assert(false);
1631 return static_cast<jbyte>(-1);
1632}
1633
1634/*
1635 * Class: org_rocksdb_Transaction
1636 * Method: getId
1637 * Signature: (J)J
1638 */
1639jlong Java_org_rocksdb_Transaction_getId(JNIEnv* /*env*/, jobject /*jobj*/,
1640 jlong jhandle) {
f67539c2 1641 auto* txn = reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2
TL
1642 uint64_t id = txn->GetId();
1643 return static_cast<jlong>(id);
1644}
1645
1646/*
1647 * Class: org_rocksdb_Transaction
1648 * Method: disposeInternal
1649 * Signature: (J)V
1650 */
1651void Java_org_rocksdb_Transaction_disposeInternal(JNIEnv* /*env*/,
1652 jobject /*jobj*/,
1653 jlong jhandle) {
f67539c2 1654 delete reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jhandle);
11fdf7f2 1655}