blob: 96f546a11b169f310fe7bbd2b98b59a32484581a [file] [log] [blame]
yoshi28bac132014-01-22 11:00:17 -08001/* Copyright (c) 2013 Stanford University
2 *
3 * Permission to use, copy, modify, and distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 */
15
Yuta HIGUCHIb6cf5832014-03-26 17:57:58 -070016/*
17 * Future TODO memo.
18 * - Throwing exception is a bit expensive in Java. (Construct backtrace, etc.)
19 * Those native methods should be modified to notify conditional failure as
20 * part of return value object instead of exception to eliminate overhead.
21 * - Inner classes in JRamCloud.java should be moved out to be a separate
22 * stand alone class, to eliminate workaround 00024 signature in
23 * C methods.
Yuta HIGUCHId150ece2014-04-29 16:25:36 -070024 * - Define and support some of ClientException sub-classes.
Yuta HIGUCHIb6cf5832014-03-26 17:57:58 -070025 *
26 */
27
yoshi28bac132014-01-22 11:00:17 -080028#include <RamCloud.h>
29#include <TableEnumerator.h>
30#include <Object.h>
31#include "edu_stanford_ramcloud_JRamCloud.h"
yoshi28bac132014-01-22 11:00:17 -080032
33using namespace RAMCloud;
34
35/// Our JRamCloud java library is packaged under "edu.stanford.ramcloud".
36/// We will need this when using FindClass, etc.
37#define PACKAGE_PATH "edu/stanford/ramcloud/"
38
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080039// Java RejectRules flags bit index
40const static int DoesntExist = 1;
41const static int Exists = 1 << 1;
42const static int VersionLeGiven = 1 << 2;
43const static int VersionNeGiven = 1 << 3;
44
yoshi28bac132014-01-22 11:00:17 -080045#define check_null(var, msg) \
46 if (var == NULL) { \
47 throw Exception(HERE, "JRamCloud: NULL returned: " msg "\n"); \
48 }
49
50/**
51 * This class provides a simple means of extracting C-style strings
52 * from a jstring and cleans up when the destructor is called. This
53 * avoids having to manually do the annoying GetStringUTFChars /
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080054 * ReleaseStringUTFChars dance.
yoshi28bac132014-01-22 11:00:17 -080055 */
56class JStringGetter {
57 public:
58 JStringGetter(JNIEnv* env, jstring jString)
59 : env(env)
60 , jString(jString)
61 , string(env->GetStringUTFChars(jString, 0))
62 {
63 check_null(string, "GetStringUTFChars failed");
64 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080065
yoshi28bac132014-01-22 11:00:17 -080066 ~JStringGetter()
67 {
68 if (string != NULL)
69 env->ReleaseStringUTFChars(jString, string);
70 }
71
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080072 private:
yoshi28bac132014-01-22 11:00:17 -080073 JNIEnv* env;
74 jstring jString;
75
76 public:
77 const char* const string;
78};
79
80/**
81 * This class provides a simple means of accessing jbyteArrays as
82 * C-style void* buffers and cleans up when the destructor is called.
83 * This avoids having to manually do the annoying GetByteArrayElements /
84 * ReleaseByteArrayElements dance.
85 */
86class JByteArrayGetter {
87 public:
88 JByteArrayGetter(JNIEnv* env, jbyteArray jByteArray)
89 : env(env)
90 , jByteArray(jByteArray)
91 , pointer(static_cast<void*>(env->GetByteArrayElements(jByteArray, 0)))
92 , length(env->GetArrayLength(jByteArray))
93 {
94 check_null(pointer, "GetByteArrayElements failed");
95 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080096
yoshi28bac132014-01-22 11:00:17 -080097 ~JByteArrayGetter()
98 {
99 if (pointer != NULL) {
100 env->ReleaseByteArrayElements(jByteArray,
101 reinterpret_cast<jbyte*>(pointer),
102 0);
103 }
104 }
105
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800106 private:
yoshi28bac132014-01-22 11:00:17 -0800107 JNIEnv* env;
108 jbyteArray jByteArray;
109
110 public:
111 void* const pointer;
112 const jsize length;
113};
114
115class JByteArrayReference {
116 public:
117 JByteArrayReference(JNIEnv* env, jbyteArray jByteArray)
118 : env(env)
119 , jByteArray(jByteArray)
120 , pointer(static_cast<const void*>(env->GetByteArrayElements(jByteArray, 0)))
121 , length(env->GetArrayLength(jByteArray))
122 {
123 check_null(pointer, "GetByteArrayElements failed");
124 }
125
126 ~JByteArrayReference()
127 {
128 if (pointer != NULL) {
129 env->ReleaseByteArrayElements(jByteArray,
130 (jbyte*)pointer,
131 JNI_ABORT);
132 }
133 }
134
135 private:
136 JNIEnv* env;
137 jbyteArray jByteArray;
138
139 public:
140 const void* const pointer;
141 const jsize length;
142};
143
144static RamCloud*
145getRamCloud(JNIEnv* env, jobject jRamCloud)
146{
147 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud"));
148 const static jfieldID fieldId = env->GetFieldID(cls, "ramcloudObjectPointer", "J");
149 return reinterpret_cast<RamCloud*>(env->GetLongField(jRamCloud, fieldId));
150}
151
152static TableEnumerator*
153getTableEnumerator(JNIEnv* env, jobject jTableEnumerator)
154{
155 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumerator"));
156 const static jfieldID fieldId = env->GetFieldID(cls, "tableEnumeratorObjectPointer", "J");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800157 return reinterpret_cast<TableEnumerator*>(env->GetLongField(jTableEnumerator, fieldId));
yoshi28bac132014-01-22 11:00:17 -0800158}
159
160static void
161createException(JNIEnv* env, jobject jRamCloud, const char* name)
162{
163 // Need to specify the full class name, including the package. To make it
164 // slightly more complicated, our exceptions are nested under the JRamCloud
165 // class.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800166 string fullName(PACKAGE_PATH "JRamCloud$");
yoshi28bac132014-01-22 11:00:17 -0800167 fullName += name;
168
yoshi28bac132014-01-22 11:00:17 -0800169 jclass cls = env->FindClass(fullName.c_str());
170 check_null(cls, "FindClass failed");
171
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800172 env->ThrowNew(cls, "");
173}
yoshi28bac132014-01-22 11:00:17 -0800174
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800175static void
176setRejectRules(JNIEnv* env, jobject jRejectRules, RejectRules& rules)
177{
178 const static jclass jc_RejectRules = (jclass) env->NewGlobalRef(
179 env->FindClass(PACKAGE_PATH "JRamCloud$RejectRules"));
180 static const jfieldID jf_flags = env->GetFieldID(jc_RejectRules, "flags", "I");
181 check_null(jf_flags, "flags field ID is null");
182 static const jfieldID jf_givenVersion = env->GetFieldID(jc_RejectRules,
183 "givenVersion", "J");
184 check_null(jf_givenVersion, "givenVersion field ID is null");
yoshi28bac132014-01-22 11:00:17 -0800185
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800186 const jint rejectFlag = env->GetIntField(jRejectRules, jf_flags);
187 rules.doesntExist = (rejectFlag & DoesntExist) != 0;
188 rules.exists = (rejectFlag & Exists) != 0;
189 rules.versionLeGiven = (rejectFlag & VersionLeGiven) != 0;
190 rules.versionNeGiven = (rejectFlag & VersionNeGiven) != 0;
191 if (rules.versionLeGiven || rules.versionNeGiven) {
192 rules.givenVersion = env->GetLongField(jRejectRules, jf_givenVersion);
193 }
yoshi28bac132014-01-22 11:00:17 -0800194}
195
196/**
197 * This macro is used to catch C++ exceptions and convert them into Java
198 * exceptions. Be sure to wrap the individual RamCloud:: calls in try blocks,
199 * rather than the entire methods, since doing so with functions that return
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800200 * non-void is a bad idea with undefined(?) behaviour.
yoshi28bac132014-01-22 11:00:17 -0800201 *
202 * _returnValue is the value that should be returned from the JNI function
203 * when an exception is caught and generated in Java. As far as I can tell,
204 * the exception fires immediately upon returning from the JNI method. I
205 * don't think anything else would make sense, but the JNI docs kind of
206 * suck.
207 */
208#define EXCEPTION_CATCHER(_returnValue) \
209 catch (TableDoesntExistException& e) { \
210 createException(env, jRamCloud, "TableDoesntExistException"); \
211 return _returnValue; \
212 } catch (ObjectDoesntExistException& e) { \
213 createException(env, jRamCloud, "ObjectDoesntExistException"); \
214 return _returnValue; \
215 } catch (ObjectExistsException& e) { \
216 createException(env, jRamCloud, "ObjectExistsException"); \
217 return _returnValue; \
218 } catch (WrongVersionException& e) { \
219 createException(env, jRamCloud, "WrongVersionException"); \
220 return _returnValue; \
221 } catch (RejectRulesException& e) { \
222 createException(env, jRamCloud, "RejectRulesException"); \
223 return _returnValue; \
224 } catch (InvalidObjectException& e) { \
225 createException(env, jRamCloud, "InvalidObjectException"); \
226 return _returnValue; \
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700227 } catch (ClientException& e) { \
228 createException(env, jRamCloud, "ClientException"); \
229 return _returnValue; \
yoshi28bac132014-01-22 11:00:17 -0800230 }
231
232/*
233 * Class: edu_stanford_ramcloud_JRamCloud
234 * Method: connect
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700235 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
yoshi28bac132014-01-22 11:00:17 -0800236 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800237JNIEXPORT jlong
yoshi28bac132014-01-22 11:00:17 -0800238JNICALL Java_edu_stanford_ramcloud_JRamCloud_connect(JNIEnv *env,
239 jclass jRamCloud,
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700240 jstring coordinatorLocator,
241 jstring clusterName)
yoshi28bac132014-01-22 11:00:17 -0800242{
243 JStringGetter locator(env, coordinatorLocator);
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700244 JStringGetter cluster(env, clusterName);
yoshi28bac132014-01-22 11:00:17 -0800245 RamCloud* ramcloud = NULL;
246 try {
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700247 ramcloud = new RamCloud(locator.string, cluster.string);
Yuta HIGUCHI52617722014-03-14 13:36:10 -0700248 } EXCEPTION_CATCHER((jlong)(NULL));
yoshi28bac132014-01-22 11:00:17 -0800249 return reinterpret_cast<jlong>(ramcloud);
250}
251
252/*
253 * Class: edu_stanford_ramcloud_JRamCloud
254 * Method: disconnect
255 * Signature: (J)V
256 */
257JNIEXPORT void
258JNICALL Java_edu_stanford_ramcloud_JRamCloud_disconnect(JNIEnv *env,
259 jclass jRamCloud,
260 jlong ramcloudObjectPointer)
261{
262 delete reinterpret_cast<RamCloud*>(ramcloudObjectPointer);
263}
264
265/*
266 * Class: edu_stanford_ramcloud_JRamCloud
267 * Method: createTable
268 * Signature: (Ljava/lang/String;)I
269 */
270JNIEXPORT jlong
271JNICALL Java_edu_stanford_ramcloud_JRamCloud_createTable__Ljava_lang_String_2(JNIEnv *env,
272 jobject jRamCloud,
273 jstring jTableName)
274{
275 return Java_edu_stanford_ramcloud_JRamCloud_createTable__Ljava_lang_String_2I(env,
276 jRamCloud,
277 jTableName,
278 1);
279}
280
281/*
282 * Class: edu_stanford_ramcloud_JRamCloud
283 * Method: createTable
284 * Signature: (Ljava/lang/String;I)I
285 */
286JNIEXPORT jlong
287JNICALL Java_edu_stanford_ramcloud_JRamCloud_createTable__Ljava_lang_String_2I(JNIEnv *env,
288 jobject jRamCloud,
289 jstring jTableName,
290 jint jServerSpan)
291{
292 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
293 JStringGetter tableName(env, jTableName);
294 uint64_t tableId;
295 try {
296 tableId = ramcloud->createTable(tableName.string, jServerSpan);
297 } EXCEPTION_CATCHER(-1);
298 return static_cast<jlong>(tableId);
299}
300
301/*
302 * Class: edu_stanford_ramcloud_JRamCloud
303 * Method: dropTable
304 * Signature: (Ljava/lang/String;)I
305 */
306JNIEXPORT void
307JNICALL Java_edu_stanford_ramcloud_JRamCloud_dropTable(JNIEnv *env,
308 jobject jRamCloud,
309 jstring jTableName)
310{
311 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
312 JStringGetter tableName(env, jTableName);
313 try {
314 ramcloud->dropTable(tableName.string);
315 } EXCEPTION_CATCHER();
316}
317
318/*
319 * Class: edu_stanford_ramcloud_JRamCloud
320 * Method: getTableId
321 * Signature: (Ljava/lang/String;)J
322 */
323JNIEXPORT jlong
324JNICALL Java_edu_stanford_ramcloud_JRamCloud_getTableId(JNIEnv *env,
325 jobject jRamCloud,
326 jstring jTableName)
327{
328 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
329 JStringGetter tableName(env, jTableName);
330 uint64_t tableId;
331 try {
332 tableId = ramcloud->getTableId(tableName.string);
333 } EXCEPTION_CATCHER(-1);
334 return tableId;
335}
336
337/*
338 * Class: edu_stanford_ramcloud_JRamCloud
339 * Method: read
340 * Signature: (J[B)LJRamCloud/Object;
341 */
342JNIEXPORT jobject
343JNICALL Java_edu_stanford_ramcloud_JRamCloud_read__J_3B(JNIEnv *env,
344 jobject jRamCloud,
345 jlong jTableId,
346 jbyteArray jKey)
347{
348 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
349 JByteArrayReference key(env, jKey);
350
351 Buffer buffer;
352 uint64_t version;
353 try {
354 ramcloud->read(jTableId, key.pointer, key.length, &buffer, NULL, &version);
355 } EXCEPTION_CATCHER(NULL);
356
357 jbyteArray jValue = env->NewByteArray(buffer.getTotalLength());
358 check_null(jValue, "NewByteArray failed");
359 JByteArrayGetter value(env, jValue);
360 buffer.copy(0, buffer.getTotalLength(), value.pointer);
361
362 // Note that using 'javap -s' on the class file will print out the method
363 // signatures (the third argument to GetMethodID).
364 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
365 check_null(cls, "FindClass failed");
366
367 const static jmethodID methodId = env->GetMethodID(cls,
368 "<init>",
Yoshi Muroie7693b12014-02-19 19:41:17 -0800369 "([B[BJ)V");
yoshi28bac132014-01-22 11:00:17 -0800370 check_null(methodId, "GetMethodID failed");
371
372 return env->NewObject(cls,
373 methodId,
yoshi28bac132014-01-22 11:00:17 -0800374 jKey,
375 jValue,
376 static_cast<jlong>(version));
377}
378
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800379// Workaround for javah generating incorrect signature for inner class
380// 00024 is an escaped signature for $ character
381#ifdef __cplusplus
382extern "C" {
383#endif
384JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_read__J_3BLedu_stanford_ramcloud_JRamCloud_00024RejectRules_2
385 (JNIEnv *, jobject, jlong, jbyteArray, jobject);
386#ifdef __cplusplus
387}
388#endif
389
yoshi28bac132014-01-22 11:00:17 -0800390/*
391 * Class: edu_stanford_ramcloud_JRamCloud
392 * Method: read
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800393 * Signature: (J[BLedu/stanford/ramcloud/JRamCloud/RejectRules;)Ledu/stanford/ramcloud/JRamCloud/Object;
yoshi28bac132014-01-22 11:00:17 -0800394 */
395JNIEXPORT jobject
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800396JNICALL Java_edu_stanford_ramcloud_JRamCloud_read__J_3BLedu_stanford_ramcloud_JRamCloud_00024RejectRules_2(JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800397 jobject jRamCloud,
398 jlong jTableId,
399 jbyteArray jKey,
400 jobject jRejectRules)
401{
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800402 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
403 JByteArrayReference key(env, jKey);
404
405 Buffer buffer;
406 uint64_t version;
407 RejectRules rules = {};
408 setRejectRules(env, jRejectRules, rules);
409
410 try {
411 ramcloud->read(jTableId, key.pointer, key.length, &buffer, &rules, &version);
412 } EXCEPTION_CATCHER(NULL);
413
414 jbyteArray jValue = env->NewByteArray(buffer.getTotalLength());
415 check_null(jValue, "NewByteArray failed");
416 JByteArrayGetter value(env, jValue);
417 buffer.copy(0, buffer.getTotalLength(), value.pointer);
418
419 // Note that using 'javap -s' on the class file will print out the method
420 // signatures (the third argument to GetMethodID).
421 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
422 check_null(cls, "FindClass failed");
423
424 const static jmethodID methodId = env->GetMethodID(cls,
425 "<init>",
426 "([B[BJ)V");
427 check_null(methodId, "GetMethodID failed");
428
429 return env->NewObject(cls,
430 methodId,
431 jKey,
432 jValue,
433 static_cast<jlong>(version));
yoshi28bac132014-01-22 11:00:17 -0800434}
435
436/*
437 * Class: edu_stanford_ramcloud_JRamCloud
438 * Method: multiRead
439 * Signature: ([Ledu/stanford/ramcloud/JRamCloud$multiReadObject;I)[Ledu/stanford/ramcloud/JRamCloud$Object;
440 */
441JNIEXPORT jobjectArray
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800442JNICALL Java_edu_stanford_ramcloud_JRamCloud_multiRead(JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800443 jobject jRamCloud,
Yoshi Muroi2c170602014-02-15 08:31:28 -0800444 jlongArray jTableId,
445 jobjectArray jKeyData,
Yoshi Muroie7693b12014-02-19 19:41:17 -0800446 jshortArray jKeyLength,
Yoshi Muroi2c170602014-02-15 08:31:28 -0800447 jint jrequestNum){
yoshi28bac132014-01-22 11:00:17 -0800448
449 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
Yoshi Muroi2c170602014-02-15 08:31:28 -0800450 MultiReadObject objects[jrequestNum];
451 Tub<Buffer> values[jrequestNum];
452 jbyteArray jKey[jrequestNum];
453 MultiReadObject* requests[jrequestNum];
yoshi28bac132014-01-22 11:00:17 -0800454
Yoshi Muroie7693b12014-02-19 19:41:17 -0800455 jlong tableId;
456 jshort keyLength;
457 jbyte* keyData[jrequestNum];
yoshi28bac132014-01-22 11:00:17 -0800458
Yoshi Muroi2c170602014-02-15 08:31:28 -0800459 for (int i = 0 ; i < jrequestNum ; i++){
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800460 jKey[i] = (jbyteArray)env->GetObjectArrayElement(jKeyData, i);
yoshi28bac132014-01-22 11:00:17 -0800461
Yoshi Muroie7693b12014-02-19 19:41:17 -0800462 env->GetShortArrayRegion(jKeyLength, i, 1, &keyLength);
yoshi28bac132014-01-22 11:00:17 -0800463
Yoshi Muroie7693b12014-02-19 19:41:17 -0800464 keyData[i] = (jbyte *) malloc(keyLength);
465 env->GetByteArrayRegion(jKey[i], 0, keyLength, keyData[i]);
yoshi28bac132014-01-22 11:00:17 -0800466
Yoshi Muroie7693b12014-02-19 19:41:17 -0800467 env->GetLongArrayRegion(jTableId, i, 1, &tableId);
468 objects[i].tableId = tableId;
469 objects[i].key = keyData[i];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800470 objects[i].keyLength = keyLength;
yoshi28bac132014-01-22 11:00:17 -0800471 objects[i].value = &values[i];
472 requests[i] = &objects[i];
473 }
474
475 try {
Yoshi Muroi2c170602014-02-15 08:31:28 -0800476 ramcloud->multiRead(requests, jrequestNum);
yoshi28bac132014-01-22 11:00:17 -0800477 } EXCEPTION_CATCHER(NULL);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800478
yoshi28bac132014-01-22 11:00:17 -0800479 const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
480 check_null(jc_RcObject, "FindClass failed");
481 const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
482 "<init>",
Yoshi Muroie7693b12014-02-19 19:41:17 -0800483 "([B[BJ)V");
yoshi28bac132014-01-22 11:00:17 -0800484
Yoshi Muroi2c170602014-02-15 08:31:28 -0800485 jobjectArray outJNIArray = env->NewObjectArray(jrequestNum, jc_RcObject , NULL);
yoshi28bac132014-01-22 11:00:17 -0800486 check_null(outJNIArray, "NewObjectArray failed");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800487
Yoshi Muroi2c170602014-02-15 08:31:28 -0800488 for (int i = 0 ; i < jrequestNum ; i++) {
yoshi28bac132014-01-22 11:00:17 -0800489 if (objects[i].status == 0) {
490 jbyteArray jValue = env->NewByteArray(values[i].get()->getTotalLength());
491 check_null(jValue, "NewByteArray failed");
492 JByteArrayGetter value(env, jValue);
493 values[i].get()->copy(0, values[i].get()->getTotalLength(), value.pointer);
Yuta HIGUCHI52617722014-03-14 13:36:10 -0700494 jobject obj = env->NewObject(jc_RcObject, jm_init, jKey[i], jValue, (jlong)objects[i].version);
yoshi28bac132014-01-22 11:00:17 -0800495 check_null(obj, "NewObject failed");
496 env->SetObjectArrayElement(outJNIArray, i, obj);
497 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800498 free(keyData[i]);
yoshi28bac132014-01-22 11:00:17 -0800499 }
500 return outJNIArray;
501}
502
503
504/*
505 * Class: edu_stanford_ramcloud_JRamCloud
506 * Method: remove
507 * Signature: (J[B)J
508 */
509JNIEXPORT jlong
510JNICALL Java_edu_stanford_ramcloud_JRamCloud_remove__J_3B(JNIEnv *env,
511 jobject jRamCloud,
512 jlong jTableId,
513 jbyteArray jKey)
514{
515 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
516 JByteArrayReference key(env, jKey);
Yuta HIGUCHI66ca1bf2014-03-12 18:34:09 -0700517 uint64_t version = VERSION_NONEXISTENT;
yoshi28bac132014-01-22 11:00:17 -0800518 try {
519 ramcloud->remove(jTableId, key.pointer, key.length, NULL, &version);
520 } EXCEPTION_CATCHER(-1);
521 return static_cast<jlong>(version);
522}
523
Yuta HIGUCHI9402dab2014-01-30 19:54:31 -0800524
525// Workaround for javah generating incorrect signature for inner class
526// 00024 is an escaped signature for $ character
527#ifdef __cplusplus
528extern "C" {
529#endif
530JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_remove__J_3BLedu_stanford_ramcloud_JRamCloud_00024RejectRules_2
531 (JNIEnv *, jobject, jlong, jbyteArray, jobject);
532#ifdef __cplusplus
533}
534#endif
535
yoshi28bac132014-01-22 11:00:17 -0800536/*
537 * Class: edu_stanford_ramcloud_JRamCloud
538 * Method: remove
Yuta HIGUCHI9402dab2014-01-30 19:54:31 -0800539 * Signature: (J[BLedu/stanford/ramcloud/JRamCloud/$RejectRules;)J
yoshi28bac132014-01-22 11:00:17 -0800540 */
541JNIEXPORT jlong
Yuta HIGUCHI9402dab2014-01-30 19:54:31 -0800542JNICALL Java_edu_stanford_ramcloud_JRamCloud_remove__J_3BLedu_stanford_ramcloud_JRamCloud_00024RejectRules_2(JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800543 jobject jRamCloud,
544 jlong jTableId,
545 jbyteArray jKey,
546 jobject jRejectRules)
547{
yoshi28bac132014-01-22 11:00:17 -0800548 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
549 JByteArrayReference key(env, jKey);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800550 RejectRules rules = {};
551 setRejectRules(env, jRejectRules, rules);
Yuta HIGUCHI66ca1bf2014-03-12 18:34:09 -0700552 uint64_t version = VERSION_NONEXISTENT;
yoshi28bac132014-01-22 11:00:17 -0800553 try {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800554 ramcloud->remove(jTableId, key.pointer, key.length, &rules, &version);
yoshi28bac132014-01-22 11:00:17 -0800555 } EXCEPTION_CATCHER(-1);
556 return static_cast<jlong>(version);
557}
558
559/*
560 * Class: edu_stanford_ramcloud_JRamCloud
561 * Method: write
562 * Signature: (J[B[B)J
563 */
564JNIEXPORT jlong
565JNICALL Java_edu_stanford_ramcloud_JRamCloud_write__J_3B_3B(JNIEnv *env,
566 jobject jRamCloud,
567 jlong jTableId,
568 jbyteArray jKey,
569 jbyteArray jValue)
570{
571 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
572 JByteArrayReference key(env, jKey);
573 JByteArrayGetter value(env, jValue);
574 uint64_t version;
575 try {
576 ramcloud->write(jTableId,
577 key.pointer, key.length,
578 value.pointer, value.length,
579 NULL,
580 &version);
581 } EXCEPTION_CATCHER(-1);
582 return static_cast<jlong>(version);
583}
584
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800585// Workaround for javah generating incorrect signature for inner class
586// 00024 is an escaped signature for $ character
587#ifdef __cplusplus
588extern "C" {
589#endif
590JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_write__J_3B_3BLedu_stanford_ramcloud_JRamCloud_00024RejectRules_2
591 (JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jobject);
592#ifdef __cplusplus
593}
594#endif
595
yoshi28bac132014-01-22 11:00:17 -0800596/*
597 * Class: edu_stanford_ramcloud_JRamCloud
598 * Method: write
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800599 * Signature: (J[B[BLedu/stanford/ramcloud/JRamCloud/RejectRules;)J
yoshi28bac132014-01-22 11:00:17 -0800600 */
601JNIEXPORT jlong
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800602JNICALL Java_edu_stanford_ramcloud_JRamCloud_write__J_3B_3BLedu_stanford_ramcloud_JRamCloud_00024RejectRules_2(JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800603 jobject jRamCloud,
604 jlong jTableId,
605 jbyteArray jKey,
606 jbyteArray jValue,
607 jobject jRejectRules)
608{
yoshi28bac132014-01-22 11:00:17 -0800609 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
610 JByteArrayReference key(env, jKey);
611 JByteArrayGetter value(env, jValue);
yoshi28bac132014-01-22 11:00:17 -0800612 RejectRules rules = {};
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800613 setRejectRules(env, jRejectRules, rules);
614 uint64_t version;
yoshi28bac132014-01-22 11:00:17 -0800615 try {
616 ramcloud->write(jTableId,
617 key.pointer, key.length,
618 value.pointer, value.length,
619 &rules,
620 &version);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800621 } EXCEPTION_CATCHER(-1);
yoshi28bac132014-01-22 11:00:17 -0800622 return static_cast<jlong> (version);
623}
624
625/*
626 * Class: edu_stanford_ramcloud_JRamCloud_TableEnumerator
627 * Method: init
628 * Signature: (J)V
629 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800630JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_init(JNIEnv *env,
631 jobject jTableEnumerator,
yoshi28bac132014-01-22 11:00:17 -0800632 jlong jTableId)
633{
634 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumerator"));
635 const static jfieldID fieldId = env->GetFieldID(cls, "ramCloudObjectPointer", "J");
636 RamCloud* ramcloud = reinterpret_cast<RamCloud*>(env->GetLongField(jTableEnumerator, fieldId));
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800637
Yuta HIGUCHIa7ec0732014-03-10 16:01:06 -0700638 return reinterpret_cast<jlong>(new TableEnumerator(*ramcloud, jTableId, false));
yoshi28bac132014-01-22 11:00:17 -0800639}
640
641/*
642 * Class: edu_stanford_ramcloud_JRamCloud_TableEnumerator
643 * Method: hasNext
644 * Signature: ()Z
645 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800646JNIEXPORT jboolean JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_hasNext( JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800647 jobject jTableEnumerator)
648{
649 TableEnumerator* tableEnum = getTableEnumerator(env, jTableEnumerator);
650 return static_cast<jboolean>(tableEnum->hasNext());
651}
652
653/*
654 * Class: edu_stanford_ramcloud_JRamCloud_TableEnumerator
655 * Method: next
656 * Signature: ()Ledu/stanford/ramcloud/JRamCloud/Object;
657 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800658JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_next( JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800659 jobject jTableEnumerator)
660{
661 TableEnumerator* tableEnum = getTableEnumerator(env, jTableEnumerator);
662
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800663 if (tableEnum->hasNext()) {
yoshi28bac132014-01-22 11:00:17 -0800664 uint32_t size = 0;
665 const void* buffer = 0;
666 uint64_t version = 0;
667
668 tableEnum->next(&size, &buffer);
669 Object object(buffer, size);
670
671 jbyteArray jKey = env->NewByteArray(object.getKeyLength());
672 jbyteArray jValue = env->NewByteArray(object.getDataLength());
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800673
yoshi28bac132014-01-22 11:00:17 -0800674 JByteArrayGetter key(env, jKey);
675 JByteArrayGetter value(env, jValue);
676
677 memcpy(key.pointer, object.getKey(), object.getKeyLength());
678 memcpy(value.pointer, object.getData(), object.getDataLength());
679
680 version = object.getVersion();
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800681
yoshi28bac132014-01-22 11:00:17 -0800682 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
683 check_null(cls, "FindClass failed");
684 const static jmethodID methodId = env->GetMethodID(cls,
685 "<init>",
Yoshi Muroie7693b12014-02-19 19:41:17 -0800686 "([B[BJ)V");
yoshi28bac132014-01-22 11:00:17 -0800687 check_null(methodId, "GetMethodID failed");
688 return env->NewObject(cls,
689 methodId,
yoshi28bac132014-01-22 11:00:17 -0800690 jKey,
691 jValue,
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800692 static_cast<jlong>(version));
693 } else {
yoshi28bac132014-01-22 11:00:17 -0800694 return NULL;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800695 }
yoshi28bac132014-01-22 11:00:17 -0800696}
697
698/*
699 * Class: edu_stanford_ramcloud_JRamCloud
Yoshi Muroie7693b12014-02-19 19:41:17 -0800700 * Method: getTableObjects
701 * Signature: (JJ)Ledu/stanford/ramcloud/JRamCloud/TableEnumeratorObject;
702 */
703JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_getTableObjects(JNIEnv *env,
704 jobject jRamCloud,
705 jlong jTableId,
706 jlong jTabletNextHash){
707
708 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
709
Yoshi Muroie7693b12014-02-19 19:41:17 -0800710 const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
711 check_null(jc_RcObject, "FindClass failed");
712 const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
713 "<init>",
714 "([B[BJ)V");
715 check_null(jm_init, "GetMethodID failed");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800716
Yoshi Muroie7693b12014-02-19 19:41:17 -0800717 const static jclass jc_RcTableObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumeratorObject"));
718 check_null(jc_RcTableObject, "FindClass failed");
719 const static jmethodID jm_TableEnumeratorObject_init = env->GetMethodID(jc_RcTableObject,
720 "<init>",
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800721 "([L" PACKAGE_PATH "JRamCloud$Object;J)V");
Yoshi Muroie7693b12014-02-19 19:41:17 -0800722 check_null(jm_TableEnumeratorObject_init, "GetMethodID failed");
723
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800724
725 Buffer state;
726 Buffer objects;
727 bool done = false;
728
Yoshi Muroie7693b12014-02-19 19:41:17 -0800729 while (true) {
Yuta HIGUCHIa7ec0732014-03-10 16:01:06 -0700730 jTabletNextHash = ramcloud->enumerateTable(jTableId, false, jTabletNextHash, state, objects);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800731 if (objects.getTotalLength() > 0) {
732 break;
733 }
734 if (objects.getTotalLength() == 0 && jTabletNextHash == 0) {
735 done = true;
736 break;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800737 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800738 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800739
Yoshi Muroie7693b12014-02-19 19:41:17 -0800740 if (done) {
741 return env->NewObject(jc_RcTableObject, jm_TableEnumeratorObject_init, env->NewObjectArray(0, jc_RcObject , NULL), 0);
742 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800743
744 int numOfObjects = 0;
745 uint32_t nextOffset = 0;
746 for (numOfObjects = 0; nextOffset < objects.getTotalLength() ; numOfObjects++) {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800747 uint32_t objectSize = *objects.getOffset<uint32_t>(nextOffset);
748 nextOffset += downCast<uint32_t>(sizeof(uint32_t));
749 nextOffset += objectSize;
750 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800751
752 jobjectArray outJNIArray = env->NewObjectArray(numOfObjects, jc_RcObject , NULL);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800753 check_null(outJNIArray, "NewObjectArray failed");
754
755 nextOffset = 0;
756 for (int i = 0; nextOffset < objects.getTotalLength() ;i++) {
757 uint32_t objectSize = *objects.getOffset<uint32_t>(nextOffset);
758 nextOffset += downCast<uint32_t>(sizeof(uint32_t));
759
760 const void* blob = objects.getRange(nextOffset, objectSize);
761 nextOffset += objectSize;
762
763 Object object(blob, objectSize);
764
765 jbyteArray jKey = env->NewByteArray(object.getKeyLength());
766 jbyteArray jValue = env->NewByteArray(object.getDataLength());
767
768 JByteArrayGetter key(env, jKey);
769 JByteArrayGetter value(env, jValue);
770
771 memcpy(key.pointer, object.getKey(), object.getKeyLength());
772 memcpy(value.pointer, object.getData(), object.getDataLength());
773
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800774 uint64_t version = object.getVersion();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800775
776 jobject obj = env->NewObject(jc_RcObject, jm_init, jKey, jValue, static_cast<jlong>(version));
777 check_null(obj, "NewObject failed");
778
779 env->SetObjectArrayElement(outJNIArray, i, obj);
780 }
781
782 return env->NewObject(jc_RcTableObject, jm_TableEnumeratorObject_init, outJNIArray, jTabletNextHash);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800783}
784
785/*
786 * Class: edu_stanford_ramcloud_JRamCloud
yoshi28bac132014-01-22 11:00:17 -0800787 * Method: multiWrite
788 * Signature: ([Ledu/stanford/ramcloud/JRamCloud/MultiWriteObject;)[Ledu/stanford/ramcloud/JRamCloud/MultiWriteRspObject;
789 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800790JNIEXPORT jobjectArray JNICALL Java_edu_stanford_ramcloud_JRamCloud_multiWrite(JNIEnv *env,
Yoshi Muroie7693b12014-02-19 19:41:17 -0800791 jobject jRamCloud,
792 jlongArray jTableId,
793 jobjectArray jKeyData,
794 jshortArray jKeyLength,
795 jobjectArray jValueData,
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800796 jintArray jValueLength,
Yoshi Muroie7693b12014-02-19 19:41:17 -0800797 jint jrequestNum,
798 jobjectArray jRules ) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800799
Yoshi Muroie7693b12014-02-19 19:41:17 -0800800 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
801 Tub<MultiWriteObject> objects[jrequestNum];
802 MultiWriteObject *requests[jrequestNum];
803 RejectRules rules[jrequestNum];
804 jbyteArray jKey[jrequestNum];
805 jbyteArray jValue[jrequestNum];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800806
Yoshi Muroie7693b12014-02-19 19:41:17 -0800807 jlong tableId;
808 jshort keyLength;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800809 jint valueLength;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800810 jbyte* keyData[jrequestNum];
811 jbyte* valueData[jrequestNum];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800812
yoshi28bac132014-01-22 11:00:17 -0800813 const static jclass jc_RejectRules = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$RejectRules"));
yoshi28bac132014-01-22 11:00:17 -0800814
yoshi28bac132014-01-22 11:00:17 -0800815 const static jfieldID jf_givenVersion = env->GetFieldID(jc_RejectRules, "givenVersion", "J");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800816 check_null(jf_givenVersion, "givenVersion field ID is null");
817
818 const static jfieldID jf_flags = env->GetFieldID(jc_RejectRules, "flags", "I");
819 check_null(jf_flags, "flags field ID is null");
yoshi28bac132014-01-22 11:00:17 -0800820
Yoshi Muroie7693b12014-02-19 19:41:17 -0800821 for (int i = 0; i < jrequestNum; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800822 env->GetLongArrayRegion(jTableId, i, 1, &tableId);
yoshi28bac132014-01-22 11:00:17 -0800823
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800824 env->GetShortArrayRegion(jKeyLength, i, 1, &keyLength);
825 jKey[i] = (jbyteArray)env->GetObjectArrayElement(jKeyData, i);
826 keyData[i] = (jbyte *) malloc(keyLength);
827 env->GetByteArrayRegion(jKey[i], 0, keyLength, keyData[i]);
828
829 env->GetIntArrayRegion(jValueLength, i, 1, &valueLength);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800830 jValue[i] = (jbyteArray)env->GetObjectArrayElement(jValueData, i);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800831 valueData[i] = (jbyte *) malloc(valueLength);
832 env->GetByteArrayRegion(jValue[i], 0, valueLength, valueData[i]);
833
834 jobject jRejectRules = (jbyteArray)env->GetObjectArrayElement(jRules, i);
yoshi28bac132014-01-22 11:00:17 -0800835 rules[i] = {};
836
837 if (jRejectRules != NULL) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800838 const jint flags = env->GetIntField(jRejectRules, jf_flags);
yoshi28bac132014-01-22 11:00:17 -0800839
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800840 rules[i].doesntExist = (flags & DoesntExist) != 0;
yoshi28bac132014-01-22 11:00:17 -0800841
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800842 rules[i].exists = (flags & Exists) != 0;
yoshi28bac132014-01-22 11:00:17 -0800843
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800844 rules[i].versionLeGiven = (flags & VersionLeGiven) != 0;
yoshi28bac132014-01-22 11:00:17 -0800845
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800846 rules[i].versionNeGiven = (flags & VersionNeGiven) != 0;
yoshi28bac132014-01-22 11:00:17 -0800847
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800848 if (rules[i].versionLeGiven || rules[i].versionNeGiven) {
849 rules[i].givenVersion = env->GetLongField(jRejectRules, jf_givenVersion);
850 }
yoshi28bac132014-01-22 11:00:17 -0800851 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800852 objects[i].construct(tableId, keyData[i], keyLength, valueData[i], valueLength, &rules[i]);
yoshi28bac132014-01-22 11:00:17 -0800853 requests[i] = objects[i].get();
854 }
855 try {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800856 ramcloud->multiWrite(requests, jrequestNum);
yoshi28bac132014-01-22 11:00:17 -0800857 } EXCEPTION_CATCHER(NULL);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800858
yoshi28bac132014-01-22 11:00:17 -0800859 const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$MultiWriteRspObject"));
860 check_null(jc_RcObject, "FindClass failed");
861 const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
862 "<init>",
Yoshi Muroie7693b12014-02-19 19:41:17 -0800863 "(IJ)V");
yoshi28bac132014-01-22 11:00:17 -0800864
Yoshi Muroie7693b12014-02-19 19:41:17 -0800865 jobjectArray outJNIArray = env->NewObjectArray(jrequestNum, jc_RcObject , NULL);
yoshi28bac132014-01-22 11:00:17 -0800866 check_null(outJNIArray, "NewObjectArray failed");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800867
Yoshi Muroie7693b12014-02-19 19:41:17 -0800868 for (int i = 0 ; i < jrequestNum ; i++) {
869 jobject obj = env->NewObject(jc_RcObject, jm_init, objects[i]->status, objects[i]->version);
yoshi28bac132014-01-22 11:00:17 -0800870 check_null(obj, "NewObject failed");
871 env->SetObjectArrayElement(outJNIArray, i, obj);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800872 free(keyData[i]);
873 free(valueData[i]);
yoshi28bac132014-01-22 11:00:17 -0800874 objects[i].destroy();
875 }
876 return outJNIArray;
877}
Yuta HIGUCHId47eac32014-04-07 13:44:47 -0700878
879/*
880 * Class: edu_stanford_ramcloud_JRamCloud
881 * Method: increment
882 * Signature: (J[BJ)J
883 */
884JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_increment (JNIEnv* env, jobject jRamCloud, jlong jTableId, jbyteArray jKey, jlong incrementValue) {
885 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
886 JByteArrayReference key(env, jKey);
887 uint64_t version = VERSION_NONEXISTENT;
888 try {
889 return ramcloud->increment(jTableId, key.pointer, key.length, incrementValue, NULL, &version);
890 } EXCEPTION_CATCHER(VERSION_NONEXISTENT);
891}