optimistic_transaction_db.cc 10 KB

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