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).
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"
12 #include "db/memtable.h"
13 #include "db/write_batch_internal.h"
14 #include "include/org_rocksdb_WriteBatch.h"
15 #include "include/org_rocksdb_WriteBatchTest.h"
16 #include "include/org_rocksdb_WriteBatchTestInternalHelper.h"
17 #include "include/org_rocksdb_WriteBatch_Handler.h"
18 #include "options/cf_options.h"
19 #include "rocksdb/db.h"
20 #include "rocksdb/env.h"
21 #include "rocksdb/memtablerep.h"
22 #include "rocksdb/status.h"
23 #include "rocksdb/write_buffer_manager.h"
24 #include "rocksjni/portal.h"
25 #include "table/scoped_arena_iterator.h"
26 #include "test_util/testharness.h"
27 #include "util/string_util.h"
30 * Class: org_rocksdb_WriteBatchTest
34 jbyteArray
Java_org_rocksdb_WriteBatchTest_getContents(JNIEnv
* env
,
37 auto* b
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle
);
40 // todo: Currently the following code is directly copied from
41 // db/write_bench_test.cc. It could be implemented in java once
42 // all the necessary components can be accessed via jni api.
44 ROCKSDB_NAMESPACE::InternalKeyComparator
cmp(
45 ROCKSDB_NAMESPACE::BytewiseComparator());
46 auto factory
= std::make_shared
<ROCKSDB_NAMESPACE::SkipListFactory
>();
47 ROCKSDB_NAMESPACE::Options options
;
48 ROCKSDB_NAMESPACE::WriteBufferManager
wb(options
.db_write_buffer_size
);
49 options
.memtable_factory
= factory
;
50 ROCKSDB_NAMESPACE::MemTable
* mem
= new ROCKSDB_NAMESPACE::MemTable(
51 cmp
, ROCKSDB_NAMESPACE::ImmutableOptions(options
),
52 ROCKSDB_NAMESPACE::MutableCFOptions(options
), &wb
,
53 ROCKSDB_NAMESPACE::kMaxSequenceNumber
, 0 /* column_family_id */);
56 ROCKSDB_NAMESPACE::ColumnFamilyMemTablesDefault
cf_mems_default(mem
);
57 ROCKSDB_NAMESPACE::Status s
=
58 ROCKSDB_NAMESPACE::WriteBatchInternal::InsertInto(b
, &cf_mems_default
,
60 unsigned int count
= 0;
61 ROCKSDB_NAMESPACE::Arena arena
;
62 ROCKSDB_NAMESPACE::ScopedArenaIterator
iter(
63 mem
->NewIterator(ROCKSDB_NAMESPACE::ReadOptions(), &arena
));
64 for (iter
->SeekToFirst(); iter
->Valid(); iter
->Next()) {
65 ROCKSDB_NAMESPACE::ParsedInternalKey ikey
;
67 ROCKSDB_NAMESPACE::Status pik_status
= ROCKSDB_NAMESPACE::ParseInternalKey(
68 iter
->key(), &ikey
, true /* log_err_key */);
69 pik_status
.PermitUncheckedError();
70 assert(pik_status
.ok());
72 case ROCKSDB_NAMESPACE::kTypeValue
:
74 state
.append(ikey
.user_key
.ToString());
76 state
.append(iter
->value().ToString());
80 case ROCKSDB_NAMESPACE::kTypeMerge
:
81 state
.append("Merge(");
82 state
.append(ikey
.user_key
.ToString());
84 state
.append(iter
->value().ToString());
88 case ROCKSDB_NAMESPACE::kTypeDeletion
:
89 state
.append("Delete(");
90 state
.append(ikey
.user_key
.ToString());
94 case ROCKSDB_NAMESPACE::kTypeSingleDeletion
:
95 state
.append("SingleDelete(");
96 state
.append(ikey
.user_key
.ToString());
100 case ROCKSDB_NAMESPACE::kTypeRangeDeletion
:
101 state
.append("DeleteRange(");
102 state
.append(ikey
.user_key
.ToString());
104 state
.append(iter
->value().ToString());
108 case ROCKSDB_NAMESPACE::kTypeLogData
:
109 state
.append("LogData(");
110 state
.append(ikey
.user_key
.ToString());
116 state
.append("Err:Expected(");
117 state
.append(std::to_string(ikey
.type
));
123 state
.append(std::to_string(ikey
.sequence
));
126 state
.append(s
.ToString());
127 } else if (ROCKSDB_NAMESPACE::WriteBatchInternal::Count(b
) != count
) {
128 state
.append("Err:CountMismatch(expected=");
130 std::to_string(ROCKSDB_NAMESPACE::WriteBatchInternal::Count(b
)));
131 state
.append(", actual=");
132 state
.append(std::to_string(count
));
137 jbyteArray jstate
= env
->NewByteArray(static_cast<jsize
>(state
.size()));
138 if (jstate
== nullptr) {
139 // exception thrown: OutOfMemoryError
143 env
->SetByteArrayRegion(
144 jstate
, 0, static_cast<jsize
>(state
.size()),
145 const_cast<jbyte
*>(reinterpret_cast<const jbyte
*>(state
.c_str())));
146 if (env
->ExceptionCheck()) {
147 // exception thrown: ArrayIndexOutOfBoundsException
148 env
->DeleteLocalRef(jstate
);
156 * Class: org_rocksdb_WriteBatchTestInternalHelper
157 * Method: setSequence
160 void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence(
161 JNIEnv
* /*env*/, jclass
/*jclazz*/, jlong jwb_handle
, jlong jsn
) {
162 auto* wb
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle
);
163 assert(wb
!= nullptr);
165 ROCKSDB_NAMESPACE::WriteBatchInternal::SetSequence(
166 wb
, static_cast<ROCKSDB_NAMESPACE::SequenceNumber
>(jsn
));
170 * Class: org_rocksdb_WriteBatchTestInternalHelper
174 jlong
Java_org_rocksdb_WriteBatchTestInternalHelper_sequence(JNIEnv
* /*env*/,
177 auto* wb
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle
);
178 assert(wb
!= nullptr);
180 return static_cast<jlong
>(
181 ROCKSDB_NAMESPACE::WriteBatchInternal::Sequence(wb
));
185 * Class: org_rocksdb_WriteBatchTestInternalHelper
189 void Java_org_rocksdb_WriteBatchTestInternalHelper_append(JNIEnv
* /*env*/,
192 jlong jwb_handle_2
) {
193 auto* wb1
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle_1
);
194 assert(wb1
!= nullptr);
195 auto* wb2
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle_2
);
196 assert(wb2
!= nullptr);
198 ROCKSDB_NAMESPACE::WriteBatchInternal::Append(wb1
, wb2
);