write_batch_test.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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++ and enables
  7. // calling c++ ROCKSDB_NAMESPACE::WriteBatch methods testing from Java side.
  8. #include "rocksdb/write_batch.h"
  9. #include <memory>
  10. #include "db/memtable.h"
  11. #include "db/write_batch_internal.h"
  12. #include "include/org_rocksdb_WriteBatch.h"
  13. #include "include/org_rocksdb_WriteBatchTest.h"
  14. #include "include/org_rocksdb_WriteBatchTestInternalHelper.h"
  15. #include "include/org_rocksdb_WriteBatch_Handler.h"
  16. #include "options/cf_options.h"
  17. #include "rocksdb/db.h"
  18. #include "rocksdb/env.h"
  19. #include "rocksdb/memtablerep.h"
  20. #include "rocksdb/status.h"
  21. #include "rocksdb/write_buffer_manager.h"
  22. #include "rocksjni/portal.h"
  23. #include "test_util/testharness.h"
  24. #include "util/string_util.h"
  25. /*
  26. * Class: org_rocksdb_WriteBatchTest
  27. * Method: getContents
  28. * Signature: (J)[B
  29. */
  30. jbyteArray Java_org_rocksdb_WriteBatchTest_getContents(JNIEnv* env,
  31. jclass /*jclazz*/,
  32. jlong jwb_handle) {
  33. auto* b = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle);
  34. assert(b != nullptr);
  35. // todo: Currently the following code is directly copied from
  36. // db/write_bench_test.cc. It could be implemented in java once
  37. // all the necessary components can be accessed via jni api.
  38. ROCKSDB_NAMESPACE::InternalKeyComparator cmp(
  39. ROCKSDB_NAMESPACE::BytewiseComparator());
  40. auto factory = std::make_shared<ROCKSDB_NAMESPACE::SkipListFactory>();
  41. ROCKSDB_NAMESPACE::Options options;
  42. ROCKSDB_NAMESPACE::WriteBufferManager wb(options.db_write_buffer_size);
  43. options.memtable_factory = factory;
  44. ROCKSDB_NAMESPACE::MemTable* mem = new ROCKSDB_NAMESPACE::MemTable(
  45. cmp, ROCKSDB_NAMESPACE::ImmutableOptions(options),
  46. ROCKSDB_NAMESPACE::MutableCFOptions(options), &wb,
  47. ROCKSDB_NAMESPACE::kMaxSequenceNumber, 0 /* column_family_id */);
  48. mem->Ref();
  49. std::string state;
  50. ROCKSDB_NAMESPACE::ColumnFamilyMemTablesDefault cf_mems_default(mem);
  51. ROCKSDB_NAMESPACE::Status s =
  52. ROCKSDB_NAMESPACE::WriteBatchInternal::InsertInto(b, &cf_mems_default,
  53. nullptr, nullptr);
  54. unsigned int count = 0;
  55. ROCKSDB_NAMESPACE::Arena arena;
  56. ROCKSDB_NAMESPACE::ScopedArenaPtr<ROCKSDB_NAMESPACE::InternalIterator> iter(
  57. mem->NewIterator(ROCKSDB_NAMESPACE::ReadOptions(),
  58. /*seqno_to_time_mapping=*/nullptr, &arena,
  59. /*prefix_extractor=*/nullptr, /*for_flush=*/false));
  60. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  61. ROCKSDB_NAMESPACE::ParsedInternalKey ikey;
  62. ikey.clear();
  63. ROCKSDB_NAMESPACE::Status pik_status = ROCKSDB_NAMESPACE::ParseInternalKey(
  64. iter->key(), &ikey, true /* log_err_key */);
  65. pik_status.PermitUncheckedError();
  66. assert(pik_status.ok());
  67. switch (ikey.type) {
  68. case ROCKSDB_NAMESPACE::kTypeValue:
  69. state.append("Put(");
  70. state.append(ikey.user_key.ToString());
  71. state.append(", ");
  72. state.append(iter->value().ToString());
  73. state.append(")");
  74. count++;
  75. break;
  76. case ROCKSDB_NAMESPACE::kTypeMerge:
  77. state.append("Merge(");
  78. state.append(ikey.user_key.ToString());
  79. state.append(", ");
  80. state.append(iter->value().ToString());
  81. state.append(")");
  82. count++;
  83. break;
  84. case ROCKSDB_NAMESPACE::kTypeDeletion:
  85. state.append("Delete(");
  86. state.append(ikey.user_key.ToString());
  87. state.append(")");
  88. count++;
  89. break;
  90. case ROCKSDB_NAMESPACE::kTypeSingleDeletion:
  91. state.append("SingleDelete(");
  92. state.append(ikey.user_key.ToString());
  93. state.append(")");
  94. count++;
  95. break;
  96. case ROCKSDB_NAMESPACE::kTypeRangeDeletion:
  97. state.append("DeleteRange(");
  98. state.append(ikey.user_key.ToString());
  99. state.append(", ");
  100. state.append(iter->value().ToString());
  101. state.append(")");
  102. count++;
  103. break;
  104. case ROCKSDB_NAMESPACE::kTypeLogData:
  105. state.append("LogData(");
  106. state.append(ikey.user_key.ToString());
  107. state.append(")");
  108. count++;
  109. break;
  110. default:
  111. assert(false);
  112. state.append("Err:Expected(");
  113. state.append(std::to_string(ikey.type));
  114. state.append(")");
  115. count++;
  116. break;
  117. }
  118. state.append("@");
  119. state.append(std::to_string(ikey.sequence));
  120. }
  121. if (!s.ok()) {
  122. state.append(s.ToString());
  123. } else if (ROCKSDB_NAMESPACE::WriteBatchInternal::Count(b) != count) {
  124. state.append("Err:CountMismatch(expected=");
  125. state.append(
  126. std::to_string(ROCKSDB_NAMESPACE::WriteBatchInternal::Count(b)));
  127. state.append(", actual=");
  128. state.append(std::to_string(count));
  129. state.append(")");
  130. }
  131. delete mem->Unref();
  132. jbyteArray jstate = env->NewByteArray(static_cast<jsize>(state.size()));
  133. if (jstate == nullptr) {
  134. // exception thrown: OutOfMemoryError
  135. return nullptr;
  136. }
  137. env->SetByteArrayRegion(
  138. jstate, 0, static_cast<jsize>(state.size()),
  139. const_cast<jbyte*>(reinterpret_cast<const jbyte*>(state.c_str())));
  140. if (env->ExceptionCheck()) {
  141. // exception thrown: ArrayIndexOutOfBoundsException
  142. env->DeleteLocalRef(jstate);
  143. return nullptr;
  144. }
  145. return jstate;
  146. }
  147. /*
  148. * Class: org_rocksdb_WriteBatchTestInternalHelper
  149. * Method: setSequence
  150. * Signature: (JJ)V
  151. */
  152. void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence(
  153. JNIEnv* /*env*/, jclass /*jclazz*/, jlong jwb_handle, jlong jsn) {
  154. auto* wb = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle);
  155. assert(wb != nullptr);
  156. ROCKSDB_NAMESPACE::WriteBatchInternal::SetSequence(
  157. wb, static_cast<ROCKSDB_NAMESPACE::SequenceNumber>(jsn));
  158. }
  159. /*
  160. * Class: org_rocksdb_WriteBatchTestInternalHelper
  161. * Method: sequence
  162. * Signature: (J)J
  163. */
  164. jlong Java_org_rocksdb_WriteBatchTestInternalHelper_sequence(JNIEnv* /*env*/,
  165. jclass /*jclazz*/,
  166. jlong jwb_handle) {
  167. auto* wb = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle);
  168. assert(wb != nullptr);
  169. return static_cast<jlong>(
  170. ROCKSDB_NAMESPACE::WriteBatchInternal::Sequence(wb));
  171. }
  172. /*
  173. * Class: org_rocksdb_WriteBatchTestInternalHelper
  174. * Method: append
  175. * Signature: (JJ)V
  176. */
  177. void Java_org_rocksdb_WriteBatchTestInternalHelper_append(JNIEnv* /*env*/,
  178. jclass /*jclazz*/,
  179. jlong jwb_handle_1,
  180. jlong jwb_handle_2) {
  181. auto* wb1 = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle_1);
  182. assert(wb1 != nullptr);
  183. auto* wb2 = reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch*>(jwb_handle_2);
  184. assert(wb2 != nullptr);
  185. ROCKSDB_NAMESPACE::WriteBatchInternal::Append(wb1, wb2);
  186. }