]>
Commit | Line | Data |
---|---|---|
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++ | |
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( | |
494da23a | 25 | JNIEnv* env, jclass, jlong joptions_handle, jstring jdb_path) { |
11fdf7f2 TL |
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( | |
494da23a | 53 | JNIEnv* env, jclass, jlong jdb_options_handle, jstring jdb_path, |
11fdf7f2 TL |
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 | ||
494da23a TL |
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 | ||
11fdf7f2 TL |
180 | /* |
181 | * Class: org_rocksdb_OptimisticTransactionDB | |
182 | * Method: beginTransaction | |
183 | * Signature: (JJ)J | |
184 | */ | |
185 | jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJ( | |
494da23a | 186 | JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle) { |
11fdf7f2 TL |
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( | |
494da23a TL |
222 | JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle, |
223 | jlong jold_txn_handle) { | |
11fdf7f2 TL |
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( | |
494da23a TL |
247 | JNIEnv*, jobject, jlong jhandle, jlong jwrite_options_handle, |
248 | jlong joptimistic_txn_options_handle, jlong jold_txn_handle) { | |
11fdf7f2 TL |
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 | */ | |
494da23a TL |
273 | jlong Java_org_rocksdb_OptimisticTransactionDB_getBaseDB( |
274 | JNIEnv*, jobject, jlong jhandle) { | |
11fdf7f2 TL |
275 | auto* optimistic_txn_db = |
276 | reinterpret_cast<rocksdb::OptimisticTransactionDB*>(jhandle); | |
277 | return reinterpret_cast<jlong>(optimistic_txn_db->GetBaseDB()); | |
278 | } |