blob: 6d5714c54253fff45f6191840b4b5d1bbf267b71 [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
16package edu.stanford.ramcloud;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080017import java.nio.charset.StandardCharsets;
Yoshi Muroi2c170602014-02-15 08:31:28 -080018import java.util.Arrays;
Yoshi Muroie7693b12014-02-19 19:41:17 -080019import java.util.LinkedList;
yoshi28bac132014-01-22 11:00:17 -080020
21/*
22 * This class provides Java bindings for RAMCloud. Right now it is a rather
23 * simple subset of what RamCloud.h defines.
24 *
25 * Running ``javah'' on this file will generate a C header file with the
26 * appropriate JNI function definitions. The glue interfacing to the C++
27 * RAMCloud library can be found in JRamCloud.cc.
28 *
29 * For JNI information, the IBM tutorials and Android developer docs are much
30 * better than Sun's at giving an overall intro:
31 * http://www.ibm.com/developerworks/java/tutorials/j-jni/section4.html
32 * http://developer.android.com/training/articles/perf-jni.html
33 */
34public class JRamCloud {
35 static {
36 System.loadLibrary("edu_stanford_ramcloud_JRamCloud");
37 }
38
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080039 public static final long VERSION_NONEXISTENT = 0L;
40
yoshi28bac132014-01-22 11:00:17 -080041 /// Pointer to the underlying C++ RAMCloud object associated with this
42 /// object.
43 private long ramcloudObjectPointer = 0;
44
45 /**
46 * See src/RejectRules.h.
47 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080048 public static class RejectRules {
49 // these needs to be in sync with JNI code;
50 public static final int DoesntExist = 1;
51 public static final int Exists = 1 << 1;
52 public static final int VersionLeGiven = 1 << 2;
53 public static final int VersionNeGiven = 1 << 3;
54
55 protected long givenVersion;
56 protected int flags;
yoshi28bac132014-01-22 11:00:17 -080057
58 public RejectRules() {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080059 clear();
yoshi28bac132014-01-22 11:00:17 -080060 }
61
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080062 public void clear() {
63 this.givenVersion = VERSION_NONEXISTENT;
64 this.flags = 0x0;
65 }
66
67 public RejectRules set(int flags, long version) {
68 this.flags = flags;
69 this.givenVersion = version;
70 return this;
71 }
72
73 public RejectRules set(int flags) {
74 return set(flags,VERSION_NONEXISTENT);
75 }
76
77 public RejectRules rejectIfLeVersion(long version) {
yoshi28bac132014-01-22 11:00:17 -080078 setVersion(version);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080079 this.flags |= VersionLeGiven;
80 return this;
yoshi28bac132014-01-22 11:00:17 -080081 }
82
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080083 public RejectRules rejectIfExists() {
84 this.flags |= Exists;
85 return this;
yoshi28bac132014-01-22 11:00:17 -080086 }
87
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080088 public RejectRules rejectIfDoesntExists() {
89 this.flags |= DoesntExist;
90 return this;
yoshi28bac132014-01-22 11:00:17 -080091 }
92
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080093 public RejectRules rejectIfNeVersion(long version) {
yoshi28bac132014-01-22 11:00:17 -080094 setVersion(version);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080095 this.flags |= VersionNeGiven;
96 return this;
yoshi28bac132014-01-22 11:00:17 -080097 }
98
99 private void setVersion(long version) {
100 this.givenVersion = version;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800101 }
yoshi28bac132014-01-22 11:00:17 -0800102 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800103
Yoshi Muroie7693b12014-02-19 19:41:17 -0800104 public static class MultiReadObject {
105 public long[] tableId;
106 public byte[] key[];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800107 public short[] keyLength;
108
Yoshi Muroie7693b12014-02-19 19:41:17 -0800109 public MultiReadObject(int size){
110 this.tableId = new long[size];
111 this.key = new byte[size][];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800112 this.keyLength = new short[size];
yoshi28bac132014-01-22 11:00:17 -0800113 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800114
Ray Milkey269ffb92014-04-03 14:43:30 -0700115 public void setObject(int num, long tableId, byte key[]){
Yoshi Muroie7693b12014-02-19 19:41:17 -0800116 this.tableId[num] = tableId;
117 this.key[num] = key;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800118 this.keyLength[num] = (short) this.key[num].length;
Ray Milkey269ffb92014-04-03 14:43:30 -0700119 }
yoshi28bac132014-01-22 11:00:17 -0800120 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800121
yoshi28bac132014-01-22 11:00:17 -0800122 public static class MultiWriteObject {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800123 public long[] tableId;
124 public byte[] key[];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800125 public short[] keyLength;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800126 public byte[] value[];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800127 public int[] valueLength;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800128 public RejectRules[] rules;
yoshi28bac132014-01-22 11:00:17 -0800129
Yoshi Muroie7693b12014-02-19 19:41:17 -0800130 public MultiWriteObject(int size) {
131 this.tableId = new long[size];
132 this.key = new byte[size][];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800133 this.keyLength = new short[size];
Yoshi Muroie7693b12014-02-19 19:41:17 -0800134 this.value = new byte[size][];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800135 this.valueLength = new int[size];
Yoshi Muroie7693b12014-02-19 19:41:17 -0800136 this.rules = new RejectRules[size];
yoshi28bac132014-01-22 11:00:17 -0800137 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800138
Ray Milkey269ffb92014-04-03 14:43:30 -0700139 public void setObject(int num, long tableId, byte key[], byte value[], RejectRules rules){
140 this.tableId[num] = tableId;
141 this.key[num] = key;
142 this.keyLength[num] = (short) key.length;
143 this.value[num] = value;
144 this.valueLength[num] = value.length;
145 this.rules[num] = rules;
146 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800147
yoshi28bac132014-01-22 11:00:17 -0800148 }
149
Yoshi Muroie7693b12014-02-19 19:41:17 -0800150 public static class MultiWriteRspObject {
yoshi28bac132014-01-22 11:00:17 -0800151 private int status;
152 private long version;
153
154 public MultiWriteRspObject(int status, long version) {
155 this.status = status;
156 this.version = version;
157 }
158 public int getStatus() {
159 return status;
160 }
161
162 public long getVersion() {
163 return version;
164 }
165 }
166
167 /**
168 * This class is returned by Read operations. It encapsulates the entire
169 * object, including the key, value, and version.
170 *
171 * It mostly exists because Java doesn't support primitive out parameters
172 * or multiple return values, and we don't know the object's size ahead of
173 * time, so passing in a fixed-length array would be problematic.
174 */
Yoshi Muroie7693b12014-02-19 19:41:17 -0800175 public static class Object {
yoshi28bac132014-01-22 11:00:17 -0800176 Object(byte[] _key, byte[] _value, long _version)
177 {
178 key = _key;
179 value = _value;
180 version = _version;
181 }
182
183 public String
184 getKey()
185 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800186 return new String(key,StandardCharsets.UTF_8);
yoshi28bac132014-01-22 11:00:17 -0800187 }
188
189 public String
190 getValue()
191 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800192 return new String(value,StandardCharsets.UTF_8);
yoshi28bac132014-01-22 11:00:17 -0800193 }
194
195 final public byte[] key;
196 final public byte[] value;
197 final public long version;
198 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800199
Yoshi Muroie7693b12014-02-19 19:41:17 -0800200 public static class TableEnumeratorObject {
Ray Milkey269ffb92014-04-03 14:43:30 -0700201 TableEnumeratorObject(Object[] _object, long _nextHash)
202 {
203 object = _object;
204 nextHash = _nextHash;
205 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800206
Ray Milkey269ffb92014-04-03 14:43:30 -0700207 final public Object[] object;
208 final public long nextHash;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800209 }
yoshi28bac132014-01-22 11:00:17 -0800210
211 public class TableEnumerator {
212 private long tableEnumeratorObjectPointer = 0;
213 private long ramCloudObjectPointer = 0;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800214
yoshi28bac132014-01-22 11:00:17 -0800215 public TableEnumerator(long tableId)
216 {
217 ramCloudObjectPointer = ramcloudObjectPointer;
218 tableEnumeratorObjectPointer = init(tableId);
219 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800220
yoshi28bac132014-01-22 11:00:17 -0800221 private native long init(long tableId);
222 public native boolean hasNext();
223 public native Object next();
224 }
225
Yoshi Muroie7693b12014-02-19 19:41:17 -0800226 public class TableEnumerator2 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800227
Ray Milkey269ffb92014-04-03 14:43:30 -0700228 protected long tableId;
229 protected LinkedList<JRamCloud.Object> rcobjs = null;
230 protected long nextHash = 0;
231 protected boolean done = false;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800232
Yoshi Muroie7693b12014-02-19 19:41:17 -0800233 public TableEnumerator2(long tableId)
234 {
Ray Milkey269ffb92014-04-03 14:43:30 -0700235 this.tableId = tableId;
236 rcobjs = new LinkedList<>();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800237 }
238 public boolean hasNext() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700239 if (rcobjs.isEmpty())
240 {
241 if (done) {
242 return false;
243 }
244 JRamCloud.TableEnumeratorObject o = getTableObjects(this.tableId, this.nextHash);
245 if (o.nextHash == 0L) {
246 done = true;
247 }
248 this.nextHash = o.nextHash;
249 rcobjs.addAll(Arrays.asList(o.object));
250 if (rcobjs.isEmpty()) {
251 return false;
252 }
253 }
254 return true;
255 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800256
Ray Milkey269ffb92014-04-03 14:43:30 -0700257 public Object next()
258 {
259 return rcobjs.pop();
260 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800261 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800262
yoshi28bac132014-01-22 11:00:17 -0800263 /**
264 * Connect to the RAMCloud cluster specified by the given coordinator's
265 * service locator string. This causes the JNI code to instantiate the
266 * underlying RamCloud C++ object.
267 */
268 public
269 JRamCloud(String coordinatorLocator)
270 {
271 ramcloudObjectPointer = connect(coordinatorLocator);
272 }
273
274 /**
275 * Disconnect from the RAMCloud cluster. This causes the JNI code to
276 * destroy the underlying RamCloud C++ object.
277 */
278 public void
279 disconnect()
280 {
281 if (ramcloudObjectPointer != 0) {
282 disconnect(ramcloudObjectPointer);
283 ramcloudObjectPointer = 0;
284 }
285 }
286
287 /**
288 * This method is called by the garbage collector before destroying the
289 * object. The user really should have called disconnect, but in case
290 * they did not, be sure to clean up after them.
291 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800292 @Override
293 protected void
yoshi28bac132014-01-22 11:00:17 -0800294 finalize()
295 {
296 System.err.println("warning: JRamCloud::disconnect() was not called " +
297 "prior to the finalizer. You should disconnect " +
298 "your JRamCloud object when you're done with it.");
299 disconnect();
300 }
301
302 /**
303 * Convenience read() wrapper that take a String key argument.
304 */
305 public Object
306 read(long tableId, String key)
307 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800308 return read(tableId, key.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800309 }
310
311 /**
312 * Convenience read() wrapper that take a String key argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800313 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800314 */
315 public Object
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800316 read(long tableId, String key, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800317 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800318 return read(tableId, key.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800319 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800320
yoshi28bac132014-01-22 11:00:17 -0800321 /**
322 * Convenience remove() wrapper that take a String key argument.
323 */
324 public long
325 remove(long tableId, String key)
326 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800327 return remove(tableId, key.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800328 }
329
330 /**
331 * Convenience remove() wrapper that take a String key argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800332 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800333 */
334 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800335 remove(long tableId, String key, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800336 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800337 return remove(tableId, key.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800338 }
339
340 /**
341 * Convenience write() wrapper that take String key and value arguments.
342 */
343 public long
344 write(long tableId, String key, String value)
345 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800346 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800347 }
348
349 /**
350 * Convenience write() wrapper that take String key and value arguments.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800351 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800352 */
353 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800354 write(long tableId, String key, String value, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800355 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800356 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800357 }
358
359 /**
360 * Convenience write() wrapper that takes a String key and a byte[] value
361 * argument.
362 */
363 public long
364 write(long tableId, String key, byte[] value)
365 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800366 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value);
yoshi28bac132014-01-22 11:00:17 -0800367 }
368
369 /**
370 * Convenience write() wrapper that takes a String key and a byte[] value
371 * argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800372 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800373 */
374 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800375 write(long tableId, String key, byte[] value, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800376 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800377 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value, rules);
yoshi28bac132014-01-22 11:00:17 -0800378 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800379
yoshi28bac132014-01-22 11:00:17 -0800380 private static native long connect(String coordinatorLocator);
381 private static native void disconnect(long ramcloudObjectPointer);
382
383 public native long createTable(String name);
384 public native long createTable(String name, int serverSpan);
385 public native void dropTable(String name);
386 public native long getTableId(String name);
387 public native Object read(long tableId, byte[] key);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800388 public native Object read(long tableId, byte[] key, RejectRules rules) throws RejectRulesException;
Yoshi Muroi2c170602014-02-15 08:31:28 -0800389 public native Object[] multiRead(long[] tableId, byte[] keydata[], short[] keyDataSize, int requestNum);
yoshi28bac132014-01-22 11:00:17 -0800390 public native long remove(long tableId, byte[] key);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800391 public native long remove(long tableId, byte[] key, RejectRules rules) throws RejectRulesException;
yoshi28bac132014-01-22 11:00:17 -0800392 public native long write(long tableId, byte[] key, byte[] value);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800393 public native long write(long tableId, byte[] key, byte[] value, RejectRules rules) throws RejectRulesException;
394 @Deprecated
yoshi28bac132014-01-22 11:00:17 -0800395 public native long writeRule(long tableId, byte[] key, byte[] value, RejectRules rules);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800396 public native MultiWriteRspObject[] multiWrite(long[] tableId, byte[] key[], short[] keyDataSize, byte[] value[], int[] valueDataSize, int requestNum, RejectRules[] rules);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800397 public native TableEnumeratorObject getTableObjects(long tableId, long nextHash);
yoshi28bac132014-01-22 11:00:17 -0800398
399 /*
400 * The following exceptions may be thrown by the JNI functions:
401 */
402
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800403 public static class TableDoesntExistException extends RuntimeException {
yoshi28bac132014-01-22 11:00:17 -0800404 public TableDoesntExistException(String message)
405 {
406 super(message);
407 }
408 }
409
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800410 public static class ObjectDoesntExistException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800411 public ObjectDoesntExistException(String message)
412 {
413 super(message);
414 }
415 }
416
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800417 public static class ObjectExistsException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800418 public ObjectExistsException(String message)
419 {
420 super(message);
421 }
422 }
423
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800424 public static class WrongVersionException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800425 public WrongVersionException(String message)
426 {
427 super(message);
428 }
429 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800430
431 public static class InvalidObjectException extends RuntimeException {
yoshi28bac132014-01-22 11:00:17 -0800432 public InvalidObjectException(String message) {
433 super(message);
434 }
435 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800436
437 public static class RejectRulesException extends Exception {
yoshi28bac132014-01-22 11:00:17 -0800438 public RejectRulesException(String message) {
439 super(message);
440 }
441 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800442
Yoshi Muroie7693b12014-02-19 19:41:17 -0800443 public static void tableEnumeratorTest(JRamCloud ramcloud) {
444 long startTime = 0;
445 for (int x = 0 ; x < 2 ; x ++){
446 for(int N = 1000; N < 10000; N += 1000) {
447 long EnumerateTesttable = ramcloud.createTable("EnumerateTest");
448 for(int i = 0 ; i < N ; ++i) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800449 String key = String.valueOf(i);
450 ramcloud.write(EnumerateTesttable, key.getBytes(StandardCharsets.UTF_8), "Hello, World!".getBytes(StandardCharsets.UTF_8));
Yoshi Muroie7693b12014-02-19 19:41:17 -0800451 }
yoshi28bac132014-01-22 11:00:17 -0800452
Yoshi Muroie7693b12014-02-19 19:41:17 -0800453 long tableIdList[] = new long[N];
454 byte[] keydata[] = new byte[N][];
455 short keydataSize[] = new short[N];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800456 startTime = System.nanoTime();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800457 for (int j = 0 ; j < N ; ++j) {
458 tableIdList[j] = EnumerateTesttable;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800459 String key = String.valueOf(j);
460 keydata[j] = key.getBytes(StandardCharsets.UTF_8);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800461 keydataSize[j] = (short) keydata[j].length;
462 }
463 JRamCloud.Object out[] = ramcloud.multiRead(tableIdList, keydata, keydataSize, N);
464 for (int i = 0; i < N; ++i) {
465 if(out[i].version == 0) {
466 System.out.println("Verify fail " + out[i].getKey() + " V:" + out[i].getValue());
467 }
468 }
469
470 System.out.println("multiRead : " + N + " Time : " + (System.nanoTime()-startTime));
471
472 startTime = System.nanoTime();
473 JRamCloud.TableEnumerator tableEnum = ramcloud.new TableEnumerator(EnumerateTesttable);
474 while (tableEnum.hasNext()) {
475 Object tableEntry = tableEnum.next();
476 if (tableEntry != null) {
477 System.out.println("tableEnumerator object: key = [" + tableEntry.getKey() + "], value = [" + tableEntry.getValue() + "]");
478 }
479 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800480 System.out.println("old TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
Yoshi Muroie7693b12014-02-19 19:41:17 -0800481
482 startTime = System.nanoTime();
483 JRamCloud.TableEnumerator2 tableEnum2 = ramcloud.new TableEnumerator2(EnumerateTesttable);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800484 while (tableEnum2.hasNext()) {
485 Object tableEntry2 = tableEnum2.next();
486 if (tableEntry2 != null) {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800487 System.out.println("tableEnumerator2 object: key = [" + tableEntry2.getKey() + "], value = [" + tableEntry2.getValue() + "]");
488 }
489 }
490 System.out.println("new TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
491 ramcloud.dropTable("EnumerateTest");
492 }
493 }
494 }
yoshi28bac132014-01-22 11:00:17 -0800495 /**
496 * A simple end-to-end test of the java bindings.
497 */
498 public static void
499 main(String argv[])
500 {
501 JRamCloud ramcloud = new JRamCloud(argv[0]);
502 long tableId = ramcloud.createTable("hi");
503 System.out.println("created table, id = " + tableId);
504 long tableId2 = ramcloud.getTableId("hi");
505 System.out.println("getTableId says tableId = " + tableId2);
506
507 System.out.println("wrote obj version = " +
508 ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue"));
509
510 JRamCloud.Object o = ramcloud.read(tableId, "thisIsTheKey");
511 System.out.println("read object: key = [" + o.getKey() + "], value = ["
512 + o.getValue() + "], version = " + o.version);
513
514 ramcloud.remove(tableId, "thisIsTheKey");
515
516 try {
517 ramcloud.read(tableId, "thisIsTheKey");
518 System.out.println("Error: shouldn't have read successfully!");
519 } catch (Exception e) {
520 // OK
521 }
522
523 ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800524
yoshi28bac132014-01-22 11:00:17 -0800525 long before = System.nanoTime();
526 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800527 @SuppressWarnings("unused")
yoshi28bac132014-01-22 11:00:17 -0800528 JRamCloud.Object unused = ramcloud.read(tableId, "thisIsTheKey");
529 }
530 long after = System.nanoTime();
531 System.out.println("Avg read latency: " +
532 ((double)(after - before) / 1000 / 1000) + " usec");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800533
yoshi28bac132014-01-22 11:00:17 -0800534 // multiRead test
535 long tableId4 = ramcloud.createTable("table4");
536 System.out.println("table4 id " + tableId4);
537 ramcloud.write(tableId4, "object1-1", "value:1-1");
538 ramcloud.write(tableId4, "object1-2", "value:1-2");
539 ramcloud.write(tableId4, "object1-3", "value:1-3");
540 long tableId5 = ramcloud.createTable("table5");
541 System.out.println("table5 id " + tableId5);
542 ramcloud.write(tableId5, "object2-1", "value:2-1");
543 long tableId6 = ramcloud.createTable("table6");
544 ramcloud.write(tableId6, "object3-1", "value:3-1");
545 ramcloud.write(tableId6, "object3-2", "value:3-2");
546
Ray Milkey269ffb92014-04-03 14:43:30 -0700547 MultiReadObject mr = new MultiReadObject(2);
548 MultiWriteObject mw = new MultiWriteObject(2);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800549
Ray Milkey269ffb92014-04-03 14:43:30 -0700550 mr.setObject(0, tableId4, "object1-1".getBytes(StandardCharsets.UTF_8));
551 mr.setObject(1, tableId5, "object2-1".getBytes(StandardCharsets.UTF_8));
Yoshi Muroi2c170602014-02-15 08:31:28 -0800552
Yoshi Muroie7693b12014-02-19 19:41:17 -0800553 JRamCloud.Object out[] = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
yoshi28bac132014-01-22 11:00:17 -0800554 for (int i = 0 ; i < 2 ; i++){
555 System.out.println("multi read object: key = [" + out[i].getKey() + "], value = ["
556 + out[i].getValue() + "]");
yoshi28bac132014-01-22 11:00:17 -0800557 }
Yoshi Muroi2c170602014-02-15 08:31:28 -0800558
yoshi28bac132014-01-22 11:00:17 -0800559 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800560 String key1 = "key1" + String.valueOf(i);
561 String key2 = "key2" + String.valueOf(i);
562
563 mw.setObject(0, tableId4, key1.getBytes(StandardCharsets.UTF_8), "v0-value".getBytes(StandardCharsets.UTF_8), null);
564 mw.setObject(1, tableId5, key2.getBytes(StandardCharsets.UTF_8), "v1".getBytes(StandardCharsets.UTF_8), null);
565
Yoshi Muroie7693b12014-02-19 19:41:17 -0800566 MultiWriteRspObject[] rsp = ramcloud.multiWrite(mw.tableId, mw.key, mw.keyLength, mw.value, mw.valueLength, 2, mw.rules);
yoshi28bac132014-01-22 11:00:17 -0800567 if (rsp != null) {
568 for (int j = 0; j < rsp.length; j++) {
569 System.out.println("multi write rsp(" + j + ") status:version " + rsp[j].getStatus() + ":" + rsp[j].getVersion());
570 }
571 }
572 }
573 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800574 String key1 = "key1" + String.valueOf(i);
575 String key2 = "key2" + String.valueOf(i);
Yoshi Muroi2c170602014-02-15 08:31:28 -0800576
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800577 mr.setObject(0, tableId4, key1.getBytes(StandardCharsets.UTF_8));
578 mr.setObject(1, tableId5, key2.getBytes(StandardCharsets.UTF_8));
579
Yoshi Muroie7693b12014-02-19 19:41:17 -0800580 out = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
yoshi28bac132014-01-22 11:00:17 -0800581 for (int j = 0; j < 2; j++) {
582 System.out.println("multi read object: key = [" + out[j].getKey() + "], value = [" + out[j].getValue() + "]");
583 }
584 }
Yoshi Muroi2c170602014-02-15 08:31:28 -0800585
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800586 tableEnumeratorTest(ramcloud);
587
yoshi28bac132014-01-22 11:00:17 -0800588 ramcloud.dropTable("table4");
589 ramcloud.dropTable("table5");
590 ramcloud.dropTable("table6");
591 ramcloud.disconnect();
592 }
593}