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::Iterator methods from Java side.
8 
9 #include <jni.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <algorithm>
13 
14 #include "include/org_rocksdb_RocksIterator.h"
15 #include "rocksdb/iterator.h"
16 #include "rocksjni/portal.h"
17 
18 /*
19  * Class:     org_rocksdb_RocksIterator
20  * Method:    disposeInternal
21  * Signature: (J)V
22  */
Java_org_rocksdb_RocksIterator_disposeInternal(JNIEnv *,jobject,jlong handle)23 void Java_org_rocksdb_RocksIterator_disposeInternal(JNIEnv* /*env*/,
24                                                     jobject /*jobj*/,
25                                                     jlong handle) {
26   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
27   assert(it != nullptr);
28   delete it;
29 }
30 
31 /*
32  * Class:     org_rocksdb_RocksIterator
33  * Method:    isValid0
34  * Signature: (J)Z
35  */
Java_org_rocksdb_RocksIterator_isValid0(JNIEnv *,jobject,jlong handle)36 jboolean Java_org_rocksdb_RocksIterator_isValid0(JNIEnv* /*env*/,
37                                                  jobject /*jobj*/,
38                                                  jlong handle) {
39   return reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle)->Valid();
40 }
41 
42 /*
43  * Class:     org_rocksdb_RocksIterator
44  * Method:    seekToFirst0
45  * Signature: (J)V
46  */
Java_org_rocksdb_RocksIterator_seekToFirst0(JNIEnv *,jobject,jlong handle)47 void Java_org_rocksdb_RocksIterator_seekToFirst0(JNIEnv* /*env*/,
48                                                  jobject /*jobj*/,
49                                                  jlong handle) {
50   reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle)->SeekToFirst();
51 }
52 
53 /*
54  * Class:     org_rocksdb_RocksIterator
55  * Method:    seekToLast0
56  * Signature: (J)V
57  */
Java_org_rocksdb_RocksIterator_seekToLast0(JNIEnv *,jobject,jlong handle)58 void Java_org_rocksdb_RocksIterator_seekToLast0(JNIEnv* /*env*/,
59                                                 jobject /*jobj*/,
60                                                 jlong handle) {
61   reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle)->SeekToLast();
62 }
63 
64 /*
65  * Class:     org_rocksdb_RocksIterator
66  * Method:    next0
67  * Signature: (J)V
68  */
Java_org_rocksdb_RocksIterator_next0(JNIEnv *,jobject,jlong handle)69 void Java_org_rocksdb_RocksIterator_next0(JNIEnv* /*env*/, jobject /*jobj*/,
70                                           jlong handle) {
71   reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle)->Next();
72 }
73 
74 /*
75  * Class:     org_rocksdb_RocksIterator
76  * Method:    prev0
77  * Signature: (J)V
78  */
Java_org_rocksdb_RocksIterator_prev0(JNIEnv *,jobject,jlong handle)79 void Java_org_rocksdb_RocksIterator_prev0(JNIEnv* /*env*/, jobject /*jobj*/,
80                                           jlong handle) {
81   reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle)->Prev();
82 }
83 
84 /*
85  * Class:     org_rocksdb_RocksIterator
86  * Method:    seek0
87  * Signature: (J[BI)V
88  */
Java_org_rocksdb_RocksIterator_seek0(JNIEnv * env,jobject,jlong handle,jbyteArray jtarget,jint jtarget_len)89 void Java_org_rocksdb_RocksIterator_seek0(JNIEnv* env, jobject /*jobj*/,
90                                           jlong handle, jbyteArray jtarget,
91                                           jint jtarget_len) {
92   jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
93   if (target == nullptr) {
94     // exception thrown: OutOfMemoryError
95     return;
96   }
97 
98   ROCKSDB_NAMESPACE::Slice target_slice(reinterpret_cast<char*>(target),
99                                         jtarget_len);
100 
101   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
102   it->Seek(target_slice);
103 
104   env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
105 }
106 
107 /*
108  * Class:     org_rocksdb_RocksIterator
109  * Method:    seekDirect0
110  * Signature: (JLjava/nio/ByteBuffer;II)V
111  */
Java_org_rocksdb_RocksIterator_seekDirect0(JNIEnv * env,jobject,jlong handle,jobject jtarget,jint jtarget_off,jint jtarget_len)112 void Java_org_rocksdb_RocksIterator_seekDirect0(JNIEnv* env, jobject /*jobj*/,
113                                                 jlong handle, jobject jtarget,
114                                                 jint jtarget_off,
115                                                 jint jtarget_len) {
116   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
117   auto seek = [&it](ROCKSDB_NAMESPACE::Slice& target_slice) {
118     it->Seek(target_slice);
119   };
120   ROCKSDB_NAMESPACE::JniUtil::k_op_direct(seek, env, jtarget, jtarget_off,
121                                           jtarget_len);
122 }
123 
124 /*
125  * Class:     org_rocksdb_RocksIterator
126  * Method:    seekForPrevDirect0
127  * Signature: (JLjava/nio/ByteBuffer;II)V
128  */
Java_org_rocksdb_RocksIterator_seekForPrevDirect0(JNIEnv * env,jobject,jlong handle,jobject jtarget,jint jtarget_off,jint jtarget_len)129 void Java_org_rocksdb_RocksIterator_seekForPrevDirect0(
130     JNIEnv* env, jobject /*jobj*/, jlong handle, jobject jtarget,
131     jint jtarget_off, jint jtarget_len) {
132   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
133   auto seekPrev = [&it](ROCKSDB_NAMESPACE::Slice& target_slice) {
134     it->SeekForPrev(target_slice);
135   };
136   ROCKSDB_NAMESPACE::JniUtil::k_op_direct(seekPrev, env, jtarget, jtarget_off,
137                                           jtarget_len);
138 }
139 
140 /*
141  * Class:     org_rocksdb_RocksIterator
142  * Method:    seekForPrev0
143  * Signature: (J[BI)V
144  */
Java_org_rocksdb_RocksIterator_seekForPrev0(JNIEnv * env,jobject,jlong handle,jbyteArray jtarget,jint jtarget_len)145 void Java_org_rocksdb_RocksIterator_seekForPrev0(JNIEnv* env, jobject /*jobj*/,
146                                                  jlong handle,
147                                                  jbyteArray jtarget,
148                                                  jint jtarget_len) {
149   jbyte* target = env->GetByteArrayElements(jtarget, nullptr);
150   if (target == nullptr) {
151     // exception thrown: OutOfMemoryError
152     return;
153   }
154 
155   ROCKSDB_NAMESPACE::Slice target_slice(reinterpret_cast<char*>(target),
156                                         jtarget_len);
157 
158   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
159   it->SeekForPrev(target_slice);
160 
161   env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
162 }
163 
164 /*
165  * Class:     org_rocksdb_RocksIterator
166  * Method:    status0
167  * Signature: (J)V
168  */
Java_org_rocksdb_RocksIterator_status0(JNIEnv * env,jobject,jlong handle)169 void Java_org_rocksdb_RocksIterator_status0(JNIEnv* env, jobject /*jobj*/,
170                                             jlong handle) {
171   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
172   ROCKSDB_NAMESPACE::Status s = it->status();
173 
174   if (s.ok()) {
175     return;
176   }
177 
178   ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
179 }
180 
181 /*
182  * Class:     org_rocksdb_RocksIterator
183  * Method:    key0
184  * Signature: (J)[B
185  */
Java_org_rocksdb_RocksIterator_key0(JNIEnv * env,jobject,jlong handle)186 jbyteArray Java_org_rocksdb_RocksIterator_key0(JNIEnv* env, jobject /*jobj*/,
187                                                jlong handle) {
188   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
189   ROCKSDB_NAMESPACE::Slice key_slice = it->key();
190 
191   jbyteArray jkey = env->NewByteArray(static_cast<jsize>(key_slice.size()));
192   if (jkey == nullptr) {
193     // exception thrown: OutOfMemoryError
194     return nullptr;
195   }
196   env->SetByteArrayRegion(
197       jkey, 0, static_cast<jsize>(key_slice.size()),
198       const_cast<jbyte*>(reinterpret_cast<const jbyte*>(key_slice.data())));
199   return jkey;
200 }
201 
202 /*
203  * Class:     org_rocksdb_RocksIterator
204  * Method:    keyDirect0
205  * Signature: (JLjava/nio/ByteBuffer;II)I
206  */
Java_org_rocksdb_RocksIterator_keyDirect0(JNIEnv * env,jobject,jlong handle,jobject jtarget,jint jtarget_off,jint jtarget_len)207 jint Java_org_rocksdb_RocksIterator_keyDirect0(JNIEnv* env, jobject /*jobj*/,
208                                                jlong handle, jobject jtarget,
209                                                jint jtarget_off,
210                                                jint jtarget_len) {
211   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
212   ROCKSDB_NAMESPACE::Slice key_slice = it->key();
213   return ROCKSDB_NAMESPACE::JniUtil::copyToDirect(env, key_slice, jtarget,
214                                                   jtarget_off, jtarget_len);
215 }
216 
217 /*
218  * Class:     org_rocksdb_RocksIterator
219  * Method:    value0
220  * Signature: (J)[B
221  */
Java_org_rocksdb_RocksIterator_value0(JNIEnv * env,jobject,jlong handle)222 jbyteArray Java_org_rocksdb_RocksIterator_value0(JNIEnv* env, jobject /*jobj*/,
223                                                  jlong handle) {
224   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
225   ROCKSDB_NAMESPACE::Slice value_slice = it->value();
226 
227   jbyteArray jkeyValue =
228       env->NewByteArray(static_cast<jsize>(value_slice.size()));
229   if (jkeyValue == nullptr) {
230     // exception thrown: OutOfMemoryError
231     return nullptr;
232   }
233   env->SetByteArrayRegion(
234       jkeyValue, 0, static_cast<jsize>(value_slice.size()),
235       const_cast<jbyte*>(reinterpret_cast<const jbyte*>(value_slice.data())));
236   return jkeyValue;
237 }
238 
239 /*
240  * Class:     org_rocksdb_RocksIterator
241  * Method:    valueDirect0
242  * Signature: (JLjava/nio/ByteBuffer;II)I
243  */
Java_org_rocksdb_RocksIterator_valueDirect0(JNIEnv * env,jobject,jlong handle,jobject jtarget,jint jtarget_off,jint jtarget_len)244 jint Java_org_rocksdb_RocksIterator_valueDirect0(JNIEnv* env, jobject /*jobj*/,
245                                                  jlong handle, jobject jtarget,
246                                                  jint jtarget_off,
247                                                  jint jtarget_len) {
248   auto* it = reinterpret_cast<ROCKSDB_NAMESPACE::Iterator*>(handle);
249   ROCKSDB_NAMESPACE::Slice value_slice = it->value();
250   return ROCKSDB_NAMESPACE::JniUtil::copyToDirect(env, value_slice, jtarget,
251                                                   jtarget_off, jtarget_len);
252 }
253