optimistic_transaction_db.cc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // This file implements the "bridge" between Java and C++
  7. // for ROCKSDB_NAMESPACE::TransactionDB.
  8. #include "rocksdb/utilities/optimistic_transaction_db.h"
  9. #include <jni.h>
  10. #include "include/org_rocksdb_OptimisticTransactionDB.h"
  11. #include "rocksdb/options.h"
  12. #include "rocksdb/utilities/transaction.h"
  13. #include "rocksjni/cplusplus_to_java_convert.h"
  14. #include "rocksjni/portal.h"
  15. /*
  16. * Class: org_rocksdb_OptimisticTransactionDB
  17. * Method: open
  18. * Signature: (JLjava/lang/String;)J
  19. */
  20. jlong Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2(
  21. JNIEnv* env, jclass, jlong joptions_handle, jstring jdb_path) {
  22. const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
  23. if (db_path == nullptr) {
  24. // exception thrown: OutOfMemoryError
  25. return 0;
  26. }
  27. auto* options =
  28. reinterpret_cast<ROCKSDB_NAMESPACE::Options*>(joptions_handle);
  29. ROCKSDB_NAMESPACE::OptimisticTransactionDB* otdb = nullptr;
  30. ROCKSDB_NAMESPACE::Status s =
  31. ROCKSDB_NAMESPACE::OptimisticTransactionDB::Open(*options, db_path,
  32. &otdb);
  33. env->ReleaseStringUTFChars(jdb_path, db_path);
  34. if (s.ok()) {
  35. return GET_CPLUSPLUS_POINTER(otdb);
  36. } else {
  37. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  38. return 0;
  39. }
  40. }
  41. /*
  42. * Class: org_rocksdb_OptimisticTransactionDB
  43. * Method: open
  44. * Signature: (JLjava/lang/String;[[B[J)[J
  45. */
  46. jlongArray
  47. Java_org_rocksdb_OptimisticTransactionDB_open__JLjava_lang_String_2_3_3B_3J(
  48. JNIEnv* env, jclass, jlong jdb_options_handle, jstring jdb_path,
  49. jobjectArray jcolumn_names, jlongArray jcolumn_options_handles) {
  50. const char* db_path = env->GetStringUTFChars(jdb_path, nullptr);
  51. if (db_path == nullptr) {
  52. // exception thrown: OutOfMemoryError
  53. return nullptr;
  54. }
  55. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> column_families;
  56. const jsize len_cols = env->GetArrayLength(jcolumn_names);
  57. if (len_cols > 0) {
  58. jlong* jco = env->GetLongArrayElements(jcolumn_options_handles, nullptr);
  59. if (jco == nullptr) {
  60. // exception thrown: OutOfMemoryError
  61. env->ReleaseStringUTFChars(jdb_path, db_path);
  62. return nullptr;
  63. }
  64. for (int i = 0; i < len_cols; i++) {
  65. const jobject jcn = env->GetObjectArrayElement(jcolumn_names, i);
  66. if (env->ExceptionCheck()) {
  67. // exception thrown: ArrayIndexOutOfBoundsException
  68. env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
  69. env->ReleaseStringUTFChars(jdb_path, db_path);
  70. return nullptr;
  71. }
  72. const jbyteArray jcn_ba = reinterpret_cast<jbyteArray>(jcn);
  73. const jsize jcf_name_len = env->GetArrayLength(jcn_ba);
  74. jbyte* jcf_name = env->GetByteArrayElements(jcn_ba, nullptr);
  75. if (jcf_name == nullptr) {
  76. // exception thrown: OutOfMemoryError
  77. env->DeleteLocalRef(jcn);
  78. env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
  79. env->ReleaseStringUTFChars(jdb_path, db_path);
  80. return nullptr;
  81. }
  82. const std::string cf_name(reinterpret_cast<char*>(jcf_name),
  83. jcf_name_len);
  84. const ROCKSDB_NAMESPACE::ColumnFamilyOptions* cf_options =
  85. reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(jco[i]);
  86. column_families.push_back(
  87. ROCKSDB_NAMESPACE::ColumnFamilyDescriptor(cf_name, *cf_options));
  88. env->ReleaseByteArrayElements(jcn_ba, jcf_name, JNI_ABORT);
  89. env->DeleteLocalRef(jcn);
  90. }
  91. env->ReleaseLongArrayElements(jcolumn_options_handles, jco, JNI_ABORT);
  92. }
  93. auto* db_options =
  94. reinterpret_cast<ROCKSDB_NAMESPACE::DBOptions*>(jdb_options_handle);
  95. std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> handles;
  96. ROCKSDB_NAMESPACE::OptimisticTransactionDB* otdb = nullptr;
  97. const ROCKSDB_NAMESPACE::Status s =
  98. ROCKSDB_NAMESPACE::OptimisticTransactionDB::Open(
  99. *db_options, db_path, column_families, &handles, &otdb);
  100. env->ReleaseStringUTFChars(jdb_path, db_path);
  101. // check if open operation was successful
  102. if (s.ok()) {
  103. const jsize resultsLen = 1 + len_cols; // db handle + column family handles
  104. std::unique_ptr<jlong[]> results =
  105. std::unique_ptr<jlong[]>(new jlong[resultsLen]);
  106. results[0] = reinterpret_cast<jlong>(otdb);
  107. for (int i = 1; i <= len_cols; i++) {
  108. results[i] = reinterpret_cast<jlong>(handles[i - 1]);
  109. }
  110. jlongArray jresults = env->NewLongArray(resultsLen);
  111. if (jresults == nullptr) {
  112. // exception thrown: OutOfMemoryError
  113. return nullptr;
  114. }
  115. env->SetLongArrayRegion(jresults, 0, resultsLen, results.get());
  116. if (env->ExceptionCheck()) {
  117. // exception thrown: ArrayIndexOutOfBoundsException
  118. return nullptr;
  119. }
  120. return jresults;
  121. }
  122. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  123. return nullptr;
  124. }
  125. /*
  126. * Class: org_rocksdb_OptimisticTransactionDB
  127. * Method: disposeInternal
  128. * Signature: (J)V
  129. */
  130. void Java_org_rocksdb_OptimisticTransactionDB_disposeInternalJni(
  131. JNIEnv*, jclass, jlong jhandle) {
  132. auto* optimistic_txn_db =
  133. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  134. assert(optimistic_txn_db != nullptr);
  135. delete optimistic_txn_db;
  136. }
  137. /*
  138. * Class: org_rocksdb_OptimisticTransactionDB
  139. * Method: closeDatabase
  140. * Signature: (J)V
  141. */
  142. void Java_org_rocksdb_OptimisticTransactionDB_closeDatabase(JNIEnv* env, jclass,
  143. jlong jhandle) {
  144. auto* optimistic_txn_db =
  145. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  146. assert(optimistic_txn_db != nullptr);
  147. ROCKSDB_NAMESPACE::Status s = optimistic_txn_db->Close();
  148. ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
  149. }
  150. /*
  151. * Class: org_rocksdb_OptimisticTransactionDB
  152. * Method: beginTransaction
  153. * Signature: (JJ)J
  154. */
  155. jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJ(
  156. JNIEnv*, jclass, jlong jhandle, jlong jwrite_options_handle) {
  157. auto* optimistic_txn_db =
  158. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  159. auto* write_options =
  160. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  161. ROCKSDB_NAMESPACE::Transaction* txn =
  162. optimistic_txn_db->BeginTransaction(*write_options);
  163. return GET_CPLUSPLUS_POINTER(txn);
  164. }
  165. /*
  166. * Class: org_rocksdb_OptimisticTransactionDB
  167. * Method: beginTransaction
  168. * Signature: (JJJ)J
  169. */
  170. jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction__JJJ(
  171. JNIEnv* /*env*/, jclass /*jcls*/, jlong jhandle,
  172. jlong jwrite_options_handle, jlong joptimistic_txn_options_handle) {
  173. auto* optimistic_txn_db =
  174. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  175. auto* write_options =
  176. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  177. auto* optimistic_txn_options =
  178. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionOptions*>(
  179. joptimistic_txn_options_handle);
  180. ROCKSDB_NAMESPACE::Transaction* txn = optimistic_txn_db->BeginTransaction(
  181. *write_options, *optimistic_txn_options);
  182. return GET_CPLUSPLUS_POINTER(txn);
  183. }
  184. /*
  185. * Class: org_rocksdb_OptimisticTransactionDB
  186. * Method: beginTransaction_withOld
  187. * Signature: (JJJ)J
  188. */
  189. jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJ(
  190. JNIEnv*, jclass, jlong jhandle, jlong jwrite_options_handle,
  191. jlong jold_txn_handle) {
  192. auto* optimistic_txn_db =
  193. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  194. auto* write_options =
  195. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  196. auto* old_txn =
  197. reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jold_txn_handle);
  198. ROCKSDB_NAMESPACE::OptimisticTransactionOptions optimistic_txn_options;
  199. ROCKSDB_NAMESPACE::Transaction* txn = optimistic_txn_db->BeginTransaction(
  200. *write_options, optimistic_txn_options, old_txn);
  201. // RocksJava relies on the assumption that
  202. // we do not allocate a new Transaction object
  203. // when providing an old_optimistic_txn
  204. assert(txn == old_txn);
  205. return GET_CPLUSPLUS_POINTER(txn);
  206. }
  207. /*
  208. * Class: org_rocksdb_OptimisticTransactionDB
  209. * Method: beginTransaction_withOld
  210. * Signature: (JJJJ)J
  211. */
  212. jlong Java_org_rocksdb_OptimisticTransactionDB_beginTransaction_1withOld__JJJJ(
  213. JNIEnv*, jclass, jlong jhandle, jlong jwrite_options_handle,
  214. jlong joptimistic_txn_options_handle, jlong jold_txn_handle) {
  215. auto* optimistic_txn_db =
  216. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  217. auto* write_options =
  218. reinterpret_cast<ROCKSDB_NAMESPACE::WriteOptions*>(jwrite_options_handle);
  219. auto* optimistic_txn_options =
  220. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionOptions*>(
  221. joptimistic_txn_options_handle);
  222. auto* old_txn =
  223. reinterpret_cast<ROCKSDB_NAMESPACE::Transaction*>(jold_txn_handle);
  224. ROCKSDB_NAMESPACE::Transaction* txn = optimistic_txn_db->BeginTransaction(
  225. *write_options, *optimistic_txn_options, old_txn);
  226. // RocksJava relies on the assumption that
  227. // we do not allocate a new Transaction object
  228. // when providing an old_optimisic_txn
  229. assert(txn == old_txn);
  230. return GET_CPLUSPLUS_POINTER(txn);
  231. }
  232. /*
  233. * Class: org_rocksdb_OptimisticTransactionDB
  234. * Method: getBaseDB
  235. * Signature: (J)J
  236. */
  237. jlong Java_org_rocksdb_OptimisticTransactionDB_getBaseDB(JNIEnv*, jclass,
  238. jlong jhandle) {
  239. auto* optimistic_txn_db =
  240. reinterpret_cast<ROCKSDB_NAMESPACE::OptimisticTransactionDB*>(jhandle);
  241. return GET_CPLUSPLUS_POINTER(optimistic_txn_db->GetBaseDB());
  242. }