1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
6 // This file implements the callback "bridge" between Java and C++ for
7 // rocksdb::Comparator.
9 #include "rocksjni/writebatchhandlerjnicallback.h"
10 #include "rocksjni/portal.h"
13 WriteBatchHandlerJniCallback::WriteBatchHandlerJniCallback(
14 JNIEnv
* env
, jobject jWriteBatchHandler
)
17 // Note: we want to access the Java WriteBatchHandler instance
18 // across multiple method calls, so we create a global ref
19 assert(jWriteBatchHandler
!= nullptr);
20 m_jWriteBatchHandler
= env
->NewGlobalRef(jWriteBatchHandler
);
21 if(m_jWriteBatchHandler
== nullptr) {
22 // exception thrown: OutOfMemoryError
26 m_jPutMethodId
= WriteBatchHandlerJni::getPutMethodId(env
);
27 if(m_jPutMethodId
== nullptr) {
32 m_jMergeMethodId
= WriteBatchHandlerJni::getMergeMethodId(env
);
33 if(m_jMergeMethodId
== nullptr) {
38 m_jDeleteMethodId
= WriteBatchHandlerJni::getDeleteMethodId(env
);
39 if(m_jDeleteMethodId
== nullptr) {
44 m_jDeleteRangeMethodId
= WriteBatchHandlerJni::getDeleteRangeMethodId(env
);
45 if (m_jDeleteRangeMethodId
== nullptr) {
50 m_jLogDataMethodId
= WriteBatchHandlerJni::getLogDataMethodId(env
);
51 if(m_jLogDataMethodId
== nullptr) {
56 m_jContinueMethodId
= WriteBatchHandlerJni::getContinueMethodId(env
);
57 if(m_jContinueMethodId
== nullptr) {
63 void WriteBatchHandlerJniCallback::Put(const Slice
& key
, const Slice
& value
) {
64 const jbyteArray j_key
= sliceToJArray(key
);
65 if(j_key
== nullptr) {
67 if(m_env
->ExceptionCheck()) {
68 m_env
->ExceptionDescribe();
73 const jbyteArray j_value
= sliceToJArray(value
);
74 if(j_value
== nullptr) {
76 if(m_env
->ExceptionCheck()) {
77 m_env
->ExceptionDescribe();
79 if(j_key
!= nullptr) {
80 m_env
->DeleteLocalRef(j_key
);
85 m_env
->CallVoidMethod(
90 if(m_env
->ExceptionCheck()) {
92 m_env
->ExceptionDescribe();
93 if(j_value
!= nullptr) {
94 m_env
->DeleteLocalRef(j_value
);
96 if(j_key
!= nullptr) {
97 m_env
->DeleteLocalRef(j_key
);
102 if(j_value
!= nullptr) {
103 m_env
->DeleteLocalRef(j_value
);
105 if(j_key
!= nullptr) {
106 m_env
->DeleteLocalRef(j_key
);
110 void WriteBatchHandlerJniCallback::Merge(const Slice
& key
, const Slice
& value
) {
111 const jbyteArray j_key
= sliceToJArray(key
);
112 if(j_key
== nullptr) {
114 if(m_env
->ExceptionCheck()) {
115 m_env
->ExceptionDescribe();
120 const jbyteArray j_value
= sliceToJArray(value
);
121 if(j_value
== nullptr) {
123 if(m_env
->ExceptionCheck()) {
124 m_env
->ExceptionDescribe();
126 if(j_key
!= nullptr) {
127 m_env
->DeleteLocalRef(j_key
);
132 m_env
->CallVoidMethod(
133 m_jWriteBatchHandler
,
137 if(m_env
->ExceptionCheck()) {
139 m_env
->ExceptionDescribe();
140 if(j_value
!= nullptr) {
141 m_env
->DeleteLocalRef(j_value
);
143 if(j_key
!= nullptr) {
144 m_env
->DeleteLocalRef(j_key
);
149 if(j_value
!= nullptr) {
150 m_env
->DeleteLocalRef(j_value
);
152 if(j_key
!= nullptr) {
153 m_env
->DeleteLocalRef(j_key
);
157 void WriteBatchHandlerJniCallback::Delete(const Slice
& key
) {
158 const jbyteArray j_key
= sliceToJArray(key
);
159 if(j_key
== nullptr) {
161 if(m_env
->ExceptionCheck()) {
162 m_env
->ExceptionDescribe();
167 m_env
->CallVoidMethod(
168 m_jWriteBatchHandler
,
171 if(m_env
->ExceptionCheck()) {
173 m_env
->ExceptionDescribe();
174 if(j_key
!= nullptr) {
175 m_env
->DeleteLocalRef(j_key
);
180 if(j_key
!= nullptr) {
181 m_env
->DeleteLocalRef(j_key
);
185 void WriteBatchHandlerJniCallback::DeleteRange(const Slice
& beginKey
,
186 const Slice
& endKey
) {
187 const jbyteArray j_beginKey
= sliceToJArray(beginKey
);
188 if (j_beginKey
== nullptr) {
190 if (m_env
->ExceptionCheck()) {
191 m_env
->ExceptionDescribe();
196 const jbyteArray j_endKey
= sliceToJArray(beginKey
);
197 if (j_endKey
== nullptr) {
199 if (m_env
->ExceptionCheck()) {
200 m_env
->ExceptionDescribe();
205 m_env
->CallVoidMethod(m_jWriteBatchHandler
, m_jDeleteRangeMethodId
,
206 j_beginKey
, j_endKey
);
207 if (m_env
->ExceptionCheck()) {
209 m_env
->ExceptionDescribe();
210 if (j_beginKey
!= nullptr) {
211 m_env
->DeleteLocalRef(j_beginKey
);
213 if (j_endKey
!= nullptr) {
214 m_env
->DeleteLocalRef(j_endKey
);
219 if (j_beginKey
!= nullptr) {
220 m_env
->DeleteLocalRef(j_beginKey
);
223 if (j_endKey
!= nullptr) {
224 m_env
->DeleteLocalRef(j_endKey
);
228 void WriteBatchHandlerJniCallback::LogData(const Slice
& blob
) {
229 const jbyteArray j_blob
= sliceToJArray(blob
);
230 if(j_blob
== nullptr) {
232 if(m_env
->ExceptionCheck()) {
233 m_env
->ExceptionDescribe();
238 m_env
->CallVoidMethod(
239 m_jWriteBatchHandler
,
242 if(m_env
->ExceptionCheck()) {
244 m_env
->ExceptionDescribe();
245 if(j_blob
!= nullptr) {
246 m_env
->DeleteLocalRef(j_blob
);
251 if(j_blob
!= nullptr) {
252 m_env
->DeleteLocalRef(j_blob
);
256 bool WriteBatchHandlerJniCallback::Continue() {
257 jboolean jContinue
= m_env
->CallBooleanMethod(
258 m_jWriteBatchHandler
,
259 m_jContinueMethodId
);
260 if(m_env
->ExceptionCheck()) {
262 m_env
->ExceptionDescribe();
265 return static_cast<bool>(jContinue
== JNI_TRUE
);
269 * Creates a Java Byte Array from the data in a Slice
271 * When calling this function
272 * you must remember to call env->DeleteLocalRef
273 * on the result after you have finished with it
275 * @param s A Slice to convery to a Java byte array
277 * @return A reference to a Java byte array, or a nullptr if an
280 jbyteArray
WriteBatchHandlerJniCallback::sliceToJArray(const Slice
& s
) {
281 jbyteArray ja
= m_env
->NewByteArray(static_cast<jsize
>(s
.size()));
283 // exception thrown: OutOfMemoryError
287 m_env
->SetByteArrayRegion(
288 ja
, 0, static_cast<jsize
>(s
.size()),
289 const_cast<jbyte
*>(reinterpret_cast<const jbyte
*>(s
.data())));
290 if(m_env
->ExceptionCheck()) {
292 m_env
->DeleteLocalRef(ja
);
294 // exception thrown: ArrayIndexOutOfBoundsException
301 WriteBatchHandlerJniCallback::~WriteBatchHandlerJniCallback() {
302 if(m_jWriteBatchHandler
!= nullptr) {
303 m_env
->DeleteGlobalRef(m_jWriteBatchHandler
);
306 } // namespace rocksdb