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