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.
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_batch.h"
22 #include "rocksdb/write_buffer_manager.h"
23 #include "rocksjni/portal.h"
24 #include "table/scoped_arena_iterator.h"
25 #include "test_util/testharness.h"
26 #include "util/string_util.h"
29 * Class: org_rocksdb_WriteBatchTest
33 jbyteArray
Java_org_rocksdb_WriteBatchTest_getContents(JNIEnv
* env
,
36 auto* b
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle
);
39 // todo: Currently the following code is directly copied from
40 // db/write_bench_test.cc. It could be implemented in java once
41 // all the necessary components can be accessed via jni api.
43 ROCKSDB_NAMESPACE::InternalKeyComparator
cmp(
44 ROCKSDB_NAMESPACE::BytewiseComparator());
45 auto factory
= std::make_shared
<ROCKSDB_NAMESPACE::SkipListFactory
>();
46 ROCKSDB_NAMESPACE::Options options
;
47 ROCKSDB_NAMESPACE::WriteBufferManager
wb(options
.db_write_buffer_size
);
48 options
.memtable_factory
= factory
;
49 ROCKSDB_NAMESPACE::MemTable
* mem
= new ROCKSDB_NAMESPACE::MemTable(
50 cmp
, ROCKSDB_NAMESPACE::ImmutableCFOptions(options
),
51 ROCKSDB_NAMESPACE::MutableCFOptions(options
), &wb
,
52 ROCKSDB_NAMESPACE::kMaxSequenceNumber
, 0 /* column_family_id */);
55 ROCKSDB_NAMESPACE::ColumnFamilyMemTablesDefault
cf_mems_default(mem
);
56 ROCKSDB_NAMESPACE::Status s
=
57 ROCKSDB_NAMESPACE::WriteBatchInternal::InsertInto(b
, &cf_mems_default
,
59 unsigned int count
= 0;
60 ROCKSDB_NAMESPACE::Arena arena
;
61 ROCKSDB_NAMESPACE::ScopedArenaIterator
iter(
62 mem
->NewIterator(ROCKSDB_NAMESPACE::ReadOptions(), &arena
));
63 for (iter
->SeekToFirst(); iter
->Valid(); iter
->Next()) {
64 ROCKSDB_NAMESPACE::ParsedInternalKey ikey
;
66 bool parsed
= ROCKSDB_NAMESPACE::ParseInternalKey(iter
->key(), &ikey
);
71 case ROCKSDB_NAMESPACE::kTypeValue
:
73 state
.append(ikey
.user_key
.ToString());
75 state
.append(iter
->value().ToString());
79 case ROCKSDB_NAMESPACE::kTypeMerge
:
80 state
.append("Merge(");
81 state
.append(ikey
.user_key
.ToString());
83 state
.append(iter
->value().ToString());
87 case ROCKSDB_NAMESPACE::kTypeDeletion
:
88 state
.append("Delete(");
89 state
.append(ikey
.user_key
.ToString());
93 case ROCKSDB_NAMESPACE::kTypeSingleDeletion
:
94 state
.append("SingleDelete(");
95 state
.append(ikey
.user_key
.ToString());
99 case ROCKSDB_NAMESPACE::kTypeRangeDeletion
:
100 state
.append("DeleteRange(");
101 state
.append(ikey
.user_key
.ToString());
103 state
.append(iter
->value().ToString());
107 case ROCKSDB_NAMESPACE::kTypeLogData
:
108 state
.append("LogData(");
109 state
.append(ikey
.user_key
.ToString());
115 state
.append("Err:Expected(");
116 state
.append(std::to_string(ikey
.type
));
122 state
.append(ROCKSDB_NAMESPACE::NumberToString(ikey
.sequence
));
125 state
.append(s
.ToString());
126 } else if (ROCKSDB_NAMESPACE::WriteBatchInternal::Count(b
) != count
) {
127 state
.append("Err:CountMismatch(expected=");
129 std::to_string(ROCKSDB_NAMESPACE::WriteBatchInternal::Count(b
)));
130 state
.append(", actual=");
131 state
.append(std::to_string(count
));
136 jbyteArray jstate
= env
->NewByteArray(static_cast<jsize
>(state
.size()));
137 if (jstate
== nullptr) {
138 // exception thrown: OutOfMemoryError
142 env
->SetByteArrayRegion(
143 jstate
, 0, static_cast<jsize
>(state
.size()),
144 const_cast<jbyte
*>(reinterpret_cast<const jbyte
*>(state
.c_str())));
145 if (env
->ExceptionCheck()) {
146 // exception thrown: ArrayIndexOutOfBoundsException
147 env
->DeleteLocalRef(jstate
);
155 * Class: org_rocksdb_WriteBatchTestInternalHelper
156 * Method: setSequence
159 void Java_org_rocksdb_WriteBatchTestInternalHelper_setSequence(
160 JNIEnv
* /*env*/, jclass
/*jclazz*/, jlong jwb_handle
, jlong jsn
) {
161 auto* wb
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle
);
162 assert(wb
!= nullptr);
164 ROCKSDB_NAMESPACE::WriteBatchInternal::SetSequence(
165 wb
, static_cast<ROCKSDB_NAMESPACE::SequenceNumber
>(jsn
));
169 * Class: org_rocksdb_WriteBatchTestInternalHelper
173 jlong
Java_org_rocksdb_WriteBatchTestInternalHelper_sequence(JNIEnv
* /*env*/,
176 auto* wb
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle
);
177 assert(wb
!= nullptr);
179 return static_cast<jlong
>(
180 ROCKSDB_NAMESPACE::WriteBatchInternal::Sequence(wb
));
184 * Class: org_rocksdb_WriteBatchTestInternalHelper
188 void Java_org_rocksdb_WriteBatchTestInternalHelper_append(JNIEnv
* /*env*/,
191 jlong jwb_handle_2
) {
192 auto* wb1
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle_1
);
193 assert(wb1
!= nullptr);
194 auto* wb2
= reinterpret_cast<ROCKSDB_NAMESPACE::WriteBatch
*>(jwb_handle_2
);
195 assert(wb2
!= nullptr);
197 ROCKSDB_NAMESPACE::WriteBatchInternal::Append(wb1
, wb2
);