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).
6 // This file implements the "bridge" between Java and C++
7 // for rocksdb::TransactionDB.
11 #include "include/org_rocksdb_OptimisticTransactionDB.h"
13 #include "rocksdb/options.h"
14 #include "rocksdb/utilities/optimistic_transaction_db.h"
15 #include "rocksdb/utilities/transaction.h"
17 #include "rocksjni/portal.h"
20 * Class: org_rocksdb_OptimisticTransactionDB
22 * Signature: (JLjava/lang/String;)J
24 jlong
Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2(
25 JNIEnv
* env
, jclass
, jlong joptions_handle
, jstring jdb_path
) {
26 const char* db_path
= env
->GetStringUTFChars(jdb_path
, nullptr);
27 if (db_path
== nullptr) {
28 // exception thrown: OutOfMemoryError
32 auto* options
= reinterpret_cast<rocksdb::Options
*>(joptions_handle
);
33 rocksdb::OptimisticTransactionDB
* otdb
= nullptr;
35 rocksdb::OptimisticTransactionDB::Open(*options
, db_path
, &otdb
);
36 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
39 return reinterpret_cast<jlong
>(otdb
);
41 rocksdb::RocksDBExceptionJni::ThrowNew(env
, s
);
47 * Class: org_rocksdb_OptimisticTransactionDB
49 * Signature: (JLjava/lang/String;[[B[J)[J
52 Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2_3_3B_3J(
53 JNIEnv
* env
, jclass
, jlong jdb_options_handle
, jstring jdb_path
,
54 jobjectArray jcolumn_names
, jlongArray jcolumn_options_handles
) {
55 const char* db_path
= env
->GetStringUTFChars(jdb_path
, nullptr);
56 if (db_path
== nullptr) {
57 // exception thrown: OutOfMemoryError
61 std::vector
<rocksdb::ColumnFamilyDescriptor
> column_families
;
62 const jsize len_cols
= env
->GetArrayLength(jcolumn_names
);
64 if (env
->EnsureLocalCapacity(len_cols
) != 0) {
66 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
70 jlong
* jco
= env
->GetLongArrayElements(jcolumn_options_handles
, nullptr);
72 // exception thrown: OutOfMemoryError
73 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
77 for (int i
= 0; i
< len_cols
; i
++) {
78 const jobject jcn
= env
->GetObjectArrayElement(jcolumn_names
, i
);
79 if (env
->ExceptionCheck()) {
80 // exception thrown: ArrayIndexOutOfBoundsException
81 env
->ReleaseLongArrayElements(jcolumn_options_handles
, jco
, JNI_ABORT
);
82 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
86 const jbyteArray jcn_ba
= reinterpret_cast<jbyteArray
>(jcn
);
87 const jsize jcf_name_len
= env
->GetArrayLength(jcn_ba
);
88 if (env
->EnsureLocalCapacity(jcf_name_len
) != 0) {
90 env
->DeleteLocalRef(jcn
);
91 env
->ReleaseLongArrayElements(jcolumn_options_handles
, jco
, JNI_ABORT
);
92 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
96 jbyte
* jcf_name
= env
->GetByteArrayElements(jcn_ba
, nullptr);
97 if (jcf_name
== nullptr) {
98 // exception thrown: OutOfMemoryError
99 env
->DeleteLocalRef(jcn
);
100 env
->ReleaseLongArrayElements(jcolumn_options_handles
, jco
, JNI_ABORT
);
101 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
105 const std::string
cf_name(reinterpret_cast<char*>(jcf_name
),
107 const rocksdb::ColumnFamilyOptions
* cf_options
=
108 reinterpret_cast<rocksdb::ColumnFamilyOptions
*>(jco
[i
]);
109 column_families
.push_back(
110 rocksdb::ColumnFamilyDescriptor(cf_name
, *cf_options
));
112 env
->ReleaseByteArrayElements(jcn_ba
, jcf_name
, JNI_ABORT
);
113 env
->DeleteLocalRef(jcn
);
115 env
->ReleaseLongArrayElements(jcolumn_options_handles
, jco
, JNI_ABORT
);
118 auto* db_options
= reinterpret_cast<rocksdb::DBOptions
*>(jdb_options_handle
);
119 std::vector
<rocksdb::ColumnFamilyHandle
*> handles
;
120 rocksdb::OptimisticTransactionDB
* otdb
= nullptr;
121 const rocksdb::Status s
= rocksdb::OptimisticTransactionDB::Open(
122 *db_options
, db_path
, column_families
, &handles
, &otdb
);
124 env
->ReleaseStringUTFChars(jdb_path
, db_path
);
126 // check if open operation was successful
128 const jsize resultsLen
= 1 + len_cols
; // db handle + column family handles
129 std::unique_ptr
<jlong
[]> results
=
130 std::unique_ptr
<jlong
[]>(new jlong
[resultsLen
]);
131 results
[0] = reinterpret_cast<jlong
>(otdb
);
132 for (int i
= 1; i
<= len_cols
; i
++) {
133 results
[i
] = reinterpret_cast<jlong
>(handles
[i
- 1]);
136 jlongArray jresults
= env
->NewLongArray(resultsLen
);
137 if (jresults
== nullptr) {
138 // exception thrown: OutOfMemoryError
141 env
->SetLongArrayRegion(jresults
, 0, resultsLen
, results
.get());
142 if (env
->ExceptionCheck()) {
143 // exception thrown: ArrayIndexOutOfBoundsException
149 rocksdb::RocksDBExceptionJni::ThrowNew(env
, s
);
154 * Class: org_rocksdb_OptimisticTransactionDB
155 * Method: disposeInternal
158 void Java_org_rocksdb_OptimisticTransactionDB_disposeInternal(
159 JNIEnv
*, jobject
, jlong jhandle
) {
160 auto* optimistic_txn_db
=
161 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
162 assert(optimistic_txn_db
!= nullptr);
163 delete optimistic_txn_db
;
167 * Class: org_rocksdb_OptimisticTransactionDB
168 * Method: closeDatabase
171 void Java_org_rocksdb_OptimisticTransactionDB_closeDatabase(
172 JNIEnv
* env
, jclass
, jlong jhandle
) {
173 auto* optimistic_txn_db
=
174 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
175 assert(optimistic_txn_db
!= nullptr);
176 rocksdb::Status s
= optimistic_txn_db
->Close();
177 rocksdb::RocksDBExceptionJni::ThrowNew(env
, s
);
181 * Class: org_rocksdb_OptimisticTransactionDB
182 * Method: beginTransaction
185 jlong
Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJ(
186 JNIEnv
*, jobject
, jlong jhandle
, jlong jwrite_options_handle
) {
187 auto* optimistic_txn_db
=
188 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
189 auto* write_options
=
190 reinterpret_cast<rocksdb::WriteOptions
*>(jwrite_options_handle
);
191 rocksdb::Transaction
* txn
=
192 optimistic_txn_db
->BeginTransaction(*write_options
);
193 return reinterpret_cast<jlong
>(txn
);
197 * Class: org_rocksdb_OptimisticTransactionDB
198 * Method: beginTransaction
201 jlong
Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJJ(
202 JNIEnv
* /*env*/, jobject
/*jobj*/, jlong jhandle
,
203 jlong jwrite_options_handle
, jlong joptimistic_txn_options_handle
) {
204 auto* optimistic_txn_db
=
205 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
206 auto* write_options
=
207 reinterpret_cast<rocksdb::WriteOptions
*>(jwrite_options_handle
);
208 auto* optimistic_txn_options
=
209 reinterpret_cast<rocksdb::OptimisticTransactionOptions
*>(
210 joptimistic_txn_options_handle
);
211 rocksdb::Transaction
* txn
= optimistic_txn_db
->BeginTransaction(
212 *write_options
, *optimistic_txn_options
);
213 return reinterpret_cast<jlong
>(txn
);
217 * Class: org_rocksdb_OptimisticTransactionDB
218 * Method: beginTransaction_withOld
221 jlong
Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJ(
222 JNIEnv
*, jobject
, jlong jhandle
, jlong jwrite_options_handle
,
223 jlong jold_txn_handle
) {
224 auto* optimistic_txn_db
=
225 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
226 auto* write_options
=
227 reinterpret_cast<rocksdb::WriteOptions
*>(jwrite_options_handle
);
228 auto* old_txn
= reinterpret_cast<rocksdb::Transaction
*>(jold_txn_handle
);
229 rocksdb::OptimisticTransactionOptions optimistic_txn_options
;
230 rocksdb::Transaction
* txn
= optimistic_txn_db
->BeginTransaction(
231 *write_options
, optimistic_txn_options
, old_txn
);
233 // RocksJava relies on the assumption that
234 // we do not allocate a new Transaction object
235 // when providing an old_optimistic_txn
236 assert(txn
== old_txn
);
238 return reinterpret_cast<jlong
>(txn
);
242 * Class: org_rocksdb_OptimisticTransactionDB
243 * Method: beginTransaction_withOld
246 jlong
Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJJ(
247 JNIEnv
*, jobject
, jlong jhandle
, jlong jwrite_options_handle
,
248 jlong joptimistic_txn_options_handle
, jlong jold_txn_handle
) {
249 auto* optimistic_txn_db
=
250 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
251 auto* write_options
=
252 reinterpret_cast<rocksdb::WriteOptions
*>(jwrite_options_handle
);
253 auto* optimistic_txn_options
=
254 reinterpret_cast<rocksdb::OptimisticTransactionOptions
*>(
255 joptimistic_txn_options_handle
);
256 auto* old_txn
= reinterpret_cast<rocksdb::Transaction
*>(jold_txn_handle
);
257 rocksdb::Transaction
* txn
= optimistic_txn_db
->BeginTransaction(
258 *write_options
, *optimistic_txn_options
, old_txn
);
260 // RocksJava relies on the assumption that
261 // we do not allocate a new Transaction object
262 // when providing an old_optimisic_txn
263 assert(txn
== old_txn
);
265 return reinterpret_cast<jlong
>(txn
);
269 * Class: org_rocksdb_OptimisticTransactionDB
273 jlong
Java_org_rocksdb_OptimisticTransactionDB_getBaseDB(
274 JNIEnv
*, jobject
, jlong jhandle
) {
275 auto* optimistic_txn_db
=
276 reinterpret_cast<rocksdb::OptimisticTransactionDB
*>(jhandle
);
277 return reinterpret_cast<jlong
>(optimistic_txn_db
->GetBaseDB());