]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/java/rocksjni/optimistic_transaction_db.cc
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / java / rocksjni / optimistic_transaction_db.cc
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::TransactionDB.
8
9 #include <jni.h>
10
11 #include "include/org_rocksdb_OptimisticTransactionDB.h"
12
13 #include "rocksdb/options.h"
14 #include "rocksdb/utilities/optimistic_transaction_db.h"
15 #include "rocksdb/utilities/transaction.h"
16
17 #include "rocksjni/portal.h"
18
19 /*
20 * Class: org_rocksdb_OptimisticTransactionDB
21 * Method: open
22 * Signature: (JLjava/lang/String;)J
23 */
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
29 return 0;
30 }
31
32 auto* options = reinterpret_cast<rocksdb::Options*>(joptions_handle);
33 rocksdb::OptimisticTransactionDB* otdb = nullptr;
34 rocksdb::Status s =
35 rocksdb::OptimisticTransactionDB::Open(*options, db_path, &otdb);
36 env->ReleaseStringUTFChars(jdb_path, db_path);
37
38 if (s.ok()) {
39 return reinterpret_cast<jlong>(otdb);
40 } else {
41 rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
42 return 0;
43 }
44 }
45
46 /*
47 * Class: org_rocksdb_OptimisticTransactionDB
48 * Method: open
49 * Signature: (JLjava/lang/String;[[B[J)[J
50 */
51 jlongArray
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
58 return nullptr;
59 }
60
61 std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
62 const jsize len_cols = env->GetArrayLength(jcolumn_names);
63 if (len_cols > 0) {
64 if (env->EnsureLocalCapacity(len_cols) != 0) {
65 // out of memory
66 env->ReleaseStringUTFChars(jdb_path, db_path);
67 return nullptr;
68 }
69
70 jlong* jco = env->GetLongArrayElements(jcolumn_options_handles, nullptr);
71 if (jco == nullptr) {
72 // exception thrown: OutOfMemoryError
73 env->ReleaseStringUTFChars(jdb_path, db_path);
74 return nullptr;
75 }
76
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);
83 return nullptr;
84 }
85
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) {
89 // out of memory
90 env->DeleteLocalRef(jcn);
91 env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
92 env->ReleaseStringUTFChars(jdb_path, db_path);
93 return nullptr;
94 }
95
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);
102 return nullptr;
103 }
104
105 const std::string cf_name(reinterpret_cast<char*>(jcf_name),
106 jcf_name_len);
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));
111
112 env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
113 env->DeleteLocalRef(jcn);
114 }
115 env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
116 }
117
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);
123
124 env->ReleaseStringUTFChars(jdb_path, db_path);
125
126 // check if open operation was successful
127 if (s.ok()) {
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]);
134 }
135
136 jlongArray jresults = env->NewLongArray(resultsLen);
137 if (jresults == nullptr) {
138 // exception thrown: OutOfMemoryError
139 return nullptr;
140 }
141 env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
142 if (env->ExceptionCheck()) {
143 // exception thrown: ArrayIndexOutOfBoundsException
144 return nullptr;
145 }
146 return jresults;
147 }
148
149 rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
150 return nullptr;
151 }
152
153 /*
154 * Class: org_rocksdb_OptimisticTransactionDB
155 * Method: disposeInternal
156 * Signature: (J)V
157 */
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;
164 }
165
166 /*
167 * Class: org_rocksdb_OptimisticTransactionDB
168 * Method: closeDatabase
169 * Signature: (J)V
170 */
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);
178 }
179
180 /*
181 * Class: org_rocksdb_OptimisticTransactionDB
182 * Method: beginTransaction
183 * Signature: (JJ)J
184 */
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);
194 }
195
196 /*
197 * Class: org_rocksdb_OptimisticTransactionDB
198 * Method: beginTransaction
199 * Signature: (JJJ)J
200 */
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);
214 }
215
216 /*
217 * Class: org_rocksdb_OptimisticTransactionDB
218 * Method: beginTransaction_withOld
219 * Signature: (JJJ)J
220 */
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);
232
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);
237
238 return reinterpret_cast<jlong>(txn);
239 }
240
241 /*
242 * Class: org_rocksdb_OptimisticTransactionDB
243 * Method: beginTransaction_withOld
244 * Signature: (JJJJ)J
245 */
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);
259
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);
264
265 return reinterpret_cast<jlong>(txn);
266 }
267
268 /*
269 * Class: org_rocksdb_OptimisticTransactionDB
270 * Method: getBaseDB
271 * Signature: (J)J
272 */
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());
278 }