blob: 4b2ecd42c4a98b5fe5958c7894540510953c76d6 [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{
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800609 return Java_edu_stanford_ramcloud_JRamCloud_writeRule(env, jRamCloud, jTableId, jKey, jValue, jRejectRules);
yoshi28bac132014-01-22 11:00:17 -0800610}
611
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800612/*
613 * Class: edu_stanford_ramcloud_JRamCloud
614 * Method: writeRule
615 * Signature: (J[B[BLedu/stanford/ramcloud/JRamCloud/RejectRules;)J
616 */
yoshi28bac132014-01-22 11:00:17 -0800617JNIEXPORT jlong
618JNICALL Java_edu_stanford_ramcloud_JRamCloud_writeRule(JNIEnv *env,
619 jobject jRamCloud,
620 jlong jTableId,
621 jbyteArray jKey,
622 jbyteArray jValue,
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800623 jobject jRejectRules)
624{
yoshi28bac132014-01-22 11:00:17 -0800625 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
626 JByteArrayReference key(env, jKey);
627 JByteArrayGetter value(env, jValue);
yoshi28bac132014-01-22 11:00:17 -0800628 RejectRules rules = {};
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800629 setRejectRules(env, jRejectRules, rules);
630 uint64_t version;
yoshi28bac132014-01-22 11:00:17 -0800631 try {
632 ramcloud->write(jTableId,
633 key.pointer, key.length,
634 value.pointer, value.length,
635 &rules,
636 &version);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800637 } EXCEPTION_CATCHER(-1);
yoshi28bac132014-01-22 11:00:17 -0800638 return static_cast<jlong> (version);
639}
640
641/*
642 * Class: edu_stanford_ramcloud_JRamCloud_TableEnumerator
643 * Method: init
644 * Signature: (J)V
645 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800646JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_init(JNIEnv *env,
647 jobject jTableEnumerator,
yoshi28bac132014-01-22 11:00:17 -0800648 jlong jTableId)
649{
650 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumerator"));
651 const static jfieldID fieldId = env->GetFieldID(cls, "ramCloudObjectPointer", "J");
652 RamCloud* ramcloud = reinterpret_cast<RamCloud*>(env->GetLongField(jTableEnumerator, fieldId));
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800653
Yuta HIGUCHIa7ec0732014-03-10 16:01:06 -0700654 return reinterpret_cast<jlong>(new TableEnumerator(*ramcloud, jTableId, false));
yoshi28bac132014-01-22 11:00:17 -0800655}
656
657/*
658 * Class: edu_stanford_ramcloud_JRamCloud_TableEnumerator
659 * Method: hasNext
660 * Signature: ()Z
661 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800662JNIEXPORT jboolean JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_hasNext( JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800663 jobject jTableEnumerator)
664{
665 TableEnumerator* tableEnum = getTableEnumerator(env, jTableEnumerator);
666 return static_cast<jboolean>(tableEnum->hasNext());
667}
668
669/*
670 * Class: edu_stanford_ramcloud_JRamCloud_TableEnumerator
671 * Method: next
672 * Signature: ()Ledu/stanford/ramcloud/JRamCloud/Object;
673 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800674JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_next( JNIEnv *env,
yoshi28bac132014-01-22 11:00:17 -0800675 jobject jTableEnumerator)
676{
677 TableEnumerator* tableEnum = getTableEnumerator(env, jTableEnumerator);
678
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800679 if (tableEnum->hasNext()) {
yoshi28bac132014-01-22 11:00:17 -0800680 uint32_t size = 0;
681 const void* buffer = 0;
682 uint64_t version = 0;
683
684 tableEnum->next(&size, &buffer);
685 Object object(buffer, size);
686
687 jbyteArray jKey = env->NewByteArray(object.getKeyLength());
688 jbyteArray jValue = env->NewByteArray(object.getDataLength());
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800689
yoshi28bac132014-01-22 11:00:17 -0800690 JByteArrayGetter key(env, jKey);
691 JByteArrayGetter value(env, jValue);
692
693 memcpy(key.pointer, object.getKey(), object.getKeyLength());
694 memcpy(value.pointer, object.getData(), object.getDataLength());
695
696 version = object.getVersion();
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800697
yoshi28bac132014-01-22 11:00:17 -0800698 const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
699 check_null(cls, "FindClass failed");
700 const static jmethodID methodId = env->GetMethodID(cls,
701 "<init>",
Yoshi Muroie7693b12014-02-19 19:41:17 -0800702 "([B[BJ)V");
yoshi28bac132014-01-22 11:00:17 -0800703 check_null(methodId, "GetMethodID failed");
704 return env->NewObject(cls,
705 methodId,
yoshi28bac132014-01-22 11:00:17 -0800706 jKey,
707 jValue,
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800708 static_cast<jlong>(version));
709 } else {
yoshi28bac132014-01-22 11:00:17 -0800710 return NULL;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800711 }
yoshi28bac132014-01-22 11:00:17 -0800712}
713
714/*
715 * Class: edu_stanford_ramcloud_JRamCloud
Yoshi Muroie7693b12014-02-19 19:41:17 -0800716 * Method: getTableObjects
717 * Signature: (JJ)Ledu/stanford/ramcloud/JRamCloud/TableEnumeratorObject;
718 */
719JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_getTableObjects(JNIEnv *env,
720 jobject jRamCloud,
721 jlong jTableId,
722 jlong jTabletNextHash){
723
724 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
725
Yoshi Muroie7693b12014-02-19 19:41:17 -0800726 const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
727 check_null(jc_RcObject, "FindClass failed");
728 const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
729 "<init>",
730 "([B[BJ)V");
731 check_null(jm_init, "GetMethodID failed");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800732
Yoshi Muroie7693b12014-02-19 19:41:17 -0800733 const static jclass jc_RcTableObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumeratorObject"));
734 check_null(jc_RcTableObject, "FindClass failed");
735 const static jmethodID jm_TableEnumeratorObject_init = env->GetMethodID(jc_RcTableObject,
736 "<init>",
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800737 "([L" PACKAGE_PATH "JRamCloud$Object;J)V");
Yoshi Muroie7693b12014-02-19 19:41:17 -0800738 check_null(jm_TableEnumeratorObject_init, "GetMethodID failed");
739
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800740
741 Buffer state;
742 Buffer objects;
743 bool done = false;
744
Yoshi Muroie7693b12014-02-19 19:41:17 -0800745 while (true) {
Yuta HIGUCHIa7ec0732014-03-10 16:01:06 -0700746 jTabletNextHash = ramcloud->enumerateTable(jTableId, false, jTabletNextHash, state, objects);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800747 if (objects.getTotalLength() > 0) {
748 break;
749 }
750 if (objects.getTotalLength() == 0 && jTabletNextHash == 0) {
751 done = true;
752 break;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800753 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800754 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800755
Yoshi Muroie7693b12014-02-19 19:41:17 -0800756 if (done) {
757 return env->NewObject(jc_RcTableObject, jm_TableEnumeratorObject_init, env->NewObjectArray(0, jc_RcObject , NULL), 0);
758 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800759
760 int numOfObjects = 0;
761 uint32_t nextOffset = 0;
762 for (numOfObjects = 0; nextOffset < objects.getTotalLength() ; numOfObjects++) {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800763 uint32_t objectSize = *objects.getOffset<uint32_t>(nextOffset);
764 nextOffset += downCast<uint32_t>(sizeof(uint32_t));
765 nextOffset += objectSize;
766 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800767
768 jobjectArray outJNIArray = env->NewObjectArray(numOfObjects, jc_RcObject , NULL);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800769 check_null(outJNIArray, "NewObjectArray failed");
770
771 nextOffset = 0;
772 for (int i = 0; nextOffset < objects.getTotalLength() ;i++) {
773 uint32_t objectSize = *objects.getOffset<uint32_t>(nextOffset);
774 nextOffset += downCast<uint32_t>(sizeof(uint32_t));
775
776 const void* blob = objects.getRange(nextOffset, objectSize);
777 nextOffset += objectSize;
778
779 Object object(blob, objectSize);
780
781 jbyteArray jKey = env->NewByteArray(object.getKeyLength());
782 jbyteArray jValue = env->NewByteArray(object.getDataLength());
783
784 JByteArrayGetter key(env, jKey);
785 JByteArrayGetter value(env, jValue);
786
787 memcpy(key.pointer, object.getKey(), object.getKeyLength());
788 memcpy(value.pointer, object.getData(), object.getDataLength());
789
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800790 uint64_t version = object.getVersion();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800791
792 jobject obj = env->NewObject(jc_RcObject, jm_init, jKey, jValue, static_cast<jlong>(version));
793 check_null(obj, "NewObject failed");
794
795 env->SetObjectArrayElement(outJNIArray, i, obj);
796 }
797
798 return env->NewObject(jc_RcTableObject, jm_TableEnumeratorObject_init, outJNIArray, jTabletNextHash);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800799}
800
801/*
802 * Class: edu_stanford_ramcloud_JRamCloud
yoshi28bac132014-01-22 11:00:17 -0800803 * Method: multiWrite
804 * Signature: ([Ledu/stanford/ramcloud/JRamCloud/MultiWriteObject;)[Ledu/stanford/ramcloud/JRamCloud/MultiWriteRspObject;
805 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800806JNIEXPORT jobjectArray JNICALL Java_edu_stanford_ramcloud_JRamCloud_multiWrite(JNIEnv *env,
Yoshi Muroie7693b12014-02-19 19:41:17 -0800807 jobject jRamCloud,
808 jlongArray jTableId,
809 jobjectArray jKeyData,
810 jshortArray jKeyLength,
811 jobjectArray jValueData,
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800812 jintArray jValueLength,
Yoshi Muroie7693b12014-02-19 19:41:17 -0800813 jint jrequestNum,
814 jobjectArray jRules ) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800815
Yoshi Muroie7693b12014-02-19 19:41:17 -0800816 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
817 Tub<MultiWriteObject> objects[jrequestNum];
818 MultiWriteObject *requests[jrequestNum];
819 RejectRules rules[jrequestNum];
820 jbyteArray jKey[jrequestNum];
821 jbyteArray jValue[jrequestNum];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800822
Yoshi Muroie7693b12014-02-19 19:41:17 -0800823 jlong tableId;
824 jshort keyLength;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800825 jint valueLength;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800826 jbyte* keyData[jrequestNum];
827 jbyte* valueData[jrequestNum];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800828
yoshi28bac132014-01-22 11:00:17 -0800829 const static jclass jc_RejectRules = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$RejectRules"));
yoshi28bac132014-01-22 11:00:17 -0800830
yoshi28bac132014-01-22 11:00:17 -0800831 const static jfieldID jf_givenVersion = env->GetFieldID(jc_RejectRules, "givenVersion", "J");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800832 check_null(jf_givenVersion, "givenVersion field ID is null");
833
834 const static jfieldID jf_flags = env->GetFieldID(jc_RejectRules, "flags", "I");
835 check_null(jf_flags, "flags field ID is null");
yoshi28bac132014-01-22 11:00:17 -0800836
Yoshi Muroie7693b12014-02-19 19:41:17 -0800837 for (int i = 0; i < jrequestNum; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800838 env->GetLongArrayRegion(jTableId, i, 1, &tableId);
yoshi28bac132014-01-22 11:00:17 -0800839
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800840 env->GetShortArrayRegion(jKeyLength, i, 1, &keyLength);
841 jKey[i] = (jbyteArray)env->GetObjectArrayElement(jKeyData, i);
842 keyData[i] = (jbyte *) malloc(keyLength);
843 env->GetByteArrayRegion(jKey[i], 0, keyLength, keyData[i]);
844
845 env->GetIntArrayRegion(jValueLength, i, 1, &valueLength);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800846 jValue[i] = (jbyteArray)env->GetObjectArrayElement(jValueData, i);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800847 valueData[i] = (jbyte *) malloc(valueLength);
848 env->GetByteArrayRegion(jValue[i], 0, valueLength, valueData[i]);
849
850 jobject jRejectRules = (jbyteArray)env->GetObjectArrayElement(jRules, i);
yoshi28bac132014-01-22 11:00:17 -0800851 rules[i] = {};
852
853 if (jRejectRules != NULL) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800854 const jint flags = env->GetIntField(jRejectRules, jf_flags);
yoshi28bac132014-01-22 11:00:17 -0800855
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800856 rules[i].doesntExist = (flags & DoesntExist) != 0;
yoshi28bac132014-01-22 11:00:17 -0800857
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800858 rules[i].exists = (flags & Exists) != 0;
yoshi28bac132014-01-22 11:00:17 -0800859
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800860 rules[i].versionLeGiven = (flags & VersionLeGiven) != 0;
yoshi28bac132014-01-22 11:00:17 -0800861
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800862 rules[i].versionNeGiven = (flags & VersionNeGiven) != 0;
yoshi28bac132014-01-22 11:00:17 -0800863
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800864 if (rules[i].versionLeGiven || rules[i].versionNeGiven) {
865 rules[i].givenVersion = env->GetLongField(jRejectRules, jf_givenVersion);
866 }
yoshi28bac132014-01-22 11:00:17 -0800867 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800868 objects[i].construct(tableId, keyData[i], keyLength, valueData[i], valueLength, &rules[i]);
yoshi28bac132014-01-22 11:00:17 -0800869 requests[i] = objects[i].get();
870 }
871 try {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800872 ramcloud->multiWrite(requests, jrequestNum);
yoshi28bac132014-01-22 11:00:17 -0800873 } EXCEPTION_CATCHER(NULL);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800874
yoshi28bac132014-01-22 11:00:17 -0800875 const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$MultiWriteRspObject"));
876 check_null(jc_RcObject, "FindClass failed");
877 const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
878 "<init>",
Yoshi Muroie7693b12014-02-19 19:41:17 -0800879 "(IJ)V");
yoshi28bac132014-01-22 11:00:17 -0800880
Yoshi Muroie7693b12014-02-19 19:41:17 -0800881 jobjectArray outJNIArray = env->NewObjectArray(jrequestNum, jc_RcObject , NULL);
yoshi28bac132014-01-22 11:00:17 -0800882 check_null(outJNIArray, "NewObjectArray failed");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800883
Yoshi Muroie7693b12014-02-19 19:41:17 -0800884 for (int i = 0 ; i < jrequestNum ; i++) {
885 jobject obj = env->NewObject(jc_RcObject, jm_init, objects[i]->status, objects[i]->version);
yoshi28bac132014-01-22 11:00:17 -0800886 check_null(obj, "NewObject failed");
887 env->SetObjectArrayElement(outJNIArray, i, obj);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800888 free(keyData[i]);
889 free(valueData[i]);
yoshi28bac132014-01-22 11:00:17 -0800890 objects[i].destroy();
891 }
892 return outJNIArray;
893}
Yuta HIGUCHId47eac32014-04-07 13:44:47 -0700894
895/*
896 * Class: edu_stanford_ramcloud_JRamCloud
897 * Method: increment
898 * Signature: (J[BJ)J
899 */
900JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_increment (JNIEnv* env, jobject jRamCloud, jlong jTableId, jbyteArray jKey, jlong incrementValue) {
901 RamCloud* ramcloud = getRamCloud(env, jRamCloud);
902 JByteArrayReference key(env, jKey);
903 uint64_t version = VERSION_NONEXISTENT;
904 try {
905 return ramcloud->increment(jTableId, key.pointer, key.length, incrementValue, NULL, &version);
906 } EXCEPTION_CATCHER(VERSION_NONEXISTENT);
907}