]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | // |
6 | // This file implements the "bridge" between Java and C++ and enables | |
7 | // calling c++ rocksdb::DB methods from Java side. | |
8 | ||
9 | #include <jni.h> | |
10 | #include <stdio.h> | |
11 | #include <stdlib.h> | |
12 | #include <algorithm> | |
13 | #include <functional> | |
14 | #include <memory> | |
15 | #include <string> | |
16 | #include <tuple> | |
17 | #include <vector> | |
18 | ||
19 | #include "include/org_rocksdb_RocksDB.h" | |
20 | #include "rocksdb/cache.h" | |
21 | #include "rocksdb/db.h" | |
22 | #include "rocksdb/options.h" | |
23 | #include "rocksdb/types.h" | |
24 | #include "rocksjni/portal.h" | |
25 | ||
26 | #ifdef min | |
27 | #undef min | |
28 | #endif | |
29 | ||
11fdf7f2 TL |
30 | jlong rocksdb_open_helper( |
31 | JNIEnv* env, jlong jopt_handle, jstring jdb_path, | |
32 | std::function<rocksdb::Status(const rocksdb::Options&, const std::string&, | |
33 | rocksdb::DB**)> | |
34 | open_fn) { | |
7c673cae | 35 | const char* db_path = env->GetStringUTFChars(jdb_path, nullptr); |
11fdf7f2 | 36 | if (db_path == nullptr) { |
7c673cae FG |
37 | // exception thrown: OutOfMemoryError |
38 | return 0; | |
39 | } | |
40 | ||
41 | auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); | |
42 | rocksdb::DB* db = nullptr; | |
43 | rocksdb::Status s = open_fn(*opt, db_path, &db); | |
44 | ||
45 | env->ReleaseStringUTFChars(jdb_path, db_path); | |
46 | ||
47 | if (s.ok()) { | |
48 | return reinterpret_cast<jlong>(db); | |
49 | } else { | |
50 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
51 | return 0; | |
52 | } | |
53 | } | |
54 | ||
55 | /* | |
56 | * Class: org_rocksdb_RocksDB | |
57 | * Method: open | |
58 | * Signature: (JLjava/lang/String;)J | |
59 | */ | |
494da23a TL |
60 | jlong Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2( |
61 | JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) { | |
11fdf7f2 TL |
62 | return rocksdb_open_helper( |
63 | env, jopt_handle, jdb_path, | |
64 | (rocksdb::Status(*)(const rocksdb::Options&, const std::string&, | |
65 | rocksdb::DB**)) & | |
66 | rocksdb::DB::Open); | |
7c673cae FG |
67 | } |
68 | ||
69 | /* | |
70 | * Class: org_rocksdb_RocksDB | |
71 | * Method: openROnly | |
72 | * Signature: (JLjava/lang/String;)J | |
73 | */ | |
74 | jlong Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2( | |
494da23a | 75 | JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) { |
11fdf7f2 TL |
76 | return rocksdb_open_helper(env, jopt_handle, jdb_path, |
77 | [](const rocksdb::Options& options, | |
78 | const std::string& db_path, rocksdb::DB** db) { | |
79 | return rocksdb::DB::OpenForReadOnly(options, | |
80 | db_path, db); | |
81 | }); | |
7c673cae FG |
82 | } |
83 | ||
11fdf7f2 TL |
84 | jlongArray rocksdb_open_helper( |
85 | JNIEnv* env, jlong jopt_handle, jstring jdb_path, | |
86 | jobjectArray jcolumn_names, jlongArray jcolumn_options, | |
7c673cae | 87 | std::function<rocksdb::Status( |
11fdf7f2 TL |
88 | const rocksdb::DBOptions&, const std::string&, |
89 | const std::vector<rocksdb::ColumnFamilyDescriptor>&, | |
90 | std::vector<rocksdb::ColumnFamilyHandle*>*, rocksdb::DB**)> | |
91 | open_fn) { | |
7c673cae | 92 | const char* db_path = env->GetStringUTFChars(jdb_path, nullptr); |
11fdf7f2 | 93 | if (db_path == nullptr) { |
7c673cae FG |
94 | // exception thrown: OutOfMemoryError |
95 | return nullptr; | |
96 | } | |
97 | ||
98 | const jsize len_cols = env->GetArrayLength(jcolumn_names); | |
99 | jlong* jco = env->GetLongArrayElements(jcolumn_options, nullptr); | |
11fdf7f2 | 100 | if (jco == nullptr) { |
7c673cae FG |
101 | // exception thrown: OutOfMemoryError |
102 | env->ReleaseStringUTFChars(jdb_path, db_path); | |
103 | return nullptr; | |
104 | } | |
105 | ||
106 | std::vector<rocksdb::ColumnFamilyDescriptor> column_families; | |
107 | jboolean has_exception = JNI_FALSE; | |
108 | rocksdb::JniUtil::byteStrings<std::string>( | |
11fdf7f2 TL |
109 | env, jcolumn_names, |
110 | [](const char* str_data, const size_t str_len) { | |
111 | return std::string(str_data, str_len); | |
112 | }, | |
113 | [&jco, &column_families](size_t idx, std::string cf_name) { | |
114 | rocksdb::ColumnFamilyOptions* cf_options = | |
115 | reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jco[idx]); | |
116 | column_families.push_back( | |
117 | rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options)); | |
118 | }, | |
119 | &has_exception); | |
7c673cae FG |
120 | |
121 | env->ReleaseLongArrayElements(jcolumn_options, jco, JNI_ABORT); | |
122 | ||
11fdf7f2 TL |
123 | if (has_exception == JNI_TRUE) { |
124 | // exception occurred | |
7c673cae FG |
125 | env->ReleaseStringUTFChars(jdb_path, db_path); |
126 | return nullptr; | |
127 | } | |
128 | ||
129 | auto* opt = reinterpret_cast<rocksdb::DBOptions*>(jopt_handle); | |
494da23a | 130 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; |
7c673cae | 131 | rocksdb::DB* db = nullptr; |
494da23a | 132 | rocksdb::Status s = open_fn(*opt, db_path, column_families, &cf_handles, &db); |
7c673cae FG |
133 | |
134 | // we have now finished with db_path | |
135 | env->ReleaseStringUTFChars(jdb_path, db_path); | |
136 | ||
137 | // check if open operation was successful | |
494da23a TL |
138 | if (!s.ok()) { |
139 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
140 | return nullptr; | |
141 | } | |
7c673cae | 142 | |
494da23a TL |
143 | const jsize resultsLen = 1 + len_cols; // db handle + column family handles |
144 | std::unique_ptr<jlong[]> results = | |
145 | std::unique_ptr<jlong[]>(new jlong[resultsLen]); | |
146 | results[0] = reinterpret_cast<jlong>(db); | |
147 | for (int i = 1; i <= len_cols; i++) { | |
148 | results[i] = reinterpret_cast<jlong>(cf_handles[i - 1]); | |
149 | } | |
7c673cae | 150 | |
494da23a TL |
151 | jlongArray jresults = env->NewLongArray(resultsLen); |
152 | if (jresults == nullptr) { | |
153 | // exception thrown: OutOfMemoryError | |
154 | return nullptr; | |
155 | } | |
7c673cae | 156 | |
494da23a TL |
157 | env->SetLongArrayRegion(jresults, 0, resultsLen, results.get()); |
158 | if (env->ExceptionCheck()) { | |
159 | // exception thrown: ArrayIndexOutOfBoundsException | |
160 | env->DeleteLocalRef(jresults); | |
7c673cae FG |
161 | return nullptr; |
162 | } | |
494da23a TL |
163 | |
164 | return jresults; | |
7c673cae FG |
165 | } |
166 | ||
167 | /* | |
168 | * Class: org_rocksdb_RocksDB | |
169 | * Method: openROnly | |
170 | * Signature: (JLjava/lang/String;[[B[J)[J | |
171 | */ | |
172 | jlongArray Java_org_rocksdb_RocksDB_openROnly__JLjava_lang_String_2_3_3B_3J( | |
494da23a | 173 | JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path, |
7c673cae | 174 | jobjectArray jcolumn_names, jlongArray jcolumn_options) { |
11fdf7f2 TL |
175 | return rocksdb_open_helper( |
176 | env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options, | |
177 | [](const rocksdb::DBOptions& options, const std::string& db_path, | |
178 | const std::vector<rocksdb::ColumnFamilyDescriptor>& column_families, | |
179 | std::vector<rocksdb::ColumnFamilyHandle*>* handles, rocksdb::DB** db) { | |
180 | return rocksdb::DB::OpenForReadOnly(options, db_path, column_families, | |
181 | handles, db); | |
182 | }); | |
7c673cae FG |
183 | } |
184 | ||
185 | /* | |
186 | * Class: org_rocksdb_RocksDB | |
187 | * Method: open | |
188 | * Signature: (JLjava/lang/String;[[B[J)[J | |
189 | */ | |
190 | jlongArray Java_org_rocksdb_RocksDB_open__JLjava_lang_String_2_3_3B_3J( | |
494da23a | 191 | JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path, |
7c673cae | 192 | jobjectArray jcolumn_names, jlongArray jcolumn_options) { |
11fdf7f2 TL |
193 | return rocksdb_open_helper( |
194 | env, jopt_handle, jdb_path, jcolumn_names, jcolumn_options, | |
195 | (rocksdb::Status(*)(const rocksdb::DBOptions&, const std::string&, | |
196 | const std::vector<rocksdb::ColumnFamilyDescriptor>&, | |
197 | std::vector<rocksdb::ColumnFamilyHandle*>*, | |
198 | rocksdb::DB**)) & | |
199 | rocksdb::DB::Open); | |
7c673cae FG |
200 | } |
201 | ||
494da23a TL |
202 | /* |
203 | * Class: org_rocksdb_RocksDB | |
204 | * Method: disposeInternal | |
205 | * Signature: (J)V | |
206 | */ | |
207 | void Java_org_rocksdb_RocksDB_disposeInternal( | |
208 | JNIEnv*, jobject, jlong jhandle) { | |
209 | auto* db = reinterpret_cast<rocksdb::DB*>(jhandle); | |
210 | assert(db != nullptr); | |
211 | delete db; | |
212 | } | |
213 | ||
214 | /* | |
215 | * Class: org_rocksdb_RocksDB | |
216 | * Method: closeDatabase | |
217 | * Signature: (J)V | |
218 | */ | |
219 | void Java_org_rocksdb_RocksDB_closeDatabase( | |
220 | JNIEnv* env, jclass, jlong jhandle) { | |
221 | auto* db = reinterpret_cast<rocksdb::DB*>(jhandle); | |
222 | assert(db != nullptr); | |
223 | rocksdb::Status s = db->Close(); | |
224 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
225 | } | |
7c673cae FG |
226 | |
227 | /* | |
228 | * Class: org_rocksdb_RocksDB | |
229 | * Method: listColumnFamilies | |
230 | * Signature: (JLjava/lang/String;)[[B | |
231 | */ | |
494da23a TL |
232 | jobjectArray Java_org_rocksdb_RocksDB_listColumnFamilies( |
233 | JNIEnv* env, jclass, jlong jopt_handle, jstring jdb_path) { | |
7c673cae FG |
234 | std::vector<std::string> column_family_names; |
235 | const char* db_path = env->GetStringUTFChars(jdb_path, nullptr); | |
11fdf7f2 | 236 | if (db_path == nullptr) { |
7c673cae FG |
237 | // exception thrown: OutOfMemoryError |
238 | return nullptr; | |
239 | } | |
240 | ||
241 | auto* opt = reinterpret_cast<rocksdb::Options*>(jopt_handle); | |
11fdf7f2 TL |
242 | rocksdb::Status s = |
243 | rocksdb::DB::ListColumnFamilies(*opt, db_path, &column_family_names); | |
7c673cae FG |
244 | |
245 | env->ReleaseStringUTFChars(jdb_path, db_path); | |
246 | ||
247 | jobjectArray jcolumn_family_names = | |
248 | rocksdb::JniUtil::stringsBytes(env, column_family_names); | |
249 | ||
250 | return jcolumn_family_names; | |
251 | } | |
252 | ||
494da23a TL |
253 | /* |
254 | * Class: org_rocksdb_RocksDB | |
255 | * Method: createColumnFamily | |
256 | * Signature: (J[BIJ)J | |
257 | */ | |
258 | jlong Java_org_rocksdb_RocksDB_createColumnFamily( | |
259 | JNIEnv* env, jobject, jlong jhandle, jbyteArray jcf_name, | |
260 | jint jcf_name_len, jlong jcf_options_handle) { | |
261 | auto* db = reinterpret_cast<rocksdb::DB*>(jhandle); | |
262 | jboolean has_exception = JNI_FALSE; | |
263 | const std::string cf_name = | |
264 | rocksdb::JniUtil::byteString<std::string>(env, jcf_name, jcf_name_len, | |
265 | [](const char* str, const size_t len) { | |
266 | return std::string(str, len); | |
267 | }, &has_exception); | |
268 | if (has_exception == JNI_TRUE) { | |
269 | // exception occurred | |
270 | return 0; | |
271 | } | |
272 | auto* cf_options = | |
273 | reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcf_options_handle); | |
274 | rocksdb::ColumnFamilyHandle *cf_handle; | |
275 | rocksdb::Status s = db->CreateColumnFamily(*cf_options, cf_name, &cf_handle); | |
276 | if (!s.ok()) { | |
277 | // error occurred | |
278 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
279 | return 0; | |
280 | } | |
281 | return reinterpret_cast<jlong>(cf_handle); | |
282 | } | |
283 | ||
284 | /* | |
285 | * Class: org_rocksdb_RocksDB | |
286 | * Method: createColumnFamilies | |
287 | * Signature: (JJ[[B)[J | |
288 | */ | |
289 | jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__JJ_3_3B( | |
290 | JNIEnv* env, jobject, jlong jhandle, jlong jcf_options_handle, | |
291 | jobjectArray jcf_names) { | |
292 | auto* db = reinterpret_cast<rocksdb::DB*>(jhandle); | |
293 | auto* cf_options = | |
294 | reinterpret_cast<rocksdb::ColumnFamilyOptions*>(jcf_options_handle); | |
295 | jboolean has_exception = JNI_FALSE; | |
296 | std::vector<std::string> cf_names; | |
297 | rocksdb::JniUtil::byteStrings<std::string>(env, jcf_names, | |
298 | [](const char* str, const size_t len) { | |
299 | return std::string(str, len); | |
300 | }, | |
301 | [&cf_names](const size_t, std::string str) { | |
302 | cf_names.push_back(str); | |
303 | }, | |
304 | &has_exception); | |
305 | if (has_exception == JNI_TRUE) { | |
306 | // exception occurred | |
307 | return nullptr; | |
308 | } | |
309 | ||
310 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; | |
311 | rocksdb::Status s = db->CreateColumnFamilies(*cf_options, cf_names, &cf_handles); | |
312 | if (!s.ok()) { | |
313 | // error occurred | |
314 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
315 | return nullptr; | |
316 | } | |
317 | ||
318 | jlongArray jcf_handles = rocksdb::JniUtil::toJPointers<rocksdb::ColumnFamilyHandle>( | |
319 | env, cf_handles, &has_exception); | |
320 | if (has_exception == JNI_TRUE) { | |
321 | // exception occurred | |
322 | return nullptr; | |
323 | } | |
324 | return jcf_handles; | |
325 | } | |
326 | ||
327 | /* | |
328 | * Class: org_rocksdb_RocksDB | |
329 | * Method: createColumnFamilies | |
330 | * Signature: (J[J[[B)[J | |
331 | */ | |
332 | jlongArray Java_org_rocksdb_RocksDB_createColumnFamilies__J_3J_3_3B( | |
333 | JNIEnv* env, jobject, jlong jhandle, jlongArray jcf_options_handles, | |
334 | jobjectArray jcf_names) { | |
335 | auto* db = reinterpret_cast<rocksdb::DB*>(jhandle); | |
336 | const jsize jlen = env->GetArrayLength(jcf_options_handles); | |
337 | std::vector<rocksdb::ColumnFamilyDescriptor> cf_descriptors; | |
338 | cf_descriptors.reserve(jlen); | |
339 | ||
340 | jboolean jcf_options_handles_is_copy = JNI_FALSE; | |
341 | jlong *jcf_options_handles_elems = env->GetLongArrayElements(jcf_options_handles, &jcf_options_handles_is_copy); | |
342 | if(jcf_options_handles_elems == nullptr) { | |
343 | // exception thrown: OutOfMemoryError | |
344 | return nullptr; | |
345 | } | |
346 | ||
347 | // extract the column family descriptors | |
348 | jboolean has_exception = JNI_FALSE; | |
349 | for (jsize i = 0; i < jlen; i++) { | |
350 | auto* cf_options = reinterpret_cast<rocksdb::ColumnFamilyOptions*>( | |
351 | jcf_options_handles_elems[i]); | |
352 | jbyteArray jcf_name = static_cast<jbyteArray>( | |
353 | env->GetObjectArrayElement(jcf_names, i)); | |
354 | if (env->ExceptionCheck()) { | |
355 | // exception thrown: ArrayIndexOutOfBoundsException | |
356 | env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT); | |
357 | return nullptr; | |
358 | } | |
359 | const std::string cf_name = | |
360 | rocksdb::JniUtil::byteString<std::string>(env, jcf_name, | |
361 | [](const char* str, const size_t len) { | |
362 | return std::string(str, len); | |
363 | }, | |
364 | &has_exception); | |
365 | if (has_exception == JNI_TRUE) { | |
366 | // exception occurred | |
367 | env->DeleteLocalRef(jcf_name); | |
368 | env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT); | |
369 | return nullptr; | |
370 | } | |
371 | ||
372 | cf_descriptors.push_back(rocksdb::ColumnFamilyDescriptor(cf_name, *cf_options)); | |
373 | ||
374 | env->DeleteLocalRef(jcf_name); | |
375 | } | |
376 | ||
377 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; | |
378 | rocksdb::Status s = db->CreateColumnFamilies(cf_descriptors, &cf_handles); | |
379 | ||
380 | env->ReleaseLongArrayElements(jcf_options_handles, jcf_options_handles_elems, JNI_ABORT); | |
381 | ||
382 | if (!s.ok()) { | |
383 | // error occurred | |
384 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
385 | return nullptr; | |
386 | } | |
387 | ||
388 | jlongArray jcf_handles = rocksdb::JniUtil::toJPointers<rocksdb::ColumnFamilyHandle>( | |
389 | env, cf_handles, &has_exception); | |
390 | if (has_exception == JNI_TRUE) { | |
391 | // exception occurred | |
392 | return nullptr; | |
393 | } | |
394 | return jcf_handles; | |
395 | } | |
396 | ||
397 | /* | |
398 | * Class: org_rocksdb_RocksDB | |
399 | * Method: dropColumnFamily | |
400 | * Signature: (JJ)V; | |
401 | */ | |
402 | void Java_org_rocksdb_RocksDB_dropColumnFamily( | |
403 | JNIEnv* env, jobject, jlong jdb_handle, | |
404 | jlong jcf_handle) { | |
405 | auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
406 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
407 | rocksdb::Status s = db_handle->DropColumnFamily(cf_handle); | |
408 | if (!s.ok()) { | |
409 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
410 | } | |
411 | } | |
412 | ||
413 | /* | |
414 | * Class: org_rocksdb_RocksDB | |
415 | * Method: dropColumnFamilies | |
416 | * Signature: (J[J)V | |
417 | */ | |
418 | void Java_org_rocksdb_RocksDB_dropColumnFamilies( | |
419 | JNIEnv* env, jobject, jlong jdb_handle, | |
420 | jlongArray jcolumn_family_handles) { | |
421 | auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
422 | ||
423 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; | |
424 | if (jcolumn_family_handles != nullptr) { | |
425 | const jsize len_cols = env->GetArrayLength(jcolumn_family_handles); | |
426 | ||
427 | jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr); | |
428 | if (jcfh == nullptr) { | |
429 | // exception thrown: OutOfMemoryError | |
430 | return; | |
431 | } | |
432 | ||
433 | for (jsize i = 0; i < len_cols; i++) { | |
434 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]); | |
435 | cf_handles.push_back(cf_handle); | |
436 | } | |
437 | env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT); | |
438 | } | |
439 | ||
440 | rocksdb::Status s = db_handle->DropColumnFamilies(cf_handles); | |
441 | if (!s.ok()) { | |
442 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
443 | } | |
444 | } | |
445 | ||
7c673cae FG |
446 | ////////////////////////////////////////////////////////////////////////////// |
447 | // rocksdb::DB::Put | |
448 | ||
449 | /** | |
450 | * @return true if the put succeeded, false if a Java Exception was thrown | |
451 | */ | |
494da23a TL |
452 | bool rocksdb_put_helper( |
453 | JNIEnv* env, rocksdb::DB* db, | |
454 | const rocksdb::WriteOptions& write_options, | |
455 | rocksdb::ColumnFamilyHandle* cf_handle, jbyteArray jkey, | |
456 | jint jkey_off, jint jkey_len, jbyteArray jval, | |
457 | jint jval_off, jint jval_len) { | |
7c673cae FG |
458 | jbyte* key = new jbyte[jkey_len]; |
459 | env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key); | |
11fdf7f2 | 460 | if (env->ExceptionCheck()) { |
7c673cae | 461 | // exception thrown: ArrayIndexOutOfBoundsException |
11fdf7f2 | 462 | delete[] key; |
7c673cae FG |
463 | return false; |
464 | } | |
465 | ||
466 | jbyte* value = new jbyte[jval_len]; | |
467 | env->GetByteArrayRegion(jval, jval_off, jval_len, value); | |
11fdf7f2 | 468 | if (env->ExceptionCheck()) { |
7c673cae | 469 | // exception thrown: ArrayIndexOutOfBoundsException |
11fdf7f2 TL |
470 | delete[] value; |
471 | delete[] key; | |
7c673cae FG |
472 | return false; |
473 | } | |
474 | ||
475 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); | |
476 | rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jval_len); | |
477 | ||
478 | rocksdb::Status s; | |
479 | if (cf_handle != nullptr) { | |
480 | s = db->Put(write_options, cf_handle, key_slice, value_slice); | |
481 | } else { | |
482 | // backwards compatibility | |
483 | s = db->Put(write_options, key_slice, value_slice); | |
484 | } | |
485 | ||
486 | // cleanup | |
11fdf7f2 TL |
487 | delete[] value; |
488 | delete[] key; | |
7c673cae FG |
489 | |
490 | if (s.ok()) { | |
491 | return true; | |
492 | } else { | |
493 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
494 | return false; | |
495 | } | |
496 | } | |
497 | ||
498 | /* | |
499 | * Class: org_rocksdb_RocksDB | |
500 | * Method: put | |
501 | * Signature: (J[BII[BII)V | |
502 | */ | |
494da23a TL |
503 | void Java_org_rocksdb_RocksDB_put__J_3BII_3BII( |
504 | JNIEnv* env, jobject, jlong jdb_handle, | |
505 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
506 | jbyteArray jval, jint jval_off, jint jval_len) { | |
7c673cae FG |
507 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
508 | static const rocksdb::WriteOptions default_write_options = | |
509 | rocksdb::WriteOptions(); | |
7c673cae | 510 | rocksdb_put_helper(env, db, default_write_options, nullptr, jkey, jkey_off, |
494da23a | 511 | jkey_len, jval, jval_off, jval_len); |
7c673cae FG |
512 | } |
513 | ||
514 | /* | |
515 | * Class: org_rocksdb_RocksDB | |
516 | * Method: put | |
517 | * Signature: (J[BII[BIIJ)V | |
518 | */ | |
494da23a TL |
519 | void Java_org_rocksdb_RocksDB_put__J_3BII_3BIIJ( |
520 | JNIEnv* env, jobject, jlong jdb_handle, | |
521 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
522 | jbyteArray jval, jint jval_off, jint jval_len, | |
523 | jlong jcf_handle) { | |
7c673cae FG |
524 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
525 | static const rocksdb::WriteOptions default_write_options = | |
526 | rocksdb::WriteOptions(); | |
527 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
528 | if (cf_handle != nullptr) { | |
529 | rocksdb_put_helper(env, db, default_write_options, cf_handle, jkey, | |
494da23a | 530 | jkey_off, jkey_len, jval, jval_off, jval_len); |
7c673cae | 531 | } else { |
11fdf7f2 TL |
532 | rocksdb::RocksDBExceptionJni::ThrowNew( |
533 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
534 | } |
535 | } | |
536 | ||
537 | /* | |
538 | * Class: org_rocksdb_RocksDB | |
539 | * Method: put | |
540 | * Signature: (JJ[BII[BII)V | |
541 | */ | |
494da23a TL |
542 | void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BII( |
543 | JNIEnv* env, jobject, jlong jdb_handle, | |
544 | jlong jwrite_options_handle, | |
545 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
546 | jbyteArray jval, jint jval_off, jint jval_len) { | |
7c673cae | 547 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
11fdf7f2 TL |
548 | auto* write_options = |
549 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle); | |
7c673cae | 550 | rocksdb_put_helper(env, db, *write_options, nullptr, jkey, jkey_off, jkey_len, |
494da23a | 551 | jval, jval_off, jval_len); |
7c673cae FG |
552 | } |
553 | ||
554 | /* | |
555 | * Class: org_rocksdb_RocksDB | |
556 | * Method: put | |
557 | * Signature: (JJ[BII[BIIJ)V | |
558 | */ | |
559 | void Java_org_rocksdb_RocksDB_put__JJ_3BII_3BIIJ( | |
494da23a TL |
560 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle, |
561 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
562 | jbyteArray jval, jint jval_off, jint jval_len, | |
563 | jlong jcf_handle) { | |
7c673cae | 564 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
11fdf7f2 TL |
565 | auto* write_options = |
566 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle); | |
7c673cae FG |
567 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
568 | if (cf_handle != nullptr) { | |
569 | rocksdb_put_helper(env, db, *write_options, cf_handle, jkey, jkey_off, | |
494da23a | 570 | jkey_len, jval, jval_off, jval_len); |
7c673cae | 571 | } else { |
11fdf7f2 TL |
572 | rocksdb::RocksDBExceptionJni::ThrowNew( |
573 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
574 | } |
575 | } | |
576 | ||
577 | ////////////////////////////////////////////////////////////////////////////// | |
494da23a | 578 | // rocksdb::DB::Delete() |
7c673cae | 579 | |
494da23a TL |
580 | /** |
581 | * @return true if the delete succeeded, false if a Java Exception was thrown | |
7c673cae | 582 | */ |
494da23a TL |
583 | bool rocksdb_delete_helper( |
584 | JNIEnv* env, rocksdb::DB* db, const rocksdb::WriteOptions& write_options, | |
585 | rocksdb::ColumnFamilyHandle* cf_handle, | |
586 | jbyteArray jkey, jint jkey_off, jint jkey_len) { | |
7c673cae FG |
587 | jbyte* key = new jbyte[jkey_len]; |
588 | env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key); | |
11fdf7f2 | 589 | if (env->ExceptionCheck()) { |
7c673cae | 590 | // exception thrown: ArrayIndexOutOfBoundsException |
11fdf7f2 | 591 | delete[] key; |
7c673cae FG |
592 | return false; |
593 | } | |
7c673cae | 594 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); |
11fdf7f2 | 595 | |
494da23a | 596 | rocksdb::Status s; |
7c673cae | 597 | if (cf_handle != nullptr) { |
494da23a | 598 | s = db->Delete(write_options, cf_handle, key_slice); |
7c673cae | 599 | } else { |
494da23a TL |
600 | // backwards compatibility |
601 | s = db->Delete(write_options, key_slice); | |
7c673cae FG |
602 | } |
603 | ||
604 | // cleanup | |
11fdf7f2 | 605 | delete[] key; |
7c673cae | 606 | |
494da23a TL |
607 | if (s.ok()) { |
608 | return true; | |
7c673cae FG |
609 | } |
610 | ||
494da23a TL |
611 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); |
612 | return false; | |
7c673cae FG |
613 | } |
614 | ||
615 | /* | |
616 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
617 | * Method: delete |
618 | * Signature: (J[BII)V | |
7c673cae | 619 | */ |
494da23a TL |
620 | void Java_org_rocksdb_RocksDB_delete__J_3BII( |
621 | JNIEnv* env, jobject, jlong jdb_handle, | |
622 | jbyteArray jkey, jint jkey_off, jint jkey_len) { | |
7c673cae | 623 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
624 | static const rocksdb::WriteOptions default_write_options = |
625 | rocksdb::WriteOptions(); | |
626 | rocksdb_delete_helper(env, db, default_write_options, nullptr, jkey, jkey_off, | |
627 | jkey_len); | |
7c673cae FG |
628 | } |
629 | ||
630 | /* | |
631 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
632 | * Method: delete |
633 | * Signature: (J[BIIJ)V | |
7c673cae | 634 | */ |
494da23a TL |
635 | void Java_org_rocksdb_RocksDB_delete__J_3BIIJ( |
636 | JNIEnv* env, jobject, jlong jdb_handle, | |
637 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
638 | jlong jcf_handle) { | |
7c673cae | 639 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
640 | static const rocksdb::WriteOptions default_write_options = |
641 | rocksdb::WriteOptions(); | |
11fdf7f2 | 642 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
7c673cae | 643 | if (cf_handle != nullptr) { |
494da23a TL |
644 | rocksdb_delete_helper(env, db, default_write_options, cf_handle, jkey, |
645 | jkey_off, jkey_len); | |
7c673cae | 646 | } else { |
11fdf7f2 TL |
647 | rocksdb::RocksDBExceptionJni::ThrowNew( |
648 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
649 | } |
650 | } | |
651 | ||
652 | /* | |
653 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
654 | * Method: delete |
655 | * Signature: (JJ[BII)V | |
7c673cae | 656 | */ |
494da23a TL |
657 | void Java_org_rocksdb_RocksDB_delete__JJ_3BII( |
658 | JNIEnv* env, jobject, | |
659 | jlong jdb_handle, | |
660 | jlong jwrite_options, | |
661 | jbyteArray jkey, jint jkey_off, jint jkey_len) { | |
7c673cae | 662 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
663 | auto* write_options = |
664 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options); | |
665 | rocksdb_delete_helper(env, db, *write_options, nullptr, jkey, jkey_off, | |
666 | jkey_len); | |
7c673cae FG |
667 | } |
668 | ||
669 | /* | |
670 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
671 | * Method: delete |
672 | * Signature: (JJ[BIIJ)V | |
7c673cae | 673 | */ |
494da23a TL |
674 | void Java_org_rocksdb_RocksDB_delete__JJ_3BIIJ( |
675 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options, | |
676 | jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) { | |
7c673cae | 677 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
678 | auto* write_options = |
679 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options); | |
11fdf7f2 | 680 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
7c673cae | 681 | if (cf_handle != nullptr) { |
494da23a TL |
682 | rocksdb_delete_helper(env, db, *write_options, cf_handle, jkey, jkey_off, |
683 | jkey_len); | |
7c673cae | 684 | } else { |
11fdf7f2 TL |
685 | rocksdb::RocksDBExceptionJni::ThrowNew( |
686 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
687 | } |
688 | } | |
689 | ||
690 | ////////////////////////////////////////////////////////////////////////////// | |
494da23a TL |
691 | // rocksdb::DB::SingleDelete() |
692 | /** | |
693 | * @return true if the single delete succeeded, false if a Java Exception | |
694 | * was thrown | |
695 | */ | |
696 | bool rocksdb_single_delete_helper( | |
697 | JNIEnv* env, rocksdb::DB* db, | |
698 | const rocksdb::WriteOptions& write_options, | |
699 | rocksdb::ColumnFamilyHandle* cf_handle, | |
700 | jbyteArray jkey, jint jkey_len) { | |
701 | jbyte* key = env->GetByteArrayElements(jkey, nullptr); | |
702 | if (key == nullptr) { | |
703 | // exception thrown: OutOfMemoryError | |
704 | return false; | |
7c673cae | 705 | } |
11fdf7f2 | 706 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); |
7c673cae | 707 | |
7c673cae | 708 | rocksdb::Status s; |
494da23a TL |
709 | if (cf_handle != nullptr) { |
710 | s = db->SingleDelete(write_options, cf_handle, key_slice); | |
7c673cae FG |
711 | } else { |
712 | // backwards compatibility | |
494da23a | 713 | s = db->SingleDelete(write_options, key_slice); |
7c673cae FG |
714 | } |
715 | ||
494da23a TL |
716 | // trigger java unref on key and value. |
717 | // by passing JNI_ABORT, it will simply release the reference without | |
718 | // copying the result back to the java byte array. | |
719 | env->ReleaseByteArrayElements(jkey, key, JNI_ABORT); | |
7c673cae FG |
720 | |
721 | if (s.ok()) { | |
494da23a | 722 | return true; |
7c673cae FG |
723 | } |
724 | ||
725 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
494da23a | 726 | return false; |
7c673cae FG |
727 | } |
728 | ||
729 | /* | |
730 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
731 | * Method: singleDelete |
732 | * Signature: (J[BI)V | |
7c673cae | 733 | */ |
494da23a TL |
734 | void Java_org_rocksdb_RocksDB_singleDelete__J_3BI( |
735 | JNIEnv* env, jobject, | |
736 | jlong jdb_handle, | |
737 | jbyteArray jkey, | |
738 | jint jkey_len) { | |
739 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
740 | static const rocksdb::WriteOptions default_write_options = | |
741 | rocksdb::WriteOptions(); | |
742 | rocksdb_single_delete_helper(env, db, default_write_options, nullptr, | |
743 | jkey, jkey_len); | |
7c673cae FG |
744 | } |
745 | ||
746 | /* | |
747 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
748 | * Method: singleDelete |
749 | * Signature: (J[BIJ)V | |
7c673cae | 750 | */ |
494da23a TL |
751 | void Java_org_rocksdb_RocksDB_singleDelete__J_3BIJ( |
752 | JNIEnv* env, jobject, jlong jdb_handle, | |
753 | jbyteArray jkey, jint jkey_len, jlong jcf_handle) { | |
754 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
755 | static const rocksdb::WriteOptions default_write_options = | |
756 | rocksdb::WriteOptions(); | |
757 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
7c673cae | 758 | if (cf_handle != nullptr) { |
494da23a TL |
759 | rocksdb_single_delete_helper(env, db, default_write_options, cf_handle, |
760 | jkey, jkey_len); | |
7c673cae | 761 | } else { |
11fdf7f2 TL |
762 | rocksdb::RocksDBExceptionJni::ThrowNew( |
763 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
764 | } |
765 | } | |
766 | ||
767 | /* | |
768 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
769 | * Method: singleDelete |
770 | * Signature: (JJ[BIJ)V | |
7c673cae | 771 | */ |
494da23a TL |
772 | void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BI( |
773 | JNIEnv* env, jobject, jlong jdb_handle, | |
774 | jlong jwrite_options, | |
775 | jbyteArray jkey, | |
776 | jint jkey_len) { | |
777 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
778 | auto* write_options = | |
779 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options); | |
780 | rocksdb_single_delete_helper(env, db, *write_options, nullptr, jkey, | |
781 | jkey_len); | |
7c673cae FG |
782 | } |
783 | ||
784 | /* | |
785 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
786 | * Method: singleDelete |
787 | * Signature: (JJ[BIJ)V | |
7c673cae | 788 | */ |
494da23a TL |
789 | void Java_org_rocksdb_RocksDB_singleDelete__JJ_3BIJ( |
790 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options, | |
791 | jbyteArray jkey, jint jkey_len, jlong jcf_handle) { | |
792 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
793 | auto* write_options = | |
794 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options); | |
7c673cae FG |
795 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
796 | if (cf_handle != nullptr) { | |
494da23a TL |
797 | rocksdb_single_delete_helper(env, db, *write_options, cf_handle, jkey, |
798 | jkey_len); | |
7c673cae | 799 | } else { |
11fdf7f2 TL |
800 | rocksdb::RocksDBExceptionJni::ThrowNew( |
801 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
802 | } |
803 | } | |
804 | ||
494da23a TL |
805 | ////////////////////////////////////////////////////////////////////////////// |
806 | // rocksdb::DB::DeleteRange() | |
807 | /** | |
808 | * @return true if the delete range succeeded, false if a Java Exception | |
809 | * was thrown | |
810 | */ | |
811 | bool rocksdb_delete_range_helper( | |
812 | JNIEnv* env, rocksdb::DB* db, | |
813 | const rocksdb::WriteOptions& write_options, | |
814 | rocksdb::ColumnFamilyHandle* cf_handle, | |
815 | jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len, | |
816 | jbyteArray jend_key, jint jend_key_off, jint jend_key_len) { | |
817 | jbyte* begin_key = new jbyte[jbegin_key_len]; | |
818 | env->GetByteArrayRegion(jbegin_key, jbegin_key_off, jbegin_key_len, | |
819 | begin_key); | |
11fdf7f2 | 820 | if (env->ExceptionCheck()) { |
494da23a TL |
821 | // exception thrown: ArrayIndexOutOfBoundsException |
822 | delete[] begin_key; | |
823 | return false; | |
7c673cae | 824 | } |
494da23a TL |
825 | rocksdb::Slice begin_key_slice(reinterpret_cast<char*>(begin_key), |
826 | jbegin_key_len); | |
7c673cae | 827 | |
494da23a TL |
828 | jbyte* end_key = new jbyte[jend_key_len]; |
829 | env->GetByteArrayRegion(jend_key, jend_key_off, jend_key_len, end_key); | |
830 | if (env->ExceptionCheck()) { | |
831 | // exception thrown: ArrayIndexOutOfBoundsException | |
832 | delete[] begin_key; | |
833 | delete[] end_key; | |
834 | return false; | |
7c673cae | 835 | } |
494da23a | 836 | rocksdb::Slice end_key_slice(reinterpret_cast<char*>(end_key), jend_key_len); |
7c673cae | 837 | |
494da23a TL |
838 | rocksdb::Status s = |
839 | db->DeleteRange(write_options, cf_handle, begin_key_slice, end_key_slice); | |
7c673cae | 840 | |
494da23a TL |
841 | // cleanup |
842 | delete[] begin_key; | |
843 | delete[] end_key; | |
7c673cae | 844 | |
494da23a TL |
845 | if (s.ok()) { |
846 | return true; | |
7c673cae FG |
847 | } |
848 | ||
494da23a TL |
849 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); |
850 | return false; | |
851 | } | |
7c673cae | 852 | |
494da23a TL |
853 | /* |
854 | * Class: org_rocksdb_RocksDB | |
855 | * Method: deleteRange | |
856 | * Signature: (J[BII[BII)V | |
857 | */ | |
858 | void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BII( | |
859 | JNIEnv* env, jobject, jlong jdb_handle, | |
860 | jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len, | |
861 | jbyteArray jend_key, jint jend_key_off, jint jend_key_len) { | |
862 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
863 | static const rocksdb::WriteOptions default_write_options = | |
864 | rocksdb::WriteOptions(); | |
865 | rocksdb_delete_range_helper(env, db, default_write_options, nullptr, | |
866 | jbegin_key, jbegin_key_off, jbegin_key_len, | |
867 | jend_key, jend_key_off, jend_key_len); | |
7c673cae FG |
868 | } |
869 | ||
494da23a TL |
870 | /* |
871 | * Class: org_rocksdb_RocksDB | |
872 | * Method: deleteRange | |
873 | * Signature: (J[BII[BIIJ)V | |
874 | */ | |
875 | void Java_org_rocksdb_RocksDB_deleteRange__J_3BII_3BIIJ( | |
876 | JNIEnv* env, jobject, jlong jdb_handle, | |
877 | jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len, | |
878 | jbyteArray jend_key, jint jend_key_off, jint jend_key_len, | |
879 | jlong jcf_handle) { | |
880 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
881 | static const rocksdb::WriteOptions default_write_options = | |
882 | rocksdb::WriteOptions(); | |
883 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
884 | if (cf_handle != nullptr) { | |
885 | rocksdb_delete_range_helper(env, db, default_write_options, cf_handle, | |
886 | jbegin_key, jbegin_key_off, jbegin_key_len, | |
887 | jend_key, jend_key_off, jend_key_len); | |
888 | } else { | |
889 | rocksdb::RocksDBExceptionJni::ThrowNew( | |
890 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae | 891 | } |
7c673cae FG |
892 | } |
893 | ||
494da23a TL |
894 | /* |
895 | * Class: org_rocksdb_RocksDB | |
896 | * Method: deleteRange | |
897 | * Signature: (JJ[BII[BII)V | |
11fdf7f2 | 898 | */ |
494da23a TL |
899 | void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BII( |
900 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options, | |
901 | jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len, | |
902 | jbyteArray jend_key, jint jend_key_off, jint jend_key_len) { | |
903 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
904 | auto* write_options = | |
905 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options); | |
906 | rocksdb_delete_range_helper(env, db, *write_options, nullptr, jbegin_key, | |
907 | jbegin_key_off, jbegin_key_len, jend_key, | |
908 | jend_key_off, jend_key_len); | |
909 | } | |
7c673cae | 910 | |
494da23a TL |
911 | /* |
912 | * Class: org_rocksdb_RocksDB | |
913 | * Method: deleteRange | |
914 | * Signature: (JJ[BII[BIIJ)V | |
915 | */ | |
916 | void Java_org_rocksdb_RocksDB_deleteRange__JJ_3BII_3BIIJ( | |
917 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options, | |
918 | jbyteArray jbegin_key, jint jbegin_key_off, jint jbegin_key_len, | |
919 | jbyteArray jend_key, jint jend_key_off, jint jend_key_len, | |
920 | jlong jcf_handle) { | |
921 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
922 | auto* write_options = | |
923 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options); | |
924 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
925 | if (cf_handle != nullptr) { | |
926 | rocksdb_delete_range_helper(env, db, *write_options, cf_handle, | |
927 | jbegin_key, jbegin_key_off, jbegin_key_len, | |
928 | jend_key, jend_key_off, jend_key_len); | |
929 | } else { | |
930 | rocksdb::RocksDBExceptionJni::ThrowNew( | |
931 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae | 932 | } |
494da23a | 933 | } |
7c673cae | 934 | |
494da23a TL |
935 | ////////////////////////////////////////////////////////////////////////////// |
936 | // rocksdb::DB::Merge | |
7c673cae | 937 | |
494da23a TL |
938 | /** |
939 | * @return true if the merge succeeded, false if a Java Exception was thrown | |
940 | */ | |
941 | bool rocksdb_merge_helper( | |
942 | JNIEnv* env, rocksdb::DB* db, const rocksdb::WriteOptions& write_options, | |
943 | rocksdb::ColumnFamilyHandle* cf_handle, | |
944 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
945 | jbyteArray jval, jint jval_off, jint jval_len) { | |
946 | jbyte* key = new jbyte[jkey_len]; | |
947 | env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key); | |
948 | if (env->ExceptionCheck()) { | |
949 | // exception thrown: ArrayIndexOutOfBoundsException | |
950 | delete[] key; | |
951 | return false; | |
7c673cae | 952 | } |
494da23a | 953 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); |
7c673cae | 954 | |
494da23a TL |
955 | jbyte* value = new jbyte[jval_len]; |
956 | env->GetByteArrayRegion(jval, jval_off, jval_len, value); | |
957 | if (env->ExceptionCheck()) { | |
958 | // exception thrown: ArrayIndexOutOfBoundsException | |
959 | delete[] value; | |
960 | delete[] key; | |
961 | return false; | |
7c673cae | 962 | } |
494da23a | 963 | rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jval_len); |
7c673cae | 964 | |
494da23a TL |
965 | rocksdb::Status s; |
966 | if (cf_handle != nullptr) { | |
967 | s = db->Merge(write_options, cf_handle, key_slice, value_slice); | |
7c673cae | 968 | } else { |
494da23a | 969 | s = db->Merge(write_options, key_slice, value_slice); |
7c673cae FG |
970 | } |
971 | ||
494da23a TL |
972 | // cleanup |
973 | delete[] value; | |
974 | delete[] key; | |
7c673cae | 975 | |
494da23a TL |
976 | if (s.ok()) { |
977 | return true; | |
7c673cae FG |
978 | } |
979 | ||
494da23a TL |
980 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); |
981 | return false; | |
7c673cae FG |
982 | } |
983 | ||
984 | /* | |
985 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
986 | * Method: merge |
987 | * Signature: (J[BII[BII)V | |
7c673cae | 988 | */ |
494da23a TL |
989 | void Java_org_rocksdb_RocksDB_merge__J_3BII_3BII( |
990 | JNIEnv* env, jobject, jlong jdb_handle, | |
991 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
992 | jbyteArray jval, jint jval_off, jint jval_len) { | |
993 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
994 | static const rocksdb::WriteOptions default_write_options = | |
995 | rocksdb::WriteOptions(); | |
996 | rocksdb_merge_helper(env, db, default_write_options, nullptr, jkey, jkey_off, | |
997 | jkey_len, jval, jval_off, jval_len); | |
7c673cae FG |
998 | } |
999 | ||
1000 | /* | |
1001 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1002 | * Method: merge |
1003 | * Signature: (J[BII[BIIJ)V | |
7c673cae | 1004 | */ |
494da23a TL |
1005 | void Java_org_rocksdb_RocksDB_merge__J_3BII_3BIIJ( |
1006 | JNIEnv* env, jobject, jlong jdb_handle, | |
1007 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1008 | jbyteArray jval, jint jval_off, jint jval_len, | |
1009 | jlong jcf_handle) { | |
1010 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1011 | static const rocksdb::WriteOptions default_write_options = | |
1012 | rocksdb::WriteOptions(); | |
1013 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
1014 | if (cf_handle != nullptr) { | |
1015 | rocksdb_merge_helper(env, db, default_write_options, cf_handle, jkey, | |
1016 | jkey_off, jkey_len, jval, jval_off, jval_len); | |
1017 | } else { | |
1018 | rocksdb::RocksDBExceptionJni::ThrowNew( | |
1019 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
1020 | } | |
7c673cae FG |
1021 | } |
1022 | ||
1023 | /* | |
1024 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1025 | * Method: merge |
1026 | * Signature: (JJ[BII[BII)V | |
7c673cae | 1027 | */ |
494da23a TL |
1028 | void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BII( |
1029 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle, | |
1030 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1031 | jbyteArray jval, jint jval_off, jint jval_len) { | |
1032 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1033 | auto* write_options = | |
1034 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle); | |
1035 | rocksdb_merge_helper(env, db, *write_options, nullptr, jkey, jkey_off, | |
1036 | jkey_len, jval, jval_off, jval_len); | |
7c673cae FG |
1037 | } |
1038 | ||
1039 | /* | |
1040 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1041 | * Method: merge |
1042 | * Signature: (JJ[BII[BIIJ)V | |
7c673cae | 1043 | */ |
494da23a TL |
1044 | void Java_org_rocksdb_RocksDB_merge__JJ_3BII_3BIIJ( |
1045 | JNIEnv* env, jobject, jlong jdb_handle, jlong jwrite_options_handle, | |
1046 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1047 | jbyteArray jval, jint jval_off, jint jval_len, jlong jcf_handle) { | |
1048 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1049 | auto* write_options = | |
1050 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle); | |
7c673cae FG |
1051 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
1052 | if (cf_handle != nullptr) { | |
494da23a TL |
1053 | rocksdb_merge_helper(env, db, *write_options, cf_handle, jkey, jkey_off, |
1054 | jkey_len, jval, jval_off, jval_len); | |
7c673cae | 1055 | } else { |
11fdf7f2 TL |
1056 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1057 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
7c673cae FG |
1058 | } |
1059 | } | |
1060 | ||
494da23a TL |
1061 | jlong rocksdb_iterator_helper(rocksdb::DB* db, |
1062 | rocksdb::ReadOptions read_options, | |
1063 | rocksdb::ColumnFamilyHandle* cf_handle) { | |
1064 | rocksdb::Iterator* iterator = nullptr; | |
1065 | if (cf_handle != nullptr) { | |
1066 | iterator = db->NewIterator(read_options, cf_handle); | |
1067 | } else { | |
1068 | iterator = db->NewIterator(read_options); | |
1069 | } | |
1070 | return reinterpret_cast<jlong>(iterator); | |
1071 | } | |
1072 | ||
1073 | ////////////////////////////////////////////////////////////////////////////// | |
1074 | // rocksdb::DB::Write | |
7c673cae FG |
1075 | /* |
1076 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1077 | * Method: write0 |
1078 | * Signature: (JJJ)V | |
7c673cae | 1079 | */ |
494da23a TL |
1080 | void Java_org_rocksdb_RocksDB_write0( |
1081 | JNIEnv* env, jobject, jlong jdb_handle, | |
1082 | jlong jwrite_options_handle, jlong jwb_handle) { | |
1083 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1084 | auto* write_options = | |
1085 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle); | |
1086 | auto* wb = reinterpret_cast<rocksdb::WriteBatch*>(jwb_handle); | |
1087 | ||
1088 | rocksdb::Status s = db->Write(*write_options, wb); | |
1089 | ||
1090 | if (!s.ok()) { | |
1091 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
1092 | } | |
7c673cae FG |
1093 | } |
1094 | ||
1095 | /* | |
1096 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1097 | * Method: write1 |
1098 | * Signature: (JJJ)V | |
7c673cae | 1099 | */ |
494da23a TL |
1100 | void Java_org_rocksdb_RocksDB_write1( |
1101 | JNIEnv* env, jobject, jlong jdb_handle, | |
1102 | jlong jwrite_options_handle, jlong jwbwi_handle) { | |
1103 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1104 | auto* write_options = | |
1105 | reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options_handle); | |
1106 | auto* wbwi = reinterpret_cast<rocksdb::WriteBatchWithIndex*>(jwbwi_handle); | |
1107 | auto* wb = wbwi->GetWriteBatch(); | |
1108 | ||
1109 | rocksdb::Status s = db->Write(*write_options, wb); | |
1110 | ||
1111 | if (!s.ok()) { | |
1112 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
7c673cae FG |
1113 | } |
1114 | } | |
1115 | ||
1116 | ////////////////////////////////////////////////////////////////////////////// | |
494da23a | 1117 | // rocksdb::DB::Get |
7c673cae | 1118 | |
494da23a TL |
1119 | jbyteArray rocksdb_get_helper( |
1120 | JNIEnv* env, rocksdb::DB* db, | |
1121 | const rocksdb::ReadOptions& read_opt, | |
1122 | rocksdb::ColumnFamilyHandle* column_family_handle, | |
1123 | jbyteArray jkey, jint jkey_off, jint jkey_len) { | |
7c673cae FG |
1124 | jbyte* key = new jbyte[jkey_len]; |
1125 | env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key); | |
11fdf7f2 | 1126 | if (env->ExceptionCheck()) { |
7c673cae | 1127 | // exception thrown: ArrayIndexOutOfBoundsException |
11fdf7f2 | 1128 | delete[] key; |
494da23a | 1129 | return nullptr; |
7c673cae | 1130 | } |
494da23a | 1131 | |
7c673cae FG |
1132 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); |
1133 | ||
494da23a | 1134 | std::string value; |
7c673cae | 1135 | rocksdb::Status s; |
494da23a TL |
1136 | if (column_family_handle != nullptr) { |
1137 | s = db->Get(read_opt, column_family_handle, key_slice, &value); | |
7c673cae FG |
1138 | } else { |
1139 | // backwards compatibility | |
494da23a | 1140 | s = db->Get(read_opt, key_slice, &value); |
7c673cae FG |
1141 | } |
1142 | ||
1143 | // cleanup | |
11fdf7f2 | 1144 | delete[] key; |
7c673cae | 1145 | |
494da23a TL |
1146 | if (s.IsNotFound()) { |
1147 | return nullptr; | |
1148 | } | |
1149 | ||
7c673cae | 1150 | if (s.ok()) { |
494da23a TL |
1151 | jbyteArray jret_value = rocksdb::JniUtil::copyBytes(env, value); |
1152 | if (jret_value == nullptr) { | |
1153 | // exception occurred | |
1154 | return nullptr; | |
1155 | } | |
1156 | return jret_value; | |
7c673cae FG |
1157 | } |
1158 | ||
1159 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
494da23a | 1160 | return nullptr; |
7c673cae FG |
1161 | } |
1162 | ||
1163 | /* | |
1164 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1165 | * Method: get |
1166 | * Signature: (J[BII)[B | |
7c673cae | 1167 | */ |
494da23a TL |
1168 | jbyteArray Java_org_rocksdb_RocksDB_get__J_3BII( |
1169 | JNIEnv* env, jobject, jlong jdb_handle, | |
1170 | jbyteArray jkey, jint jkey_off, jint jkey_len) { | |
1171 | return rocksdb_get_helper(env, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1172 | rocksdb::ReadOptions(), nullptr, jkey, jkey_off, jkey_len); | |
7c673cae FG |
1173 | } |
1174 | ||
1175 | /* | |
1176 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1177 | * Method: get |
1178 | * Signature: (J[BIIJ)[B | |
7c673cae | 1179 | */ |
494da23a TL |
1180 | jbyteArray Java_org_rocksdb_RocksDB_get__J_3BIIJ( |
1181 | JNIEnv* env, jobject, jlong jdb_handle, | |
1182 | jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) { | |
1183 | auto db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1184 | auto cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
7c673cae | 1185 | if (cf_handle != nullptr) { |
494da23a TL |
1186 | return rocksdb_get_helper(env, db_handle, rocksdb::ReadOptions(), cf_handle, |
1187 | jkey, jkey_off, jkey_len); | |
7c673cae | 1188 | } else { |
11fdf7f2 TL |
1189 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1190 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
494da23a | 1191 | return nullptr; |
7c673cae FG |
1192 | } |
1193 | } | |
1194 | ||
1195 | /* | |
1196 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1197 | * Method: get |
1198 | * Signature: (JJ[BII)[B | |
7c673cae | 1199 | */ |
494da23a TL |
1200 | jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BII( |
1201 | JNIEnv* env, jobject, | |
1202 | jlong jdb_handle, jlong jropt_handle, | |
1203 | jbyteArray jkey, jint jkey_off, jint jkey_len) { | |
1204 | return rocksdb_get_helper( | |
1205 | env, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1206 | *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), nullptr, jkey, | |
1207 | jkey_off, jkey_len); | |
7c673cae FG |
1208 | } |
1209 | ||
1210 | /* | |
1211 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1212 | * Method: get |
1213 | * Signature: (JJ[BIIJ)[B | |
7c673cae | 1214 | */ |
494da23a TL |
1215 | jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BIIJ( |
1216 | JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle, | |
11fdf7f2 | 1217 | jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle) { |
494da23a TL |
1218 | auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
1219 | auto& ro_opt = *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle); | |
7c673cae FG |
1220 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
1221 | if (cf_handle != nullptr) { | |
494da23a TL |
1222 | return rocksdb_get_helper( |
1223 | env, db_handle, ro_opt, cf_handle, jkey, jkey_off, jkey_len); | |
7c673cae | 1224 | } else { |
11fdf7f2 TL |
1225 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1226 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
494da23a | 1227 | return nullptr; |
7c673cae FG |
1228 | } |
1229 | } | |
1230 | ||
494da23a TL |
1231 | jint rocksdb_get_helper( |
1232 | JNIEnv* env, rocksdb::DB* db, const rocksdb::ReadOptions& read_options, | |
1233 | rocksdb::ColumnFamilyHandle* column_family_handle, | |
1234 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1235 | jbyteArray jval, jint jval_off, jint jval_len, | |
1236 | bool* has_exception) { | |
1237 | static const int kNotFound = -1; | |
1238 | static const int kStatusError = -2; | |
1239 | ||
1240 | jbyte* key = new jbyte[jkey_len]; | |
1241 | env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key); | |
1242 | if (env->ExceptionCheck()) { | |
7c673cae | 1243 | // exception thrown: OutOfMemoryError |
494da23a TL |
1244 | delete[] key; |
1245 | *has_exception = true; | |
1246 | return kStatusError; | |
7c673cae FG |
1247 | } |
1248 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); | |
1249 | ||
494da23a TL |
1250 | // TODO(yhchiang): we might save one memory allocation here by adding |
1251 | // a DB::Get() function which takes preallocated jbyte* as input. | |
1252 | std::string cvalue; | |
7c673cae | 1253 | rocksdb::Status s; |
494da23a TL |
1254 | if (column_family_handle != nullptr) { |
1255 | s = db->Get(read_options, column_family_handle, key_slice, &cvalue); | |
7c673cae FG |
1256 | } else { |
1257 | // backwards compatibility | |
494da23a | 1258 | s = db->Get(read_options, key_slice, &cvalue); |
7c673cae FG |
1259 | } |
1260 | ||
494da23a TL |
1261 | // cleanup |
1262 | delete[] key; | |
7c673cae | 1263 | |
494da23a TL |
1264 | if (s.IsNotFound()) { |
1265 | *has_exception = false; | |
1266 | return kNotFound; | |
1267 | } else if (!s.ok()) { | |
1268 | *has_exception = true; | |
1269 | // Here since we are throwing a Java exception from c++ side. | |
1270 | // As a result, c++ does not know calling this function will in fact | |
1271 | // throwing an exception. As a result, the execution flow will | |
1272 | // not stop here, and codes after this throw will still be | |
1273 | // executed. | |
1274 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
1275 | ||
1276 | // Return a dummy const value to avoid compilation error, although | |
1277 | // java side might not have a chance to get the return value :) | |
1278 | return kStatusError; | |
1279 | } | |
1280 | ||
1281 | const jint cvalue_len = static_cast<jint>(cvalue.size()); | |
1282 | const jint length = std::min(jval_len, cvalue_len); | |
1283 | ||
1284 | env->SetByteArrayRegion( | |
1285 | jval, jval_off, length, | |
1286 | const_cast<jbyte*>(reinterpret_cast<const jbyte*>(cvalue.c_str()))); | |
1287 | if (env->ExceptionCheck()) { | |
1288 | // exception thrown: OutOfMemoryError | |
1289 | *has_exception = true; | |
1290 | return kStatusError; | |
7c673cae FG |
1291 | } |
1292 | ||
494da23a TL |
1293 | *has_exception = false; |
1294 | return cvalue_len; | |
7c673cae FG |
1295 | } |
1296 | ||
494da23a | 1297 | |
7c673cae FG |
1298 | /* |
1299 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1300 | * Method: get |
1301 | * Signature: (J[BII[BII)I | |
7c673cae | 1302 | */ |
494da23a TL |
1303 | jint Java_org_rocksdb_RocksDB_get__J_3BII_3BII( |
1304 | JNIEnv* env, jobject, jlong jdb_handle, | |
1305 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1306 | jbyteArray jval, jint jval_off, jint jval_len) { | |
1307 | bool has_exception = false; | |
1308 | return rocksdb_get_helper(env, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1309 | rocksdb::ReadOptions(), nullptr, jkey, jkey_off, | |
1310 | jkey_len, jval, jval_off, jval_len, &has_exception); | |
7c673cae FG |
1311 | } |
1312 | ||
1313 | /* | |
1314 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1315 | * Method: get |
1316 | * Signature: (J[BII[BIIJ)I | |
7c673cae | 1317 | */ |
494da23a TL |
1318 | jint Java_org_rocksdb_RocksDB_get__J_3BII_3BIIJ( |
1319 | JNIEnv* env, jobject, jlong jdb_handle, | |
1320 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1321 | jbyteArray jval, jint jval_off, jint jval_len, | |
1322 | jlong jcf_handle) { | |
1323 | auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
7c673cae FG |
1324 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
1325 | if (cf_handle != nullptr) { | |
494da23a TL |
1326 | bool has_exception = false; |
1327 | return rocksdb_get_helper(env, db_handle, rocksdb::ReadOptions(), cf_handle, | |
1328 | jkey, jkey_off, jkey_len, jval, jval_off, | |
1329 | jval_len, &has_exception); | |
7c673cae | 1330 | } else { |
11fdf7f2 TL |
1331 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1332 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
494da23a TL |
1333 | // will never be evaluated |
1334 | return 0; | |
7c673cae FG |
1335 | } |
1336 | } | |
1337 | ||
1338 | /* | |
1339 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1340 | * Method: get |
1341 | * Signature: (JJ[BII[BII)I | |
7c673cae | 1342 | */ |
494da23a TL |
1343 | jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BII( |
1344 | JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle, | |
1345 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1346 | jbyteArray jval, jint jval_off, jint jval_len) { | |
1347 | bool has_exception = false; | |
1348 | return rocksdb_get_helper( | |
1349 | env, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1350 | *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), nullptr, jkey, | |
1351 | jkey_off, jkey_len, jval, jval_off, jval_len, &has_exception); | |
7c673cae FG |
1352 | } |
1353 | ||
1354 | /* | |
1355 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1356 | * Method: get |
1357 | * Signature: (JJ[BII[BIIJ)I | |
7c673cae | 1358 | */ |
494da23a TL |
1359 | jint Java_org_rocksdb_RocksDB_get__JJ_3BII_3BIIJ( |
1360 | JNIEnv* env, jobject, jlong jdb_handle, jlong jropt_handle, | |
1361 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1362 | jbyteArray jval, jint jval_off, jint jval_len, | |
1363 | jlong jcf_handle) { | |
1364 | auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1365 | auto& ro_opt = *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle); | |
7c673cae FG |
1366 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
1367 | if (cf_handle != nullptr) { | |
494da23a TL |
1368 | bool has_exception = false; |
1369 | return rocksdb_get_helper(env, db_handle, ro_opt, cf_handle, | |
1370 | jkey, jkey_off, jkey_len, | |
1371 | jval, jval_off, jval_len, | |
1372 | &has_exception); | |
7c673cae | 1373 | } else { |
11fdf7f2 TL |
1374 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1375 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
494da23a TL |
1376 | // will never be evaluated |
1377 | return 0; | |
7c673cae FG |
1378 | } |
1379 | } | |
1380 | ||
494da23a TL |
1381 | inline void multi_get_helper_release_keys( |
1382 | JNIEnv* env, std::vector<std::pair<jbyte*, jobject>>& keys_to_free) { | |
1383 | auto end = keys_to_free.end(); | |
1384 | for (auto it = keys_to_free.begin(); it != end; ++it) { | |
1385 | delete[] it->first; | |
1386 | env->DeleteLocalRef(it->second); | |
1387 | } | |
1388 | keys_to_free.clear(); | |
1389 | } | |
1390 | ||
7c673cae | 1391 | /** |
494da23a TL |
1392 | * cf multi get |
1393 | * | |
1394 | * @return byte[][] of values or nullptr if an exception occurs | |
7c673cae | 1395 | */ |
494da23a TL |
1396 | jobjectArray multi_get_helper( |
1397 | JNIEnv* env, jobject, rocksdb::DB* db, const rocksdb::ReadOptions& rOpt, | |
1398 | jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens, | |
1399 | jlongArray jcolumn_family_handles) { | |
1400 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; | |
1401 | if (jcolumn_family_handles != nullptr) { | |
1402 | const jsize len_cols = env->GetArrayLength(jcolumn_family_handles); | |
1403 | ||
1404 | jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr); | |
1405 | if (jcfh == nullptr) { | |
1406 | // exception thrown: OutOfMemoryError | |
1407 | return nullptr; | |
1408 | } | |
1409 | ||
1410 | for (jsize i = 0; i < len_cols; i++) { | |
1411 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]); | |
1412 | cf_handles.push_back(cf_handle); | |
1413 | } | |
1414 | env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT); | |
7c673cae | 1415 | } |
7c673cae | 1416 | |
494da23a TL |
1417 | const jsize len_keys = env->GetArrayLength(jkeys); |
1418 | if (env->EnsureLocalCapacity(len_keys) != 0) { | |
1419 | // exception thrown: OutOfMemoryError | |
1420 | return nullptr; | |
7c673cae | 1421 | } |
7c673cae | 1422 | |
494da23a TL |
1423 | jint* jkey_off = env->GetIntArrayElements(jkey_offs, nullptr); |
1424 | if (jkey_off == nullptr) { | |
1425 | // exception thrown: OutOfMemoryError | |
1426 | return nullptr; | |
1427 | } | |
7c673cae | 1428 | |
494da23a TL |
1429 | jint* jkey_len = env->GetIntArrayElements(jkey_lens, nullptr); |
1430 | if (jkey_len == nullptr) { | |
1431 | // exception thrown: OutOfMemoryError | |
1432 | env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT); | |
1433 | return nullptr; | |
1434 | } | |
7c673cae | 1435 | |
494da23a TL |
1436 | std::vector<rocksdb::Slice> keys; |
1437 | std::vector<std::pair<jbyte*, jobject>> keys_to_free; | |
1438 | for (jsize i = 0; i < len_keys; i++) { | |
1439 | jobject jkey = env->GetObjectArrayElement(jkeys, i); | |
1440 | if (env->ExceptionCheck()) { | |
1441 | // exception thrown: ArrayIndexOutOfBoundsException | |
1442 | env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT); | |
1443 | env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT); | |
1444 | multi_get_helper_release_keys(env, keys_to_free); | |
1445 | return nullptr; | |
1446 | } | |
1447 | ||
1448 | jbyteArray jkey_ba = reinterpret_cast<jbyteArray>(jkey); | |
1449 | ||
1450 | const jint len_key = jkey_len[i]; | |
1451 | jbyte* key = new jbyte[len_key]; | |
1452 | env->GetByteArrayRegion(jkey_ba, jkey_off[i], len_key, key); | |
1453 | if (env->ExceptionCheck()) { | |
1454 | // exception thrown: ArrayIndexOutOfBoundsException | |
1455 | delete[] key; | |
1456 | env->DeleteLocalRef(jkey); | |
1457 | env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT); | |
1458 | env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT); | |
1459 | multi_get_helper_release_keys(env, keys_to_free); | |
1460 | return nullptr; | |
1461 | } | |
1462 | ||
1463 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), len_key); | |
1464 | keys.push_back(key_slice); | |
1465 | ||
1466 | keys_to_free.push_back(std::pair<jbyte*, jobject>(key, jkey)); | |
7c673cae FG |
1467 | } |
1468 | ||
494da23a TL |
1469 | // cleanup jkey_off and jken_len |
1470 | env->ReleaseIntArrayElements(jkey_lens, jkey_len, JNI_ABORT); | |
1471 | env->ReleaseIntArrayElements(jkey_offs, jkey_off, JNI_ABORT); | |
7c673cae | 1472 | |
494da23a TL |
1473 | std::vector<std::string> values; |
1474 | std::vector<rocksdb::Status> s; | |
1475 | if (cf_handles.size() == 0) { | |
1476 | s = db->MultiGet(rOpt, keys, &values); | |
1477 | } else { | |
1478 | s = db->MultiGet(rOpt, cf_handles, keys, &values); | |
1479 | } | |
1480 | ||
1481 | // free up allocated byte arrays | |
1482 | multi_get_helper_release_keys(env, keys_to_free); | |
1483 | ||
1484 | // prepare the results | |
1485 | jobjectArray jresults = | |
1486 | rocksdb::ByteJni::new2dByteArray(env, static_cast<jsize>(s.size())); | |
1487 | if (jresults == nullptr) { | |
1488 | // exception occurred | |
1489 | return nullptr; | |
1490 | } | |
1491 | ||
1492 | // TODO(AR) it is not clear to me why EnsureLocalCapacity is needed for the | |
1493 | // loop as we cleanup references with env->DeleteLocalRef(jentry_value); | |
1494 | if (env->EnsureLocalCapacity(static_cast<jint>(s.size())) != 0) { | |
1495 | // exception thrown: OutOfMemoryError | |
1496 | return nullptr; | |
1497 | } | |
1498 | // add to the jresults | |
1499 | for (std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) { | |
1500 | if (s[i].ok()) { | |
1501 | std::string* value = &values[i]; | |
1502 | const jsize jvalue_len = static_cast<jsize>(value->size()); | |
1503 | jbyteArray jentry_value = env->NewByteArray(jvalue_len); | |
1504 | if (jentry_value == nullptr) { | |
1505 | // exception thrown: OutOfMemoryError | |
1506 | return nullptr; | |
1507 | } | |
1508 | ||
1509 | env->SetByteArrayRegion( | |
1510 | jentry_value, 0, static_cast<jsize>(jvalue_len), | |
1511 | const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value->c_str()))); | |
1512 | if (env->ExceptionCheck()) { | |
1513 | // exception thrown: ArrayIndexOutOfBoundsException | |
1514 | env->DeleteLocalRef(jentry_value); | |
1515 | return nullptr; | |
1516 | } | |
1517 | ||
1518 | env->SetObjectArrayElement(jresults, static_cast<jsize>(i), jentry_value); | |
1519 | if (env->ExceptionCheck()) { | |
1520 | // exception thrown: ArrayIndexOutOfBoundsException | |
1521 | env->DeleteLocalRef(jentry_value); | |
1522 | return nullptr; | |
1523 | } | |
1524 | ||
1525 | env->DeleteLocalRef(jentry_value); | |
1526 | } | |
1527 | } | |
1528 | ||
1529 | return jresults; | |
7c673cae FG |
1530 | } |
1531 | ||
1532 | /* | |
1533 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1534 | * Method: multiGet |
1535 | * Signature: (J[[B[I[I)[[B | |
7c673cae | 1536 | */ |
494da23a TL |
1537 | jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I( |
1538 | JNIEnv* env, jobject jdb, jlong jdb_handle, | |
1539 | jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) { | |
1540 | return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1541 | rocksdb::ReadOptions(), jkeys, jkey_offs, jkey_lens, | |
1542 | nullptr); | |
7c673cae FG |
1543 | } |
1544 | ||
1545 | /* | |
1546 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1547 | * Method: multiGet |
1548 | * Signature: (J[[B[I[I[J)[[B | |
7c673cae | 1549 | */ |
494da23a TL |
1550 | jobjectArray Java_org_rocksdb_RocksDB_multiGet__J_3_3B_3I_3I_3J( |
1551 | JNIEnv* env, jobject jdb, jlong jdb_handle, | |
1552 | jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens, | |
1553 | jlongArray jcolumn_family_handles) { | |
1554 | return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1555 | rocksdb::ReadOptions(), jkeys, jkey_offs, jkey_lens, | |
1556 | jcolumn_family_handles); | |
7c673cae FG |
1557 | } |
1558 | ||
1559 | /* | |
1560 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1561 | * Method: multiGet |
1562 | * Signature: (JJ[[B[I[I)[[B | |
7c673cae | 1563 | */ |
494da23a TL |
1564 | jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I( |
1565 | JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle, | |
1566 | jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens) { | |
1567 | return multi_get_helper( | |
1568 | env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1569 | *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkeys, jkey_offs, | |
1570 | jkey_lens, nullptr); | |
7c673cae FG |
1571 | } |
1572 | ||
494da23a TL |
1573 | /* |
1574 | * Class: org_rocksdb_RocksDB | |
1575 | * Method: multiGet | |
1576 | * Signature: (JJ[[B[I[I[J)[[B | |
7c673cae | 1577 | */ |
494da23a TL |
1578 | jobjectArray Java_org_rocksdb_RocksDB_multiGet__JJ_3_3B_3I_3I_3J( |
1579 | JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle, | |
1580 | jobjectArray jkeys, jintArray jkey_offs, jintArray jkey_lens, | |
1581 | jlongArray jcolumn_family_handles) { | |
1582 | return multi_get_helper( | |
1583 | env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle), | |
1584 | *reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkeys, jkey_offs, | |
1585 | jkey_lens, jcolumn_family_handles); | |
1586 | } | |
1587 | ||
1588 | ////////////////////////////////////////////////////////////////////////////// | |
1589 | // rocksdb::DB::KeyMayExist | |
1590 | jboolean key_may_exist_helper(JNIEnv* env, rocksdb::DB* db, | |
1591 | const rocksdb::ReadOptions& read_opt, | |
1592 | rocksdb::ColumnFamilyHandle* cf_handle, | |
1593 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1594 | jobject jstring_builder, bool* has_exception) { | |
7c673cae FG |
1595 | jbyte* key = new jbyte[jkey_len]; |
1596 | env->GetByteArrayRegion(jkey, jkey_off, jkey_len, key); | |
11fdf7f2 | 1597 | if (env->ExceptionCheck()) { |
7c673cae | 1598 | // exception thrown: ArrayIndexOutOfBoundsException |
11fdf7f2 | 1599 | delete[] key; |
494da23a | 1600 | *has_exception = true; |
7c673cae FG |
1601 | return false; |
1602 | } | |
7c673cae | 1603 | |
494da23a | 1604 | rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len); |
7c673cae | 1605 | |
494da23a TL |
1606 | std::string value; |
1607 | bool value_found = false; | |
1608 | bool keyMayExist; | |
7c673cae | 1609 | if (cf_handle != nullptr) { |
494da23a TL |
1610 | keyMayExist = |
1611 | db->KeyMayExist(read_opt, cf_handle, key_slice, &value, &value_found); | |
7c673cae | 1612 | } else { |
494da23a | 1613 | keyMayExist = db->KeyMayExist(read_opt, key_slice, &value, &value_found); |
7c673cae FG |
1614 | } |
1615 | ||
1616 | // cleanup | |
11fdf7f2 | 1617 | delete[] key; |
7c673cae | 1618 | |
494da23a TL |
1619 | // extract the value |
1620 | if (value_found && !value.empty()) { | |
1621 | jobject jresult_string_builder = | |
1622 | rocksdb::StringBuilderJni::append(env, jstring_builder, value.c_str()); | |
1623 | if (jresult_string_builder == nullptr) { | |
1624 | *has_exception = true; | |
1625 | return false; | |
1626 | } | |
7c673cae FG |
1627 | } |
1628 | ||
494da23a TL |
1629 | *has_exception = false; |
1630 | return static_cast<jboolean>(keyMayExist); | |
7c673cae FG |
1631 | } |
1632 | ||
1633 | /* | |
1634 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1635 | * Method: keyMayExist |
1636 | * Signature: (J[BIILjava/lang/StringBuilder;)Z | |
7c673cae | 1637 | */ |
494da23a TL |
1638 | jboolean Java_org_rocksdb_RocksDB_keyMayExist__J_3BIILjava_lang_StringBuilder_2( |
1639 | JNIEnv* env, jobject, jlong jdb_handle, | |
1640 | jbyteArray jkey, jint jkey_off, jint jkey_len, jobject jstring_builder) { | |
7c673cae | 1641 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
1642 | bool has_exception = false; |
1643 | return key_may_exist_helper(env, db, rocksdb::ReadOptions(), nullptr, jkey, | |
1644 | jkey_off, jkey_len, jstring_builder, &has_exception); | |
7c673cae FG |
1645 | } |
1646 | ||
1647 | /* | |
1648 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1649 | * Method: keyMayExist |
1650 | * Signature: (J[BIIJLjava/lang/StringBuilder;)Z | |
7c673cae | 1651 | */ |
494da23a TL |
1652 | jboolean |
1653 | Java_org_rocksdb_RocksDB_keyMayExist__J_3BIIJLjava_lang_StringBuilder_2( | |
1654 | JNIEnv* env, jobject, jlong jdb_handle, | |
1655 | jbyteArray jkey, jint jkey_off, jint jkey_len, | |
1656 | jlong jcf_handle, jobject jstring_builder) { | |
7c673cae | 1657 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
7c673cae FG |
1658 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
1659 | if (cf_handle != nullptr) { | |
494da23a TL |
1660 | bool has_exception = false; |
1661 | return key_may_exist_helper(env, db, rocksdb::ReadOptions(), cf_handle, | |
1662 | jkey, jkey_off, jkey_len, jstring_builder, | |
1663 | &has_exception); | |
7c673cae | 1664 | } else { |
11fdf7f2 TL |
1665 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1666 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
494da23a | 1667 | return true; |
7c673cae FG |
1668 | } |
1669 | } | |
1670 | ||
1671 | /* | |
1672 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1673 | * Method: keyMayExist |
1674 | * Signature: (JJ[BIILjava/lang/StringBuilder;)Z | |
7c673cae | 1675 | */ |
494da23a TL |
1676 | jboolean |
1677 | Java_org_rocksdb_RocksDB_keyMayExist__JJ_3BIILjava_lang_StringBuilder_2( | |
1678 | JNIEnv* env, jobject, jlong jdb_handle, jlong jread_options_handle, | |
1679 | jbyteArray jkey, jint jkey_off, jint jkey_len, jobject jstring_builder) { | |
7c673cae | 1680 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
1681 | auto& read_options = |
1682 | *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle); | |
1683 | bool has_exception = false; | |
1684 | return key_may_exist_helper(env, db, read_options, nullptr, jkey, jkey_off, | |
1685 | jkey_len, jstring_builder, &has_exception); | |
7c673cae FG |
1686 | } |
1687 | ||
1688 | /* | |
1689 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1690 | * Method: keyMayExist |
1691 | * Signature: (JJ[BIIJLjava/lang/StringBuilder;)Z | |
7c673cae | 1692 | */ |
494da23a TL |
1693 | jboolean |
1694 | Java_org_rocksdb_RocksDB_keyMayExist__JJ_3BIIJLjava_lang_StringBuilder_2( | |
1695 | JNIEnv* env, jobject, jlong jdb_handle, jlong jread_options_handle, | |
1696 | jbyteArray jkey, jint jkey_off, jint jkey_len, jlong jcf_handle, | |
1697 | jobject jstring_builder) { | |
7c673cae | 1698 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
1699 | auto& read_options = |
1700 | *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle); | |
7c673cae FG |
1701 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
1702 | if (cf_handle != nullptr) { | |
494da23a TL |
1703 | bool has_exception = false; |
1704 | return key_may_exist_helper(env, db, read_options, cf_handle, jkey, | |
1705 | jkey_off, jkey_len, jstring_builder, &has_exception); | |
7c673cae | 1706 | } else { |
11fdf7f2 TL |
1707 | rocksdb::RocksDBExceptionJni::ThrowNew( |
1708 | env, rocksdb::Status::InvalidArgument("Invalid ColumnFamilyHandle.")); | |
494da23a | 1709 | return true; |
7c673cae FG |
1710 | } |
1711 | } | |
1712 | ||
7c673cae FG |
1713 | /* |
1714 | * Class: org_rocksdb_RocksDB | |
1715 | * Method: iterator | |
1716 | * Signature: (J)J | |
1717 | */ | |
494da23a TL |
1718 | jlong Java_org_rocksdb_RocksDB_iterator__J( |
1719 | JNIEnv*, jobject, jlong db_handle) { | |
7c673cae | 1720 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
11fdf7f2 | 1721 | return rocksdb_iterator_helper(db, rocksdb::ReadOptions(), nullptr); |
7c673cae FG |
1722 | } |
1723 | ||
1724 | /* | |
1725 | * Class: org_rocksdb_RocksDB | |
1726 | * Method: iterator | |
1727 | * Signature: (JJ)J | |
1728 | */ | |
494da23a TL |
1729 | jlong Java_org_rocksdb_RocksDB_iterator__JJ( |
1730 | JNIEnv*, jobject, jlong db_handle, jlong jread_options_handle) { | |
7c673cae | 1731 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
11fdf7f2 TL |
1732 | auto& read_options = |
1733 | *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle); | |
1734 | return rocksdb_iterator_helper(db, read_options, nullptr); | |
7c673cae FG |
1735 | } |
1736 | ||
1737 | /* | |
1738 | * Class: org_rocksdb_RocksDB | |
1739 | * Method: iteratorCF | |
1740 | * Signature: (JJ)J | |
1741 | */ | |
494da23a TL |
1742 | jlong Java_org_rocksdb_RocksDB_iteratorCF__JJ( |
1743 | JNIEnv*, jobject, jlong db_handle, jlong jcf_handle) { | |
7c673cae FG |
1744 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
1745 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
11fdf7f2 | 1746 | return rocksdb_iterator_helper(db, rocksdb::ReadOptions(), cf_handle); |
7c673cae FG |
1747 | } |
1748 | ||
1749 | /* | |
1750 | * Class: org_rocksdb_RocksDB | |
1751 | * Method: iteratorCF | |
1752 | * Signature: (JJJ)J | |
1753 | */ | |
494da23a TL |
1754 | jlong Java_org_rocksdb_RocksDB_iteratorCF__JJJ( |
1755 | JNIEnv*, jobject, | |
1756 | jlong db_handle, jlong jcf_handle, jlong jread_options_handle) { | |
7c673cae FG |
1757 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
1758 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
11fdf7f2 TL |
1759 | auto& read_options = |
1760 | *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle); | |
1761 | return rocksdb_iterator_helper(db, read_options, cf_handle); | |
7c673cae FG |
1762 | } |
1763 | ||
1764 | /* | |
1765 | * Class: org_rocksdb_RocksDB | |
1766 | * Method: iterators | |
1767 | * Signature: (J[JJ)[J | |
1768 | */ | |
494da23a TL |
1769 | jlongArray Java_org_rocksdb_RocksDB_iterators( |
1770 | JNIEnv* env, jobject, jlong db_handle, | |
1771 | jlongArray jcolumn_family_handles, | |
1772 | jlong jread_options_handle) { | |
7c673cae | 1773 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
11fdf7f2 TL |
1774 | auto& read_options = |
1775 | *reinterpret_cast<rocksdb::ReadOptions*>(jread_options_handle); | |
7c673cae FG |
1776 | |
1777 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; | |
1778 | if (jcolumn_family_handles != nullptr) { | |
1779 | const jsize len_cols = env->GetArrayLength(jcolumn_family_handles); | |
1780 | jlong* jcfh = env->GetLongArrayElements(jcolumn_family_handles, nullptr); | |
11fdf7f2 | 1781 | if (jcfh == nullptr) { |
7c673cae FG |
1782 | // exception thrown: OutOfMemoryError |
1783 | return nullptr; | |
1784 | } | |
1785 | ||
1786 | for (jsize i = 0; i < len_cols; i++) { | |
11fdf7f2 | 1787 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcfh[i]); |
7c673cae FG |
1788 | cf_handles.push_back(cf_handle); |
1789 | } | |
1790 | ||
1791 | env->ReleaseLongArrayElements(jcolumn_family_handles, jcfh, JNI_ABORT); | |
1792 | } | |
1793 | ||
1794 | std::vector<rocksdb::Iterator*> iterators; | |
11fdf7f2 | 1795 | rocksdb::Status s = db->NewIterators(read_options, cf_handles, &iterators); |
7c673cae FG |
1796 | if (s.ok()) { |
1797 | jlongArray jLongArray = | |
1798 | env->NewLongArray(static_cast<jsize>(iterators.size())); | |
11fdf7f2 | 1799 | if (jLongArray == nullptr) { |
7c673cae FG |
1800 | // exception thrown: OutOfMemoryError |
1801 | return nullptr; | |
1802 | } | |
1803 | ||
11fdf7f2 TL |
1804 | for (std::vector<rocksdb::Iterator*>::size_type i = 0; i < iterators.size(); |
1805 | i++) { | |
1806 | env->SetLongArrayRegion( | |
1807 | jLongArray, static_cast<jsize>(i), 1, | |
1808 | const_cast<jlong*>(reinterpret_cast<const jlong*>(&iterators[i]))); | |
1809 | if (env->ExceptionCheck()) { | |
7c673cae FG |
1810 | // exception thrown: ArrayIndexOutOfBoundsException |
1811 | env->DeleteLocalRef(jLongArray); | |
1812 | return nullptr; | |
1813 | } | |
1814 | } | |
1815 | ||
1816 | return jLongArray; | |
1817 | } else { | |
1818 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
1819 | return nullptr; | |
1820 | } | |
1821 | } | |
1822 | ||
7c673cae FG |
1823 | /* |
1824 | * Method: getSnapshot | |
1825 | * Signature: (J)J | |
1826 | */ | |
494da23a TL |
1827 | jlong Java_org_rocksdb_RocksDB_getSnapshot( |
1828 | JNIEnv*, jobject, jlong db_handle) { | |
7c673cae FG |
1829 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
1830 | const rocksdb::Snapshot* snapshot = db->GetSnapshot(); | |
1831 | return reinterpret_cast<jlong>(snapshot); | |
1832 | } | |
1833 | ||
1834 | /* | |
1835 | * Method: releaseSnapshot | |
1836 | * Signature: (JJ)V | |
1837 | */ | |
494da23a TL |
1838 | void Java_org_rocksdb_RocksDB_releaseSnapshot( |
1839 | JNIEnv*, jobject, jlong db_handle, | |
1840 | jlong snapshot_handle) { | |
7c673cae FG |
1841 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
1842 | auto* snapshot = reinterpret_cast<rocksdb::Snapshot*>(snapshot_handle); | |
1843 | db->ReleaseSnapshot(snapshot); | |
1844 | } | |
1845 | ||
1846 | /* | |
1847 | * Class: org_rocksdb_RocksDB | |
494da23a | 1848 | * Method: getProperty |
7c673cae FG |
1849 | * Signature: (JJLjava/lang/String;I)Ljava/lang/String; |
1850 | */ | |
494da23a TL |
1851 | jstring Java_org_rocksdb_RocksDB_getProperty( |
1852 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
7c673cae FG |
1853 | jstring jproperty, jint jproperty_len) { |
1854 | const char* property = env->GetStringUTFChars(jproperty, nullptr); | |
11fdf7f2 | 1855 | if (property == nullptr) { |
7c673cae FG |
1856 | // exception thrown: OutOfMemoryError |
1857 | return nullptr; | |
1858 | } | |
494da23a TL |
1859 | rocksdb::Slice property_name(property, jproperty_len); |
1860 | ||
1861 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1862 | rocksdb::ColumnFamilyHandle* cf_handle; | |
1863 | if (jcf_handle == 0) { | |
1864 | cf_handle = db->DefaultColumnFamily(); | |
1865 | } else { | |
1866 | cf_handle = | |
1867 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
1868 | } | |
7c673cae | 1869 | |
7c673cae | 1870 | std::string property_value; |
494da23a | 1871 | bool retCode = db->GetProperty(cf_handle, property_name, &property_value); |
7c673cae FG |
1872 | env->ReleaseStringUTFChars(jproperty, property); |
1873 | ||
1874 | if (retCode) { | |
1875 | return env->NewStringUTF(property_value.c_str()); | |
1876 | } | |
1877 | ||
1878 | rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound()); | |
1879 | return nullptr; | |
1880 | } | |
1881 | ||
1882 | /* | |
1883 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
1884 | * Method: getMapProperty |
1885 | * Signature: (JJLjava/lang/String;I)Ljava/util/Map; | |
7c673cae | 1886 | */ |
494da23a TL |
1887 | jobject Java_org_rocksdb_RocksDB_getMapProperty( |
1888 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
1889 | jstring jproperty, jint jproperty_len) { | |
1890 | const char* property = env->GetStringUTFChars(jproperty, nullptr); | |
11fdf7f2 | 1891 | if (property == nullptr) { |
7c673cae | 1892 | // exception thrown: OutOfMemoryError |
494da23a TL |
1893 | return nullptr; |
1894 | } | |
1895 | rocksdb::Slice property_name(property, jproperty_len); | |
1896 | ||
1897 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1898 | rocksdb::ColumnFamilyHandle* cf_handle; | |
1899 | if (jcf_handle == 0) { | |
1900 | cf_handle = db->DefaultColumnFamily(); | |
1901 | } else { | |
1902 | cf_handle = | |
1903 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
7c673cae | 1904 | } |
7c673cae | 1905 | |
494da23a TL |
1906 | std::map<std::string, std::string> property_value; |
1907 | bool retCode = db->GetMapProperty(cf_handle, property_name, &property_value); | |
7c673cae FG |
1908 | env->ReleaseStringUTFChars(jproperty, property); |
1909 | ||
1910 | if (retCode) { | |
494da23a | 1911 | return rocksdb::HashMapJni::fromCppMap(env, &property_value); |
7c673cae FG |
1912 | } |
1913 | ||
1914 | rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound()); | |
494da23a | 1915 | return nullptr; |
7c673cae FG |
1916 | } |
1917 | ||
1918 | /* | |
1919 | * Class: org_rocksdb_RocksDB | |
1920 | * Method: getLongProperty | |
494da23a | 1921 | * Signature: (JJLjava/lang/String;I)J |
7c673cae | 1922 | */ |
494da23a TL |
1923 | jlong Java_org_rocksdb_RocksDB_getLongProperty( |
1924 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
7c673cae FG |
1925 | jstring jproperty, jint jproperty_len) { |
1926 | const char* property = env->GetStringUTFChars(jproperty, nullptr); | |
11fdf7f2 | 1927 | if (property == nullptr) { |
7c673cae FG |
1928 | // exception thrown: OutOfMemoryError |
1929 | return 0; | |
1930 | } | |
494da23a TL |
1931 | rocksdb::Slice property_name(property, jproperty_len); |
1932 | ||
1933 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1934 | rocksdb::ColumnFamilyHandle* cf_handle; | |
1935 | if (jcf_handle == 0) { | |
1936 | cf_handle = db->DefaultColumnFamily(); | |
1937 | } else { | |
1938 | cf_handle = | |
1939 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
1940 | } | |
7c673cae | 1941 | |
7c673cae | 1942 | uint64_t property_value; |
494da23a | 1943 | bool retCode = db->GetIntProperty(cf_handle, property_name, &property_value); |
7c673cae FG |
1944 | env->ReleaseStringUTFChars(jproperty, property); |
1945 | ||
1946 | if (retCode) { | |
1947 | return property_value; | |
1948 | } | |
1949 | ||
1950 | rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound()); | |
1951 | return 0; | |
1952 | } | |
1953 | ||
494da23a TL |
1954 | /* |
1955 | * Class: org_rocksdb_RocksDB | |
1956 | * Method: resetStats | |
1957 | * Signature: (J)V | |
1958 | */ | |
1959 | void Java_org_rocksdb_RocksDB_resetStats( | |
1960 | JNIEnv *, jobject, jlong jdb_handle) { | |
1961 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
1962 | db->ResetStats(); | |
1963 | } | |
1964 | ||
11fdf7f2 TL |
1965 | /* |
1966 | * Class: org_rocksdb_RocksDB | |
1967 | * Method: getAggregatedLongProperty | |
1968 | * Signature: (JLjava/lang/String;I)J | |
1969 | */ | |
1970 | jlong Java_org_rocksdb_RocksDB_getAggregatedLongProperty( | |
494da23a TL |
1971 | JNIEnv* env, jobject, jlong db_handle, |
1972 | jstring jproperty, jint jproperty_len) { | |
11fdf7f2 TL |
1973 | const char* property = env->GetStringUTFChars(jproperty, nullptr); |
1974 | if (property == nullptr) { | |
1975 | return 0; | |
1976 | } | |
494da23a | 1977 | rocksdb::Slice property_name(property, jproperty_len); |
11fdf7f2 TL |
1978 | auto* db = reinterpret_cast<rocksdb::DB*>(db_handle); |
1979 | uint64_t property_value = 0; | |
494da23a | 1980 | bool retCode = db->GetAggregatedIntProperty(property_name, &property_value); |
11fdf7f2 TL |
1981 | env->ReleaseStringUTFChars(jproperty, property); |
1982 | ||
1983 | if (retCode) { | |
1984 | return property_value; | |
1985 | } | |
1986 | ||
1987 | rocksdb::RocksDBExceptionJni::ThrowNew(env, rocksdb::Status::NotFound()); | |
1988 | return 0; | |
1989 | } | |
1990 | ||
494da23a TL |
1991 | /* |
1992 | * Class: org_rocksdb_RocksDB | |
1993 | * Method: getApproximateSizes | |
1994 | * Signature: (JJ[JB)[J | |
1995 | */ | |
1996 | jlongArray Java_org_rocksdb_RocksDB_getApproximateSizes( | |
1997 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
1998 | jlongArray jrange_slice_handles, jbyte jinclude_flags) { | |
1999 | const jsize jlen = env->GetArrayLength(jrange_slice_handles); | |
2000 | const size_t range_count = jlen / 2; | |
11fdf7f2 | 2001 | |
494da23a TL |
2002 | jboolean jranges_is_copy = JNI_FALSE; |
2003 | jlong* jranges = env->GetLongArrayElements(jrange_slice_handles, | |
2004 | &jranges_is_copy); | |
2005 | if (jranges == nullptr) { | |
2006 | // exception thrown: OutOfMemoryError | |
2007 | return nullptr; | |
2008 | } | |
7c673cae | 2009 | |
494da23a TL |
2010 | auto ranges = std::unique_ptr<rocksdb::Range[]>( |
2011 | new rocksdb::Range[range_count]); | |
2012 | for (jsize i = 0; i < jlen; ++i) { | |
2013 | auto* start = reinterpret_cast<rocksdb::Slice*>(jranges[i]); | |
2014 | auto* limit = reinterpret_cast<rocksdb::Slice*>(jranges[++i]); | |
2015 | ranges.get()[i] = rocksdb::Range(*start, *limit); | |
2016 | } | |
2017 | ||
2018 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2019 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2020 | if (jcf_handle == 0) { | |
2021 | cf_handle = db->DefaultColumnFamily(); | |
7c673cae | 2022 | } else { |
494da23a TL |
2023 | cf_handle = |
2024 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
7c673cae | 2025 | } |
494da23a TL |
2026 | |
2027 | auto sizes = std::unique_ptr<uint64_t[]>(new uint64_t[range_count]); | |
2028 | db->GetApproximateSizes(cf_handle, ranges.get(), | |
2029 | static_cast<int>(range_count), sizes.get(), | |
2030 | static_cast<uint8_t>(jinclude_flags)); | |
2031 | ||
2032 | // release LongArrayElements | |
2033 | env->ReleaseLongArrayElements(jrange_slice_handles, jranges, JNI_ABORT); | |
2034 | ||
2035 | // prepare results | |
2036 | auto results = std::unique_ptr<jlong[]>(new jlong[range_count]); | |
2037 | for (size_t i = 0; i < range_count; ++i) { | |
2038 | results.get()[i] = static_cast<jlong>(sizes.get()[i]); | |
2039 | } | |
2040 | ||
2041 | const jsize jrange_count = jlen / 2; | |
2042 | jlongArray jresults = env->NewLongArray(jrange_count); | |
2043 | if (jresults == nullptr) { | |
2044 | // exception thrown: OutOfMemoryError | |
2045 | return nullptr; | |
2046 | } | |
2047 | ||
2048 | env->SetLongArrayRegion(jresults, 0, jrange_count, results.get()); | |
2049 | if (env->ExceptionCheck()) { | |
2050 | // exception thrown: ArrayIndexOutOfBoundsException | |
2051 | env->DeleteLocalRef(jresults); | |
2052 | return nullptr; | |
7c673cae | 2053 | } |
494da23a TL |
2054 | |
2055 | return jresults; | |
7c673cae FG |
2056 | } |
2057 | ||
2058 | /* | |
2059 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2060 | * Method: getApproximateMemTableStats |
2061 | * Signature: (JJJJ)[J | |
7c673cae | 2062 | */ |
494da23a TL |
2063 | jlongArray Java_org_rocksdb_RocksDB_getApproximateMemTableStats( |
2064 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
2065 | jlong jstartHandle, jlong jlimitHandle) { | |
2066 | auto* start = reinterpret_cast<rocksdb::Slice*>(jstartHandle); | |
2067 | auto* limit = reinterpret_cast<rocksdb::Slice*>( jlimitHandle); | |
2068 | const rocksdb::Range range(*start, *limit); | |
2069 | ||
7c673cae | 2070 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
2071 | rocksdb::ColumnFamilyHandle* cf_handle; |
2072 | if (jcf_handle == 0) { | |
2073 | cf_handle = db->DefaultColumnFamily(); | |
2074 | } else { | |
2075 | cf_handle = | |
2076 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2077 | } | |
2078 | ||
2079 | uint64_t count = 0; | |
2080 | uint64_t sizes = 0; | |
2081 | db->GetApproximateMemTableStats(cf_handle, range, &count, &sizes); | |
2082 | ||
2083 | // prepare results | |
2084 | jlong results[2] = { | |
2085 | static_cast<jlong>(count), | |
2086 | static_cast<jlong>(sizes)}; | |
2087 | ||
2088 | const jsize jcount = static_cast<jsize>(count); | |
2089 | jlongArray jsizes = env->NewLongArray(jcount); | |
2090 | if (jsizes == nullptr) { | |
2091 | // exception thrown: OutOfMemoryError | |
2092 | return nullptr; | |
2093 | } | |
2094 | ||
2095 | env->SetLongArrayRegion(jsizes, 0, jcount, results); | |
2096 | if (env->ExceptionCheck()) { | |
2097 | // exception thrown: ArrayIndexOutOfBoundsException | |
2098 | env->DeleteLocalRef(jsizes); | |
2099 | return nullptr; | |
2100 | } | |
2101 | ||
2102 | return jsizes; | |
7c673cae FG |
2103 | } |
2104 | ||
2105 | /* | |
2106 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2107 | * Method: compactRange |
2108 | * Signature: (J[BI[BIJJ)V | |
7c673cae | 2109 | */ |
494da23a TL |
2110 | void Java_org_rocksdb_RocksDB_compactRange( |
2111 | JNIEnv* env, jobject, jlong jdb_handle, | |
2112 | jbyteArray jbegin, jint jbegin_len, | |
2113 | jbyteArray jend, jint jend_len, | |
2114 | jlong jcompact_range_opts_handle, | |
2115 | jlong jcf_handle) { | |
2116 | jboolean has_exception = JNI_FALSE; | |
2117 | ||
2118 | std::string str_begin; | |
2119 | if (jbegin_len > 0) { | |
2120 | str_begin = rocksdb::JniUtil::byteString<std::string>(env, jbegin, jbegin_len, | |
2121 | [](const char* str, const size_t len) { | |
2122 | return std::string(str, len); | |
2123 | }, | |
2124 | &has_exception); | |
2125 | if (has_exception == JNI_TRUE) { | |
2126 | // exception occurred | |
2127 | return; | |
2128 | } | |
2129 | } | |
2130 | ||
2131 | std::string str_end; | |
2132 | if (jend_len > 0) { | |
2133 | str_end = rocksdb::JniUtil::byteString<std::string>(env, jend, jend_len, | |
2134 | [](const char* str, const size_t len) { | |
2135 | return std::string(str, len); | |
2136 | }, | |
2137 | &has_exception); | |
2138 | if (has_exception == JNI_TRUE) { | |
2139 | // exception occurred | |
2140 | return; | |
2141 | } | |
2142 | } | |
2143 | ||
2144 | rocksdb::CompactRangeOptions *compact_range_opts = nullptr; | |
2145 | if (jcompact_range_opts_handle == 0) { | |
2146 | // NOTE: we DO own the pointer! | |
2147 | compact_range_opts = new rocksdb::CompactRangeOptions(); | |
2148 | } else { | |
2149 | // NOTE: we do NOT own the pointer! | |
2150 | compact_range_opts = | |
2151 | reinterpret_cast<rocksdb::CompactRangeOptions*>(jcompact_range_opts_handle); | |
2152 | } | |
2153 | ||
7c673cae | 2154 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
7c673cae | 2155 | |
494da23a TL |
2156 | rocksdb::ColumnFamilyHandle* cf_handle; |
2157 | if (jcf_handle == 0) { | |
2158 | cf_handle = db->DefaultColumnFamily(); | |
2159 | } else { | |
2160 | cf_handle = | |
2161 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2162 | } | |
7c673cae | 2163 | |
7c673cae | 2164 | rocksdb::Status s; |
494da23a TL |
2165 | if (jbegin_len > 0 || jend_len > 0) { |
2166 | const rocksdb::Slice begin(str_begin); | |
2167 | const rocksdb::Slice end(str_end); | |
2168 | s = db->CompactRange(*compact_range_opts, cf_handle, &begin, &end); | |
7c673cae | 2169 | } else { |
494da23a | 2170 | s = db->CompactRange(*compact_range_opts, cf_handle, nullptr, nullptr); |
7c673cae FG |
2171 | } |
2172 | ||
494da23a TL |
2173 | if (jcompact_range_opts_handle == 0) { |
2174 | delete compact_range_opts; | |
7c673cae FG |
2175 | } |
2176 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2177 | } | |
2178 | ||
2179 | /* | |
2180 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2181 | * Method: setOptions |
2182 | * Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)V | |
7c673cae | 2183 | */ |
494da23a TL |
2184 | void Java_org_rocksdb_RocksDB_setOptions( |
2185 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
2186 | jobjectArray jkeys, jobjectArray jvalues) { | |
2187 | const jsize len = env->GetArrayLength(jkeys); | |
2188 | assert(len == env->GetArrayLength(jvalues)); | |
2189 | ||
2190 | std::unordered_map<std::string, std::string> options_map; | |
2191 | for (jsize i = 0; i < len; i++) { | |
2192 | jobject jobj_key = env->GetObjectArrayElement(jkeys, i); | |
2193 | if (env->ExceptionCheck()) { | |
2194 | // exception thrown: ArrayIndexOutOfBoundsException | |
2195 | return; | |
2196 | } | |
2197 | ||
2198 | jobject jobj_value = env->GetObjectArrayElement(jvalues, i); | |
2199 | if (env->ExceptionCheck()) { | |
2200 | // exception thrown: ArrayIndexOutOfBoundsException | |
2201 | env->DeleteLocalRef(jobj_key); | |
2202 | return; | |
2203 | } | |
2204 | ||
2205 | jboolean has_exception = JNI_FALSE; | |
2206 | std::string s_key = | |
2207 | rocksdb::JniUtil::copyStdString( | |
2208 | env, reinterpret_cast<jstring>(jobj_key), &has_exception); | |
2209 | if (has_exception == JNI_TRUE) { | |
2210 | // exception occurred | |
2211 | env->DeleteLocalRef(jobj_value); | |
2212 | env->DeleteLocalRef(jobj_key); | |
2213 | return; | |
2214 | } | |
2215 | ||
2216 | std::string s_value = | |
2217 | rocksdb::JniUtil::copyStdString( | |
2218 | env, reinterpret_cast<jstring>(jobj_value), &has_exception); | |
2219 | if (has_exception == JNI_TRUE) { | |
2220 | // exception occurred | |
2221 | env->DeleteLocalRef(jobj_value); | |
2222 | env->DeleteLocalRef(jobj_key); | |
2223 | return; | |
2224 | } | |
2225 | ||
2226 | options_map[s_key] = s_value; | |
2227 | ||
2228 | env->DeleteLocalRef(jobj_key); | |
2229 | env->DeleteLocalRef(jobj_value); | |
2230 | } | |
2231 | ||
7c673cae | 2232 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
2233 | auto* cf_handle = reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); |
2234 | auto s = db->SetOptions(cf_handle, options_map); | |
2235 | if (!s.ok()) { | |
2236 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2237 | } | |
7c673cae FG |
2238 | } |
2239 | ||
2240 | /* | |
2241 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2242 | * Method: setDBOptions |
2243 | * Signature: (J[Ljava/lang/String;[Ljava/lang/String;)V | |
7c673cae | 2244 | */ |
494da23a TL |
2245 | void Java_org_rocksdb_RocksDB_setDBOptions( |
2246 | JNIEnv* env, jobject, jlong jdb_handle, | |
2247 | jobjectArray jkeys, jobjectArray jvalues) { | |
2248 | const jsize len = env->GetArrayLength(jkeys); | |
2249 | assert(len == env->GetArrayLength(jvalues)); | |
2250 | ||
2251 | std::unordered_map<std::string, std::string> options_map; | |
2252 | for (jsize i = 0; i < len; i++) { | |
2253 | jobject jobj_key = env->GetObjectArrayElement(jkeys, i); | |
2254 | if (env->ExceptionCheck()) { | |
2255 | // exception thrown: ArrayIndexOutOfBoundsException | |
2256 | return; | |
2257 | } | |
2258 | ||
2259 | jobject jobj_value = env->GetObjectArrayElement(jvalues, i); | |
2260 | if (env->ExceptionCheck()) { | |
2261 | // exception thrown: ArrayIndexOutOfBoundsException | |
2262 | env->DeleteLocalRef(jobj_key); | |
2263 | return; | |
2264 | } | |
2265 | ||
2266 | jboolean has_exception = JNI_FALSE; | |
2267 | std::string s_key = | |
2268 | rocksdb::JniUtil::copyStdString( | |
2269 | env, reinterpret_cast<jstring>(jobj_key), &has_exception); | |
2270 | if (has_exception == JNI_TRUE) { | |
2271 | // exception occurred | |
2272 | env->DeleteLocalRef(jobj_value); | |
2273 | env->DeleteLocalRef(jobj_key); | |
2274 | return; | |
2275 | } | |
2276 | ||
2277 | std::string s_value = | |
2278 | rocksdb::JniUtil::copyStdString( | |
2279 | env, reinterpret_cast<jstring>(jobj_value), &has_exception); | |
2280 | if (has_exception == JNI_TRUE) { | |
2281 | // exception occurred | |
2282 | env->DeleteLocalRef(jobj_value); | |
2283 | env->DeleteLocalRef(jobj_key); | |
2284 | return; | |
2285 | } | |
2286 | ||
2287 | options_map[s_key] = s_value; | |
2288 | ||
2289 | env->DeleteLocalRef(jobj_key); | |
2290 | env->DeleteLocalRef(jobj_value); | |
2291 | } | |
2292 | ||
7c673cae | 2293 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
2294 | auto s = db->SetDBOptions(options_map); |
2295 | if (!s.ok()) { | |
2296 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2297 | } | |
7c673cae FG |
2298 | } |
2299 | ||
494da23a TL |
2300 | /* |
2301 | * Class: org_rocksdb_RocksDB | |
2302 | * Method: compactFiles | |
2303 | * Signature: (JJJ[Ljava/lang/String;IIJ)[Ljava/lang/String; | |
7c673cae | 2304 | */ |
494da23a TL |
2305 | jobjectArray Java_org_rocksdb_RocksDB_compactFiles( |
2306 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcompaction_opts_handle, | |
2307 | jlong jcf_handle, jobjectArray jinput_file_names, jint joutput_level, | |
2308 | jint joutput_path_id, jlong jcompaction_job_info_handle) { | |
2309 | jboolean has_exception = JNI_FALSE; | |
2310 | const std::vector<std::string> input_file_names = | |
2311 | rocksdb::JniUtil::copyStrings(env, jinput_file_names, &has_exception); | |
2312 | if (has_exception == JNI_TRUE) { | |
2313 | // exception occurred | |
2314 | return nullptr; | |
7c673cae FG |
2315 | } |
2316 | ||
494da23a TL |
2317 | auto* compaction_opts = |
2318 | reinterpret_cast<rocksdb::CompactionOptions*>(jcompaction_opts_handle); | |
2319 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2320 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2321 | if (jcf_handle == 0) { | |
2322 | cf_handle = db->DefaultColumnFamily(); | |
2323 | } else { | |
2324 | cf_handle = | |
2325 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
7c673cae FG |
2326 | } |
2327 | ||
494da23a TL |
2328 | rocksdb::CompactionJobInfo* compaction_job_info = nullptr; |
2329 | if (jcompaction_job_info_handle != 0) { | |
2330 | compaction_job_info = | |
2331 | reinterpret_cast<rocksdb::CompactionJobInfo*>(jcompaction_job_info_handle); | |
2332 | } | |
7c673cae | 2333 | |
494da23a TL |
2334 | std::vector<std::string> output_file_names; |
2335 | auto s = db->CompactFiles(*compaction_opts, cf_handle, input_file_names, | |
2336 | static_cast<int>(joutput_level), static_cast<int>(joutput_path_id), | |
2337 | &output_file_names, compaction_job_info); | |
2338 | if (!s.ok()) { | |
2339 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2340 | return nullptr; | |
7c673cae FG |
2341 | } |
2342 | ||
494da23a TL |
2343 | return rocksdb::JniUtil::toJavaStrings(env, &output_file_names); |
2344 | } | |
7c673cae | 2345 | |
494da23a TL |
2346 | /* |
2347 | * Class: org_rocksdb_RocksDB | |
2348 | * Method: pauseBackgroundWork | |
2349 | * Signature: (J)V | |
2350 | */ | |
2351 | void Java_org_rocksdb_RocksDB_pauseBackgroundWork( | |
2352 | JNIEnv* env, jobject, jlong jdb_handle) { | |
2353 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2354 | auto s = db->PauseBackgroundWork(); | |
2355 | if (!s.ok()) { | |
2356 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
7c673cae | 2357 | } |
494da23a | 2358 | } |
7c673cae | 2359 | |
494da23a TL |
2360 | /* |
2361 | * Class: org_rocksdb_RocksDB | |
2362 | * Method: continueBackgroundWork | |
2363 | * Signature: (J)V | |
2364 | */ | |
2365 | void Java_org_rocksdb_RocksDB_continueBackgroundWork( | |
2366 | JNIEnv* env, jobject, jlong jdb_handle) { | |
2367 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2368 | auto s = db->ContinueBackgroundWork(); | |
2369 | if (!s.ok()) { | |
2370 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2371 | } | |
7c673cae FG |
2372 | } |
2373 | ||
494da23a TL |
2374 | /* |
2375 | * Class: org_rocksdb_RocksDB | |
2376 | * Method: enableAutoCompaction | |
2377 | * Signature: (J[J)V | |
2378 | */ | |
2379 | void Java_org_rocksdb_RocksDB_enableAutoCompaction( | |
2380 | JNIEnv* env, jobject, jlong jdb_handle, jlongArray jcf_handles) { | |
2381 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2382 | jboolean has_exception = JNI_FALSE; | |
2383 | const std::vector<rocksdb::ColumnFamilyHandle*> cf_handles = | |
2384 | rocksdb::JniUtil::fromJPointers<rocksdb::ColumnFamilyHandle>(env, jcf_handles, &has_exception); | |
2385 | if (has_exception == JNI_TRUE) { | |
2386 | // exception occurred | |
2387 | return; | |
2388 | } | |
2389 | db->EnableAutoCompaction(cf_handles); | |
2390 | } | |
2391 | ||
2392 | /* | |
2393 | * Class: org_rocksdb_RocksDB | |
2394 | * Method: numberLevels | |
2395 | * Signature: (JJ)I | |
2396 | */ | |
2397 | jint Java_org_rocksdb_RocksDB_numberLevels( | |
2398 | JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) { | |
2399 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2400 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2401 | if (jcf_handle == 0) { | |
2402 | cf_handle = db->DefaultColumnFamily(); | |
2403 | } else { | |
2404 | cf_handle = | |
2405 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2406 | } | |
2407 | return static_cast<jint>(db->NumberLevels(cf_handle)); | |
2408 | } | |
2409 | ||
2410 | /* | |
2411 | * Class: org_rocksdb_RocksDB | |
2412 | * Method: maxMemCompactionLevel | |
2413 | * Signature: (JJ)I | |
11fdf7f2 | 2414 | */ |
494da23a TL |
2415 | jint Java_org_rocksdb_RocksDB_maxMemCompactionLevel( |
2416 | JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) { | |
2417 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2418 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2419 | if (jcf_handle == 0) { | |
2420 | cf_handle = db->DefaultColumnFamily(); | |
2421 | } else { | |
2422 | cf_handle = | |
2423 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2424 | } | |
2425 | return static_cast<jint>(db->MaxMemCompactionLevel(cf_handle)); | |
2426 | } | |
11fdf7f2 | 2427 | |
494da23a TL |
2428 | /* |
2429 | * Class: org_rocksdb_RocksDB | |
2430 | * Method: level0StopWriteTrigger | |
2431 | * Signature: (JJ)I | |
2432 | */ | |
2433 | jint Java_org_rocksdb_RocksDB_level0StopWriteTrigger( | |
2434 | JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle) { | |
2435 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2436 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2437 | if (jcf_handle == 0) { | |
2438 | cf_handle = db->DefaultColumnFamily(); | |
2439 | } else { | |
2440 | cf_handle = | |
2441 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2442 | } | |
2443 | return static_cast<jint>(db->Level0StopWriteTrigger(cf_handle)); | |
11fdf7f2 TL |
2444 | } |
2445 | ||
7c673cae FG |
2446 | /* |
2447 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2448 | * Method: getName |
2449 | * Signature: (J)Ljava/lang/String; | |
7c673cae | 2450 | */ |
494da23a TL |
2451 | jstring Java_org_rocksdb_RocksDB_getName( |
2452 | JNIEnv* env, jobject, jlong jdb_handle) { | |
7c673cae | 2453 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
2454 | std::string name = db->GetName(); |
2455 | return rocksdb::JniUtil::toJavaString(env, &name, false); | |
7c673cae FG |
2456 | } |
2457 | ||
2458 | /* | |
2459 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2460 | * Method: getEnv |
2461 | * Signature: (J)J | |
7c673cae | 2462 | */ |
494da23a TL |
2463 | jlong Java_org_rocksdb_RocksDB_getEnv( |
2464 | JNIEnv*, jobject, jlong jdb_handle) { | |
11fdf7f2 | 2465 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a | 2466 | return reinterpret_cast<jlong>(db->GetEnv()); |
11fdf7f2 TL |
2467 | } |
2468 | ||
494da23a TL |
2469 | /* |
2470 | * Class: org_rocksdb_RocksDB | |
2471 | * Method: flush | |
2472 | * Signature: (JJ[J)V | |
2473 | */ | |
2474 | void Java_org_rocksdb_RocksDB_flush( | |
2475 | JNIEnv* env, jobject, jlong jdb_handle, jlong jflush_opts_handle, | |
2476 | jlongArray jcf_handles) { | |
7c673cae | 2477 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a TL |
2478 | auto* flush_opts = |
2479 | reinterpret_cast<rocksdb::FlushOptions*>(jflush_opts_handle); | |
2480 | std::vector<rocksdb::ColumnFamilyHandle*> cf_handles; | |
2481 | if (jcf_handles == nullptr) { | |
2482 | cf_handles.push_back(db->DefaultColumnFamily()); | |
2483 | } else { | |
2484 | jboolean has_exception = JNI_FALSE; | |
2485 | cf_handles = | |
2486 | rocksdb::JniUtil::fromJPointers<rocksdb::ColumnFamilyHandle>( | |
2487 | env, jcf_handles, &has_exception); | |
2488 | if (has_exception) { | |
2489 | // exception occurred | |
2490 | return; | |
2491 | } | |
2492 | } | |
2493 | auto s = db->Flush(*flush_opts, cf_handles); | |
2494 | if (!s.ok()) { | |
2495 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2496 | } | |
7c673cae FG |
2497 | } |
2498 | ||
7c673cae FG |
2499 | /* |
2500 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2501 | * Method: flushWal |
2502 | * Signature: (JZ)V | |
7c673cae | 2503 | */ |
494da23a TL |
2504 | void Java_org_rocksdb_RocksDB_flushWal( |
2505 | JNIEnv* env, jobject, jlong jdb_handle, jboolean jsync) { | |
7c673cae | 2506 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a | 2507 | auto s = db->FlushWAL(jsync == JNI_TRUE); |
7c673cae FG |
2508 | if (!s.ok()) { |
2509 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2510 | } | |
2511 | } | |
2512 | ||
7c673cae FG |
2513 | /* |
2514 | * Class: org_rocksdb_RocksDB | |
494da23a | 2515 | * Method: syncWal |
7c673cae FG |
2516 | * Signature: (J)V |
2517 | */ | |
494da23a TL |
2518 | void Java_org_rocksdb_RocksDB_syncWal( |
2519 | JNIEnv* env, jobject, jlong jdb_handle) { | |
7c673cae | 2520 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
494da23a | 2521 | auto s = db->SyncWAL(); |
7c673cae FG |
2522 | if (!s.ok()) { |
2523 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2524 | } | |
2525 | } | |
2526 | ||
7c673cae FG |
2527 | /* |
2528 | * Class: org_rocksdb_RocksDB | |
2529 | * Method: getLatestSequenceNumber | |
2530 | * Signature: (J)V | |
2531 | */ | |
494da23a TL |
2532 | jlong Java_org_rocksdb_RocksDB_getLatestSequenceNumber( |
2533 | JNIEnv*, jobject, jlong jdb_handle) { | |
7c673cae FG |
2534 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
2535 | return db->GetLatestSequenceNumber(); | |
2536 | } | |
2537 | ||
494da23a TL |
2538 | /* |
2539 | * Class: org_rocksdb_RocksDB | |
2540 | * Method: setPreserveDeletesSequenceNumber | |
2541 | * Signature: (JJ)Z | |
2542 | */ | |
2543 | jboolean JNICALL Java_org_rocksdb_RocksDB_setPreserveDeletesSequenceNumber( | |
2544 | JNIEnv*, jobject, jlong jdb_handle, jlong jseq_number) { | |
2545 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2546 | if (db->SetPreserveDeletesSequenceNumber( | |
2547 | static_cast<uint64_t>(jseq_number))) { | |
2548 | return JNI_TRUE; | |
2549 | } else { | |
2550 | return JNI_FALSE; | |
2551 | } | |
2552 | } | |
7c673cae FG |
2553 | |
2554 | /* | |
2555 | * Class: org_rocksdb_RocksDB | |
494da23a | 2556 | * Method: disableFileDeletions |
7c673cae FG |
2557 | * Signature: (J)V |
2558 | */ | |
494da23a TL |
2559 | void Java_org_rocksdb_RocksDB_disableFileDeletions( |
2560 | JNIEnv* env, jobject, jlong jdb_handle) { | |
7c673cae FG |
2561 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
2562 | rocksdb::Status s = db->DisableFileDeletions(); | |
2563 | if (!s.ok()) { | |
2564 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2565 | } | |
2566 | } | |
2567 | ||
2568 | /* | |
2569 | * Class: org_rocksdb_RocksDB | |
2570 | * Method: enableFileDeletions | |
2571 | * Signature: (JZ)V | |
2572 | */ | |
494da23a TL |
2573 | void Java_org_rocksdb_RocksDB_enableFileDeletions( |
2574 | JNIEnv* env, jobject, jlong jdb_handle, jboolean jforce) { | |
7c673cae FG |
2575 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
2576 | rocksdb::Status s = db->EnableFileDeletions(jforce); | |
2577 | if (!s.ok()) { | |
2578 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2579 | } | |
2580 | } | |
2581 | ||
494da23a TL |
2582 | /* |
2583 | * Class: org_rocksdb_RocksDB | |
2584 | * Method: getLiveFiles | |
2585 | * Signature: (JZ)[Ljava/lang/String; | |
2586 | */ | |
2587 | jobjectArray Java_org_rocksdb_RocksDB_getLiveFiles( | |
2588 | JNIEnv* env, jobject, jlong jdb_handle, jboolean jflush_memtable) { | |
2589 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2590 | std::vector<std::string> live_files; | |
2591 | uint64_t manifest_file_size = 0; | |
2592 | auto s = db->GetLiveFiles( | |
2593 | live_files, &manifest_file_size, jflush_memtable == JNI_TRUE); | |
2594 | if (!s.ok()) { | |
2595 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2596 | return nullptr; | |
2597 | } | |
2598 | ||
2599 | // append the manifest_file_size to the vector | |
2600 | // for passing back to java | |
2601 | live_files.push_back(std::to_string(manifest_file_size)); | |
2602 | ||
2603 | return rocksdb::JniUtil::toJavaStrings(env, &live_files); | |
2604 | } | |
2605 | ||
2606 | /* | |
2607 | * Class: org_rocksdb_RocksDB | |
2608 | * Method: getSortedWalFiles | |
2609 | * Signature: (J)[Lorg/rocksdb/LogFile; | |
2610 | */ | |
2611 | jobjectArray Java_org_rocksdb_RocksDB_getSortedWalFiles( | |
2612 | JNIEnv* env, jobject, jlong jdb_handle) { | |
2613 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2614 | std::vector<std::unique_ptr<rocksdb::LogFile>> sorted_wal_files; | |
2615 | auto s = db->GetSortedWalFiles(sorted_wal_files); | |
2616 | if (!s.ok()) { | |
2617 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2618 | return nullptr; | |
2619 | } | |
2620 | ||
2621 | // convert to Java type | |
2622 | const jsize jlen = static_cast<jsize>(sorted_wal_files.size()); | |
2623 | jobjectArray jsorted_wal_files = env->NewObjectArray( | |
2624 | jlen, rocksdb::LogFileJni::getJClass(env), nullptr); | |
2625 | if(jsorted_wal_files == nullptr) { | |
2626 | // exception thrown: OutOfMemoryError | |
2627 | return nullptr; | |
2628 | } | |
2629 | ||
2630 | jsize i = 0; | |
2631 | for (auto it = sorted_wal_files.begin(); it != sorted_wal_files.end(); ++it) { | |
2632 | jobject jlog_file = rocksdb::LogFileJni::fromCppLogFile(env, it->get()); | |
2633 | if (jlog_file == nullptr) { | |
2634 | // exception occurred | |
2635 | env->DeleteLocalRef(jsorted_wal_files); | |
2636 | return nullptr; | |
2637 | } | |
2638 | ||
2639 | env->SetObjectArrayElement(jsorted_wal_files, i++, jlog_file); | |
2640 | if (env->ExceptionCheck()) { | |
2641 | // exception occurred | |
2642 | env->DeleteLocalRef(jlog_file); | |
2643 | env->DeleteLocalRef(jsorted_wal_files); | |
2644 | return nullptr; | |
2645 | } | |
2646 | ||
2647 | env->DeleteLocalRef(jlog_file); | |
2648 | } | |
2649 | ||
2650 | return jsorted_wal_files; | |
2651 | } | |
7c673cae FG |
2652 | |
2653 | /* | |
2654 | * Class: org_rocksdb_RocksDB | |
2655 | * Method: getUpdatesSince | |
2656 | * Signature: (JJ)J | |
2657 | */ | |
494da23a TL |
2658 | jlong Java_org_rocksdb_RocksDB_getUpdatesSince( |
2659 | JNIEnv* env, jobject, jlong jdb_handle, jlong jsequence_number) { | |
7c673cae FG |
2660 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); |
2661 | rocksdb::SequenceNumber sequence_number = | |
2662 | static_cast<rocksdb::SequenceNumber>(jsequence_number); | |
2663 | std::unique_ptr<rocksdb::TransactionLogIterator> iter; | |
2664 | rocksdb::Status s = db->GetUpdatesSince(sequence_number, &iter); | |
2665 | if (s.ok()) { | |
2666 | return reinterpret_cast<jlong>(iter.release()); | |
2667 | } | |
2668 | ||
2669 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2670 | return 0; | |
2671 | } | |
2672 | ||
2673 | /* | |
2674 | * Class: org_rocksdb_RocksDB | |
494da23a TL |
2675 | * Method: deleteFile |
2676 | * Signature: (JLjava/lang/String;)V | |
7c673cae | 2677 | */ |
494da23a TL |
2678 | void Java_org_rocksdb_RocksDB_deleteFile( |
2679 | JNIEnv* env, jobject, jlong jdb_handle, jstring jname) { | |
2680 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2681 | jboolean has_exception = JNI_FALSE; | |
2682 | std::string name = | |
2683 | rocksdb::JniUtil::copyStdString(env, jname, &has_exception); | |
2684 | if (has_exception == JNI_TRUE) { | |
2685 | // exception occurred | |
2686 | return; | |
2687 | } | |
2688 | db->DeleteFile(name); | |
2689 | } | |
7c673cae | 2690 | |
494da23a TL |
2691 | /* |
2692 | * Class: org_rocksdb_RocksDB | |
2693 | * Method: getLiveFilesMetaData | |
2694 | * Signature: (J)[Lorg/rocksdb/LiveFileMetaData; | |
2695 | */ | |
2696 | jobjectArray Java_org_rocksdb_RocksDB_getLiveFilesMetaData( | |
2697 | JNIEnv* env, jobject, jlong jdb_handle) { | |
2698 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2699 | std::vector<rocksdb::LiveFileMetaData> live_files_meta_data; | |
2700 | db->GetLiveFilesMetaData(&live_files_meta_data); | |
2701 | ||
2702 | // convert to Java type | |
2703 | const jsize jlen = static_cast<jsize>(live_files_meta_data.size()); | |
2704 | jobjectArray jlive_files_meta_data = env->NewObjectArray( | |
2705 | jlen, rocksdb::LiveFileMetaDataJni::getJClass(env), nullptr); | |
2706 | if(jlive_files_meta_data == nullptr) { | |
2707 | // exception thrown: OutOfMemoryError | |
2708 | return nullptr; | |
2709 | } | |
7c673cae | 2710 | |
494da23a TL |
2711 | jsize i = 0; |
2712 | for (auto it = live_files_meta_data.begin(); it != live_files_meta_data.end(); ++it) { | |
2713 | jobject jlive_file_meta_data = | |
2714 | rocksdb::LiveFileMetaDataJni::fromCppLiveFileMetaData(env, &(*it)); | |
2715 | if (jlive_file_meta_data == nullptr) { | |
2716 | // exception occurred | |
2717 | env->DeleteLocalRef(jlive_files_meta_data); | |
2718 | return nullptr; | |
7c673cae FG |
2719 | } |
2720 | ||
494da23a TL |
2721 | env->SetObjectArrayElement(jlive_files_meta_data, i++, jlive_file_meta_data); |
2722 | if (env->ExceptionCheck()) { | |
2723 | // exception occurred | |
2724 | env->DeleteLocalRef(jlive_file_meta_data); | |
2725 | env->DeleteLocalRef(jlive_files_meta_data); | |
2726 | return nullptr; | |
7c673cae FG |
2727 | } |
2728 | ||
494da23a | 2729 | env->DeleteLocalRef(jlive_file_meta_data); |
7c673cae FG |
2730 | } |
2731 | ||
494da23a | 2732 | return jlive_files_meta_data; |
7c673cae FG |
2733 | } |
2734 | ||
494da23a TL |
2735 | /* |
2736 | * Class: org_rocksdb_RocksDB | |
2737 | * Method: getColumnFamilyMetaData | |
2738 | * Signature: (JJ)Lorg/rocksdb/ColumnFamilyMetaData; | |
2739 | */ | |
2740 | jobject Java_org_rocksdb_RocksDB_getColumnFamilyMetaData( | |
2741 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) { | |
2742 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2743 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2744 | if (jcf_handle == 0) { | |
2745 | cf_handle = db->DefaultColumnFamily(); | |
2746 | } else { | |
2747 | cf_handle = | |
2748 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2749 | } | |
2750 | rocksdb::ColumnFamilyMetaData cf_metadata; | |
2751 | db->GetColumnFamilyMetaData(cf_handle, &cf_metadata); | |
2752 | return rocksdb::ColumnFamilyMetaDataJni::fromCppColumnFamilyMetaData( | |
2753 | env, &cf_metadata); | |
2754 | } | |
7c673cae FG |
2755 | |
2756 | /* | |
2757 | * Class: org_rocksdb_RocksDB | |
11fdf7f2 TL |
2758 | * Method: ingestExternalFile |
2759 | * Signature: (JJ[Ljava/lang/String;IJ)V | |
7c673cae | 2760 | */ |
11fdf7f2 | 2761 | void Java_org_rocksdb_RocksDB_ingestExternalFile( |
494da23a | 2762 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, |
7c673cae | 2763 | jobjectArray jfile_path_list, jint jfile_path_list_len, |
11fdf7f2 | 2764 | jlong jingest_external_file_options_handle) { |
7c673cae | 2765 | jboolean has_exception = JNI_FALSE; |
11fdf7f2 TL |
2766 | std::vector<std::string> file_path_list = rocksdb::JniUtil::copyStrings( |
2767 | env, jfile_path_list, jfile_path_list_len, &has_exception); | |
2768 | if (has_exception == JNI_TRUE) { | |
2769 | // exception occurred | |
7c673cae FG |
2770 | return; |
2771 | } | |
2772 | ||
2773 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2774 | auto* column_family = | |
2775 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
11fdf7f2 TL |
2776 | auto* ifo = reinterpret_cast<rocksdb::IngestExternalFileOptions*>( |
2777 | jingest_external_file_options_handle); | |
7c673cae | 2778 | rocksdb::Status s = |
11fdf7f2 | 2779 | db->IngestExternalFile(column_family, file_path_list, *ifo); |
7c673cae FG |
2780 | if (!s.ok()) { |
2781 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2782 | } | |
2783 | } | |
2784 | ||
494da23a TL |
2785 | /* |
2786 | * Class: org_rocksdb_RocksDB | |
2787 | * Method: verifyChecksum | |
2788 | * Signature: (J)V | |
2789 | */ | |
2790 | void Java_org_rocksdb_RocksDB_verifyChecksum( | |
2791 | JNIEnv* env, jobject, jlong jdb_handle) { | |
2792 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2793 | auto s = db->VerifyChecksum(); | |
2794 | if (!s.ok()) { | |
2795 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2796 | } | |
2797 | } | |
2798 | ||
2799 | /* | |
2800 | * Class: org_rocksdb_RocksDB | |
2801 | * Method: getDefaultColumnFamily | |
2802 | * Signature: (J)J | |
2803 | */ | |
2804 | jlong Java_org_rocksdb_RocksDB_getDefaultColumnFamily( | |
2805 | JNIEnv*, jobject, jlong jdb_handle) { | |
2806 | auto* db_handle = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2807 | auto* cf_handle = db_handle->DefaultColumnFamily(); | |
2808 | return reinterpret_cast<jlong>(cf_handle); | |
2809 | } | |
2810 | ||
2811 | /* | |
2812 | * Class: org_rocksdb_RocksDB | |
2813 | * Method: getPropertiesOfAllTables | |
2814 | * Signature: (JJ)Ljava/util/Map; | |
2815 | */ | |
2816 | jobject Java_org_rocksdb_RocksDB_getPropertiesOfAllTables( | |
2817 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) { | |
2818 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2819 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2820 | if (jcf_handle == 0) { | |
2821 | cf_handle = db->DefaultColumnFamily(); | |
2822 | } else { | |
2823 | cf_handle = | |
2824 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2825 | } | |
2826 | rocksdb::TablePropertiesCollection table_properties_collection; | |
2827 | auto s = db->GetPropertiesOfAllTables(cf_handle, | |
2828 | &table_properties_collection); | |
2829 | if (!s.ok()) { | |
2830 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2831 | } | |
2832 | ||
2833 | // convert to Java type | |
2834 | jobject jhash_map = rocksdb::HashMapJni::construct( | |
2835 | env, static_cast<uint32_t>(table_properties_collection.size())); | |
2836 | if (jhash_map == nullptr) { | |
2837 | // exception occurred | |
2838 | return nullptr; | |
2839 | } | |
2840 | ||
2841 | const rocksdb::HashMapJni::FnMapKV<const std::string, const std::shared_ptr<const rocksdb::TableProperties>, jobject, jobject> fn_map_kv = | |
2842 | [env](const std::pair<const std::string, const std::shared_ptr<const rocksdb::TableProperties>>& kv) { | |
2843 | jstring jkey = rocksdb::JniUtil::toJavaString(env, &(kv.first), false); | |
2844 | if (env->ExceptionCheck()) { | |
2845 | // an error occurred | |
2846 | return std::unique_ptr<std::pair<jobject, jobject>>(nullptr); | |
2847 | } | |
2848 | ||
2849 | jobject jtable_properties = rocksdb::TablePropertiesJni::fromCppTableProperties(env, *(kv.second.get())); | |
2850 | if (jtable_properties == nullptr) { | |
2851 | // an error occurred | |
2852 | env->DeleteLocalRef(jkey); | |
2853 | return std::unique_ptr<std::pair<jobject, jobject>>(nullptr); | |
2854 | } | |
2855 | ||
2856 | return std::unique_ptr<std::pair<jobject, jobject>>(new std::pair<jobject, jobject>(static_cast<jobject>(jkey), static_cast<jobject>(jtable_properties))); | |
2857 | }; | |
2858 | ||
2859 | if (!rocksdb::HashMapJni::putAll(env, jhash_map, table_properties_collection.begin(), table_properties_collection.end(), fn_map_kv)) { | |
2860 | // exception occurred | |
2861 | return nullptr; | |
2862 | } | |
2863 | ||
2864 | return jhash_map; | |
2865 | } | |
2866 | ||
2867 | /* | |
2868 | * Class: org_rocksdb_RocksDB | |
2869 | * Method: getPropertiesOfTablesInRange | |
2870 | * Signature: (JJ[J)Ljava/util/Map; | |
2871 | */ | |
2872 | jobject Java_org_rocksdb_RocksDB_getPropertiesOfTablesInRange( | |
2873 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle, | |
2874 | jlongArray jrange_slice_handles) { | |
2875 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2876 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2877 | if (jcf_handle == 0) { | |
2878 | cf_handle = db->DefaultColumnFamily(); | |
2879 | } else { | |
2880 | cf_handle = | |
2881 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2882 | } | |
2883 | const jsize jlen = env->GetArrayLength(jrange_slice_handles); | |
2884 | jboolean jrange_slice_handles_is_copy = JNI_FALSE; | |
2885 | jlong *jrange_slice_handle = env->GetLongArrayElements( | |
2886 | jrange_slice_handles, &jrange_slice_handles_is_copy); | |
2887 | if (jrange_slice_handle == nullptr) { | |
2888 | // exception occurred | |
2889 | return nullptr; | |
2890 | } | |
2891 | ||
2892 | const size_t ranges_len = static_cast<size_t>(jlen / 2); | |
2893 | auto ranges = std::unique_ptr<rocksdb::Range[]>(new rocksdb::Range[ranges_len]); | |
2894 | for (jsize i = 0, j = 0; i < jlen; ++i) { | |
2895 | auto* start = reinterpret_cast<rocksdb::Slice*>( | |
2896 | jrange_slice_handle[i]); | |
2897 | auto* limit = reinterpret_cast<rocksdb::Slice*>( | |
2898 | jrange_slice_handle[++i]); | |
2899 | ranges[j++] = rocksdb::Range(*start, *limit); | |
2900 | } | |
2901 | ||
2902 | rocksdb::TablePropertiesCollection table_properties_collection; | |
2903 | auto s = db->GetPropertiesOfTablesInRange( | |
2904 | cf_handle, ranges.get(), ranges_len, &table_properties_collection); | |
2905 | if (!s.ok()) { | |
2906 | // error occurred | |
2907 | env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle, JNI_ABORT); | |
2908 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2909 | return nullptr; | |
2910 | } | |
2911 | ||
2912 | // cleanup | |
2913 | env->ReleaseLongArrayElements(jrange_slice_handles, jrange_slice_handle, JNI_ABORT); | |
2914 | ||
2915 | return jrange_slice_handles; | |
2916 | } | |
2917 | ||
2918 | /* | |
2919 | * Class: org_rocksdb_RocksDB | |
2920 | * Method: suggestCompactRange | |
2921 | * Signature: (JJ)[J | |
2922 | */ | |
2923 | jlongArray Java_org_rocksdb_RocksDB_suggestCompactRange( | |
2924 | JNIEnv* env, jobject, jlong jdb_handle, jlong jcf_handle) { | |
2925 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2926 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2927 | if (jcf_handle == 0) { | |
2928 | cf_handle = db->DefaultColumnFamily(); | |
2929 | } else { | |
2930 | cf_handle = | |
2931 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2932 | } | |
2933 | auto* begin = new rocksdb::Slice(); | |
2934 | auto* end = new rocksdb::Slice(); | |
2935 | auto s = db->SuggestCompactRange(cf_handle, begin, end); | |
2936 | if (!s.ok()) { | |
2937 | // error occurred | |
2938 | delete begin; | |
2939 | delete end; | |
2940 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
2941 | return nullptr; | |
2942 | } | |
2943 | ||
2944 | jlongArray jslice_handles = env->NewLongArray(2); | |
2945 | if (jslice_handles == nullptr) { | |
2946 | // exception thrown: OutOfMemoryError | |
2947 | delete begin; | |
2948 | delete end; | |
2949 | return nullptr; | |
2950 | } | |
2951 | ||
2952 | jlong slice_handles[2]; | |
2953 | slice_handles[0] = reinterpret_cast<jlong>(begin); | |
2954 | slice_handles[1] = reinterpret_cast<jlong>(end); | |
2955 | env->SetLongArrayRegion(jslice_handles, 0, 2, slice_handles); | |
2956 | if (env->ExceptionCheck()) { | |
2957 | // exception thrown: ArrayIndexOutOfBoundsException | |
2958 | delete begin; | |
2959 | delete end; | |
2960 | env->DeleteLocalRef(jslice_handles); | |
2961 | return nullptr; | |
2962 | } | |
2963 | ||
2964 | return jslice_handles; | |
2965 | } | |
2966 | ||
2967 | /* | |
2968 | * Class: org_rocksdb_RocksDB | |
2969 | * Method: promoteL0 | |
2970 | * Signature: (JJI)V | |
2971 | */ | |
2972 | void Java_org_rocksdb_RocksDB_promoteL0( | |
2973 | JNIEnv*, jobject, jlong jdb_handle, jlong jcf_handle, jint jtarget_level) { | |
2974 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2975 | rocksdb::ColumnFamilyHandle* cf_handle; | |
2976 | if (jcf_handle == 0) { | |
2977 | cf_handle = db->DefaultColumnFamily(); | |
2978 | } else { | |
2979 | cf_handle = | |
2980 | reinterpret_cast<rocksdb::ColumnFamilyHandle*>(jcf_handle); | |
2981 | } | |
2982 | db->PromoteL0(cf_handle, static_cast<int>(jtarget_level)); | |
2983 | } | |
2984 | ||
2985 | /* | |
2986 | * Class: org_rocksdb_RocksDB | |
2987 | * Method: startTrace | |
2988 | * Signature: (JJJ)V | |
2989 | */ | |
2990 | void Java_org_rocksdb_RocksDB_startTrace( | |
2991 | JNIEnv* env, jobject, jlong jdb_handle, jlong jmax_trace_file_size, | |
2992 | jlong jtrace_writer_jnicallback_handle) { | |
2993 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
2994 | rocksdb::TraceOptions trace_options; | |
2995 | trace_options.max_trace_file_size = | |
2996 | static_cast<uint64_t>(jmax_trace_file_size); | |
2997 | // transfer ownership of trace writer from Java to C++ | |
2998 | auto trace_writer = std::unique_ptr<rocksdb::TraceWriterJniCallback>( | |
2999 | reinterpret_cast<rocksdb::TraceWriterJniCallback*>( | |
3000 | jtrace_writer_jnicallback_handle)); | |
3001 | auto s = db->StartTrace(trace_options, std::move(trace_writer)); | |
3002 | if (!s.ok()) { | |
3003 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
3004 | } | |
3005 | } | |
3006 | ||
3007 | /* | |
3008 | * Class: org_rocksdb_RocksDB | |
3009 | * Method: endTrace | |
3010 | * Signature: (J)V | |
3011 | */ | |
3012 | JNIEXPORT void JNICALL Java_org_rocksdb_RocksDB_endTrace( | |
3013 | JNIEnv* env, jobject, jlong jdb_handle) { | |
3014 | auto* db = reinterpret_cast<rocksdb::DB*>(jdb_handle); | |
3015 | auto s = db->EndTrace(); | |
3016 | if (!s.ok()) { | |
3017 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
3018 | } | |
3019 | } | |
3020 | ||
11fdf7f2 TL |
3021 | /* |
3022 | * Class: org_rocksdb_RocksDB | |
3023 | * Method: destroyDB | |
3024 | * Signature: (Ljava/lang/String;J)V | |
3025 | */ | |
494da23a TL |
3026 | void Java_org_rocksdb_RocksDB_destroyDB( |
3027 | JNIEnv* env, jclass, jstring jdb_path, jlong joptions_handle) { | |
11fdf7f2 TL |
3028 | const char* db_path = env->GetStringUTFChars(jdb_path, nullptr); |
3029 | if (db_path == nullptr) { | |
3030 | // exception thrown: OutOfMemoryError | |
3031 | return; | |
3032 | } | |
3033 | ||
3034 | auto* options = reinterpret_cast<rocksdb::Options*>(joptions_handle); | |
3035 | if (options == nullptr) { | |
3036 | rocksdb::RocksDBExceptionJni::ThrowNew( | |
3037 | env, rocksdb::Status::InvalidArgument("Invalid Options.")); | |
3038 | } | |
3039 | ||
3040 | rocksdb::Status s = rocksdb::DestroyDB(db_path, *options); | |
3041 | env->ReleaseStringUTFChars(jdb_path, db_path); | |
3042 | ||
3043 | if (!s.ok()) { | |
3044 | rocksdb::RocksDBExceptionJni::ThrowNew(env, s); | |
3045 | } | |
3046 | } |