blob: 2bfd145e8f89f33051f67f029ae4f6d74c795486 [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
Yuta HIGUCHIceb99bd2014-04-19 11:55:12 -070021import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
yoshi28bac132014-01-22 11:00:17 -080024/*
25 * This class provides Java bindings for RAMCloud. Right now it is a rather
26 * simple subset of what RamCloud.h defines.
27 *
28 * Running ``javah'' on this file will generate a C header file with the
29 * appropriate JNI function definitions. The glue interfacing to the C++
30 * RAMCloud library can be found in JRamCloud.cc.
31 *
32 * For JNI information, the IBM tutorials and Android developer docs are much
33 * better than Sun's at giving an overall intro:
34 * http://www.ibm.com/developerworks/java/tutorials/j-jni/section4.html
35 * http://developer.android.com/training/articles/perf-jni.html
36 */
37public class JRamCloud {
Yuta HIGUCHIceb99bd2014-04-19 11:55:12 -070038 private static final Logger log = LoggerFactory.getLogger(JRamCloud.class);
39
yoshi28bac132014-01-22 11:00:17 -080040 static {
Yuta HIGUCHIceb99bd2014-04-19 11:55:12 -070041 try {
42 System.loadLibrary("edu_stanford_ramcloud_JRamCloud");
43 } catch (UnsatisfiedLinkError e) {
44 System.err.println("Unable to load JNI binding. Please build RAMCloud Java bindings.");
45 log.error("Unable to load JNI binding. Please build RAMCloud Java bindings.", e);
46 System.exit(-1);
47 }
yoshi28bac132014-01-22 11:00:17 -080048 }
49
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080050 public static final long VERSION_NONEXISTENT = 0L;
51
yoshi28bac132014-01-22 11:00:17 -080052 /// Pointer to the underlying C++ RAMCloud object associated with this
53 /// object.
54 private long ramcloudObjectPointer = 0;
55
56 /**
57 * See src/RejectRules.h.
58 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080059 public static class RejectRules {
60 // these needs to be in sync with JNI code;
61 public static final int DoesntExist = 1;
62 public static final int Exists = 1 << 1;
63 public static final int VersionLeGiven = 1 << 2;
64 public static final int VersionNeGiven = 1 << 3;
65
66 protected long givenVersion;
67 protected int flags;
yoshi28bac132014-01-22 11:00:17 -080068
69 public RejectRules() {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080070 clear();
yoshi28bac132014-01-22 11:00:17 -080071 }
72
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080073 public void clear() {
74 this.givenVersion = VERSION_NONEXISTENT;
75 this.flags = 0x0;
76 }
77
78 public RejectRules set(int flags, long version) {
79 this.flags = flags;
80 this.givenVersion = version;
81 return this;
82 }
83
84 public RejectRules set(int flags) {
85 return set(flags,VERSION_NONEXISTENT);
86 }
87
88 public RejectRules rejectIfLeVersion(long version) {
yoshi28bac132014-01-22 11:00:17 -080089 setVersion(version);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080090 this.flags |= VersionLeGiven;
91 return this;
yoshi28bac132014-01-22 11:00:17 -080092 }
93
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080094 public RejectRules rejectIfExists() {
95 this.flags |= Exists;
96 return this;
yoshi28bac132014-01-22 11:00:17 -080097 }
98
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -080099 public RejectRules rejectIfDoesntExists() {
100 this.flags |= DoesntExist;
101 return this;
yoshi28bac132014-01-22 11:00:17 -0800102 }
103
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800104 public RejectRules rejectIfNeVersion(long version) {
yoshi28bac132014-01-22 11:00:17 -0800105 setVersion(version);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800106 this.flags |= VersionNeGiven;
107 return this;
yoshi28bac132014-01-22 11:00:17 -0800108 }
109
110 private void setVersion(long version) {
111 this.givenVersion = version;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800112 }
yoshi28bac132014-01-22 11:00:17 -0800113 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800114
Yoshi Muroie7693b12014-02-19 19:41:17 -0800115 public static class MultiReadObject {
116 public long[] tableId;
117 public byte[] key[];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800118 public short[] keyLength;
119
Yoshi Muroie7693b12014-02-19 19:41:17 -0800120 public MultiReadObject(int size){
121 this.tableId = new long[size];
122 this.key = new byte[size][];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800123 this.keyLength = new short[size];
yoshi28bac132014-01-22 11:00:17 -0800124 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800125
Ray Milkey269ffb92014-04-03 14:43:30 -0700126 public void setObject(int num, long tableId, byte key[]){
Yoshi Muroie7693b12014-02-19 19:41:17 -0800127 this.tableId[num] = tableId;
128 this.key[num] = key;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800129 this.keyLength[num] = (short) this.key[num].length;
Ray Milkey269ffb92014-04-03 14:43:30 -0700130 }
yoshi28bac132014-01-22 11:00:17 -0800131 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800132
yoshi28bac132014-01-22 11:00:17 -0800133 public static class MultiWriteObject {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800134 public long[] tableId;
135 public byte[] key[];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800136 public short[] keyLength;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800137 public byte[] value[];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800138 public int[] valueLength;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800139 public RejectRules[] rules;
yoshi28bac132014-01-22 11:00:17 -0800140
Yoshi Muroie7693b12014-02-19 19:41:17 -0800141 public MultiWriteObject(int size) {
142 this.tableId = new long[size];
143 this.key = new byte[size][];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800144 this.keyLength = new short[size];
Yoshi Muroie7693b12014-02-19 19:41:17 -0800145 this.value = new byte[size][];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800146 this.valueLength = new int[size];
Yoshi Muroie7693b12014-02-19 19:41:17 -0800147 this.rules = new RejectRules[size];
yoshi28bac132014-01-22 11:00:17 -0800148 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800149
Ray Milkey269ffb92014-04-03 14:43:30 -0700150 public void setObject(int num, long tableId, byte key[], byte value[], RejectRules rules){
151 this.tableId[num] = tableId;
152 this.key[num] = key;
153 this.keyLength[num] = (short) key.length;
154 this.value[num] = value;
155 this.valueLength[num] = value.length;
156 this.rules[num] = rules;
157 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800158
yoshi28bac132014-01-22 11:00:17 -0800159 }
160
Yoshi Muroie7693b12014-02-19 19:41:17 -0800161 public static class MultiWriteRspObject {
yoshi28bac132014-01-22 11:00:17 -0800162 private int status;
163 private long version;
164
165 public MultiWriteRspObject(int status, long version) {
166 this.status = status;
167 this.version = version;
168 }
169 public int getStatus() {
170 return status;
171 }
172
173 public long getVersion() {
174 return version;
175 }
176 }
177
178 /**
179 * This class is returned by Read operations. It encapsulates the entire
180 * object, including the key, value, and version.
181 *
182 * It mostly exists because Java doesn't support primitive out parameters
183 * or multiple return values, and we don't know the object's size ahead of
184 * time, so passing in a fixed-length array would be problematic.
185 */
Yoshi Muroie7693b12014-02-19 19:41:17 -0800186 public static class Object {
yoshi28bac132014-01-22 11:00:17 -0800187 Object(byte[] _key, byte[] _value, long _version)
188 {
189 key = _key;
190 value = _value;
191 version = _version;
192 }
193
194 public String
195 getKey()
196 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800197 return new String(key,StandardCharsets.UTF_8);
yoshi28bac132014-01-22 11:00:17 -0800198 }
199
200 public String
201 getValue()
202 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800203 return new String(value,StandardCharsets.UTF_8);
yoshi28bac132014-01-22 11:00:17 -0800204 }
205
206 final public byte[] key;
207 final public byte[] value;
208 final public long version;
209 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800210
Yoshi Muroie7693b12014-02-19 19:41:17 -0800211 public static class TableEnumeratorObject {
Ray Milkey269ffb92014-04-03 14:43:30 -0700212 TableEnumeratorObject(Object[] _object, long _nextHash)
213 {
214 object = _object;
215 nextHash = _nextHash;
216 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800217
Ray Milkey269ffb92014-04-03 14:43:30 -0700218 final public Object[] object;
219 final public long nextHash;
Yoshi Muroie7693b12014-02-19 19:41:17 -0800220 }
yoshi28bac132014-01-22 11:00:17 -0800221
Yuta HIGUCHIe316d5c2014-04-19 13:37:38 -0700222 @Deprecated
yoshi28bac132014-01-22 11:00:17 -0800223 public class TableEnumerator {
224 private long tableEnumeratorObjectPointer = 0;
225 private long ramCloudObjectPointer = 0;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800226
yoshi28bac132014-01-22 11:00:17 -0800227 public TableEnumerator(long tableId)
228 {
229 ramCloudObjectPointer = ramcloudObjectPointer;
230 tableEnumeratorObjectPointer = init(tableId);
231 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800232
yoshi28bac132014-01-22 11:00:17 -0800233 private native long init(long tableId);
234 public native boolean hasNext();
235 public native Object next();
236 }
237
Yoshi Muroie7693b12014-02-19 19:41:17 -0800238 public class TableEnumerator2 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800239
Ray Milkey269ffb92014-04-03 14:43:30 -0700240 protected long tableId;
241 protected LinkedList<JRamCloud.Object> rcobjs = null;
242 protected long nextHash = 0;
243 protected boolean done = false;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800244
Yoshi Muroie7693b12014-02-19 19:41:17 -0800245 public TableEnumerator2(long tableId)
246 {
Ray Milkey269ffb92014-04-03 14:43:30 -0700247 this.tableId = tableId;
248 rcobjs = new LinkedList<>();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800249 }
250 public boolean hasNext() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700251 if (rcobjs.isEmpty())
252 {
253 if (done) {
254 return false;
255 }
256 JRamCloud.TableEnumeratorObject o = getTableObjects(this.tableId, this.nextHash);
257 if (o.nextHash == 0L) {
258 done = true;
259 }
260 this.nextHash = o.nextHash;
261 rcobjs.addAll(Arrays.asList(o.object));
262 if (rcobjs.isEmpty()) {
263 return false;
264 }
265 }
266 return true;
267 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800268
Ray Milkey269ffb92014-04-03 14:43:30 -0700269 public Object next()
270 {
271 return rcobjs.pop();
272 }
Yoshi Muroie7693b12014-02-19 19:41:17 -0800273 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800274
yoshi28bac132014-01-22 11:00:17 -0800275 /**
276 * Connect to the RAMCloud cluster specified by the given coordinator's
277 * service locator string. This causes the JNI code to instantiate the
278 * underlying RamCloud C++ object.
279 */
280 public
281 JRamCloud(String coordinatorLocator)
282 {
283 ramcloudObjectPointer = connect(coordinatorLocator);
284 }
285
286 /**
287 * Disconnect from the RAMCloud cluster. This causes the JNI code to
288 * destroy the underlying RamCloud C++ object.
289 */
290 public void
291 disconnect()
292 {
293 if (ramcloudObjectPointer != 0) {
294 disconnect(ramcloudObjectPointer);
295 ramcloudObjectPointer = 0;
296 }
297 }
298
299 /**
300 * This method is called by the garbage collector before destroying the
301 * object. The user really should have called disconnect, but in case
302 * they did not, be sure to clean up after them.
303 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800304 @Override
305 protected void
yoshi28bac132014-01-22 11:00:17 -0800306 finalize()
307 {
308 System.err.println("warning: JRamCloud::disconnect() was not called " +
309 "prior to the finalizer. You should disconnect " +
310 "your JRamCloud object when you're done with it.");
311 disconnect();
312 }
313
314 /**
315 * Convenience read() wrapper that take a String key argument.
316 */
317 public Object
318 read(long tableId, String key)
319 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800320 return read(tableId, key.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800321 }
322
323 /**
324 * Convenience read() wrapper that take a String key argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800325 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800326 */
327 public Object
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800328 read(long tableId, String key, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800329 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800330 return read(tableId, key.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800331 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800332
yoshi28bac132014-01-22 11:00:17 -0800333 /**
334 * Convenience remove() wrapper that take a String key argument.
335 */
336 public long
337 remove(long tableId, String key)
338 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800339 return remove(tableId, key.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800340 }
341
342 /**
343 * Convenience remove() wrapper that take a String key argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800344 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800345 */
346 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800347 remove(long tableId, String key, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800348 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800349 return remove(tableId, key.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800350 }
351
352 /**
353 * Convenience write() wrapper that take String key and value arguments.
354 */
355 public long
356 write(long tableId, String key, String value)
357 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800358 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800359 }
360
361 /**
362 * Convenience write() wrapper that take String key and value arguments.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800363 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800364 */
365 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800366 write(long tableId, String key, String value, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800367 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800368 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800369 }
370
371 /**
372 * Convenience write() wrapper that takes a String key and a byte[] value
373 * argument.
374 */
375 public long
376 write(long tableId, String key, byte[] value)
377 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800378 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value);
yoshi28bac132014-01-22 11:00:17 -0800379 }
380
381 /**
382 * Convenience write() wrapper that takes a String key and a byte[] value
383 * argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800384 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800385 */
386 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800387 write(long tableId, String key, byte[] value, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800388 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800389 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value, rules);
yoshi28bac132014-01-22 11:00:17 -0800390 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800391
yoshi28bac132014-01-22 11:00:17 -0800392 private static native long connect(String coordinatorLocator);
393 private static native void disconnect(long ramcloudObjectPointer);
394
395 public native long createTable(String name);
396 public native long createTable(String name, int serverSpan);
397 public native void dropTable(String name);
398 public native long getTableId(String name);
399 public native Object read(long tableId, byte[] key);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800400 public native Object read(long tableId, byte[] key, RejectRules rules) throws RejectRulesException;
Yoshi Muroi2c170602014-02-15 08:31:28 -0800401 public native Object[] multiRead(long[] tableId, byte[] keydata[], short[] keyDataSize, int requestNum);
yoshi28bac132014-01-22 11:00:17 -0800402 public native long remove(long tableId, byte[] key);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800403 public native long remove(long tableId, byte[] key, RejectRules rules) throws RejectRulesException;
yoshi28bac132014-01-22 11:00:17 -0800404 public native long write(long tableId, byte[] key, byte[] value);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800405 public native long write(long tableId, byte[] key, byte[] value, RejectRules rules) throws RejectRulesException;
406 @Deprecated
yoshi28bac132014-01-22 11:00:17 -0800407 public native long writeRule(long tableId, byte[] key, byte[] value, RejectRules rules);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800408 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 -0800409 public native TableEnumeratorObject getTableObjects(long tableId, long nextHash);
Yuta HIGUCHId47eac32014-04-07 13:44:47 -0700410 public native long increment(long tableId, byte[] key, long incrementValue) throws ObjectDoesntExistException;
yoshi28bac132014-01-22 11:00:17 -0800411
412 /*
413 * The following exceptions may be thrown by the JNI functions:
414 */
415
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800416 public static class TableDoesntExistException extends RuntimeException {
yoshi28bac132014-01-22 11:00:17 -0800417 public TableDoesntExistException(String message)
418 {
419 super(message);
420 }
421 }
422
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800423 public static class ObjectDoesntExistException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800424 public ObjectDoesntExistException(String message)
425 {
426 super(message);
427 }
428 }
429
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800430 public static class ObjectExistsException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800431 public ObjectExistsException(String message)
432 {
433 super(message);
434 }
435 }
436
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800437 public static class WrongVersionException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800438 public WrongVersionException(String message)
439 {
440 super(message);
441 }
442 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800443
444 public static class InvalidObjectException extends RuntimeException {
yoshi28bac132014-01-22 11:00:17 -0800445 public InvalidObjectException(String message) {
446 super(message);
447 }
448 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800449
450 public static class RejectRulesException extends Exception {
yoshi28bac132014-01-22 11:00:17 -0800451 public RejectRulesException(String message) {
452 super(message);
453 }
454 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800455
Yoshi Muroie7693b12014-02-19 19:41:17 -0800456 public static void tableEnumeratorTest(JRamCloud ramcloud) {
457 long startTime = 0;
458 for (int x = 0 ; x < 2 ; x ++){
459 for(int N = 1000; N < 10000; N += 1000) {
460 long EnumerateTesttable = ramcloud.createTable("EnumerateTest");
461 for(int i = 0 ; i < N ; ++i) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800462 String key = String.valueOf(i);
463 ramcloud.write(EnumerateTesttable, key.getBytes(StandardCharsets.UTF_8), "Hello, World!".getBytes(StandardCharsets.UTF_8));
Yoshi Muroie7693b12014-02-19 19:41:17 -0800464 }
yoshi28bac132014-01-22 11:00:17 -0800465
Yoshi Muroie7693b12014-02-19 19:41:17 -0800466 long tableIdList[] = new long[N];
467 byte[] keydata[] = new byte[N][];
468 short keydataSize[] = new short[N];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800469 startTime = System.nanoTime();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800470 for (int j = 0 ; j < N ; ++j) {
471 tableIdList[j] = EnumerateTesttable;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800472 String key = String.valueOf(j);
473 keydata[j] = key.getBytes(StandardCharsets.UTF_8);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800474 keydataSize[j] = (short) keydata[j].length;
475 }
476 JRamCloud.Object out[] = ramcloud.multiRead(tableIdList, keydata, keydataSize, N);
477 for (int i = 0; i < N; ++i) {
478 if(out[i].version == 0) {
479 System.out.println("Verify fail " + out[i].getKey() + " V:" + out[i].getValue());
480 }
481 }
482
483 System.out.println("multiRead : " + N + " Time : " + (System.nanoTime()-startTime));
484
485 startTime = System.nanoTime();
486 JRamCloud.TableEnumerator tableEnum = ramcloud.new TableEnumerator(EnumerateTesttable);
487 while (tableEnum.hasNext()) {
488 Object tableEntry = tableEnum.next();
489 if (tableEntry != null) {
490 System.out.println("tableEnumerator object: key = [" + tableEntry.getKey() + "], value = [" + tableEntry.getValue() + "]");
491 }
492 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800493 System.out.println("old TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
Yoshi Muroie7693b12014-02-19 19:41:17 -0800494
495 startTime = System.nanoTime();
496 JRamCloud.TableEnumerator2 tableEnum2 = ramcloud.new TableEnumerator2(EnumerateTesttable);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800497 while (tableEnum2.hasNext()) {
498 Object tableEntry2 = tableEnum2.next();
499 if (tableEntry2 != null) {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800500 System.out.println("tableEnumerator2 object: key = [" + tableEntry2.getKey() + "], value = [" + tableEntry2.getValue() + "]");
501 }
502 }
503 System.out.println("new TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
504 ramcloud.dropTable("EnumerateTest");
505 }
506 }
507 }
yoshi28bac132014-01-22 11:00:17 -0800508 /**
509 * A simple end-to-end test of the java bindings.
510 */
511 public static void
512 main(String argv[])
513 {
514 JRamCloud ramcloud = new JRamCloud(argv[0]);
515 long tableId = ramcloud.createTable("hi");
516 System.out.println("created table, id = " + tableId);
517 long tableId2 = ramcloud.getTableId("hi");
518 System.out.println("getTableId says tableId = " + tableId2);
519
520 System.out.println("wrote obj version = " +
521 ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue"));
522
523 JRamCloud.Object o = ramcloud.read(tableId, "thisIsTheKey");
524 System.out.println("read object: key = [" + o.getKey() + "], value = ["
525 + o.getValue() + "], version = " + o.version);
526
527 ramcloud.remove(tableId, "thisIsTheKey");
528
529 try {
530 ramcloud.read(tableId, "thisIsTheKey");
531 System.out.println("Error: shouldn't have read successfully!");
532 } catch (Exception e) {
533 // OK
534 }
535
536 ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800537
yoshi28bac132014-01-22 11:00:17 -0800538 long before = System.nanoTime();
539 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800540 @SuppressWarnings("unused")
yoshi28bac132014-01-22 11:00:17 -0800541 JRamCloud.Object unused = ramcloud.read(tableId, "thisIsTheKey");
542 }
543 long after = System.nanoTime();
544 System.out.println("Avg read latency: " +
545 ((double)(after - before) / 1000 / 1000) + " usec");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800546
yoshi28bac132014-01-22 11:00:17 -0800547 // multiRead test
548 long tableId4 = ramcloud.createTable("table4");
549 System.out.println("table4 id " + tableId4);
550 ramcloud.write(tableId4, "object1-1", "value:1-1");
551 ramcloud.write(tableId4, "object1-2", "value:1-2");
552 ramcloud.write(tableId4, "object1-3", "value:1-3");
553 long tableId5 = ramcloud.createTable("table5");
554 System.out.println("table5 id " + tableId5);
555 ramcloud.write(tableId5, "object2-1", "value:2-1");
556 long tableId6 = ramcloud.createTable("table6");
557 ramcloud.write(tableId6, "object3-1", "value:3-1");
558 ramcloud.write(tableId6, "object3-2", "value:3-2");
559
Ray Milkey269ffb92014-04-03 14:43:30 -0700560 MultiReadObject mr = new MultiReadObject(2);
561 MultiWriteObject mw = new MultiWriteObject(2);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800562
Ray Milkey269ffb92014-04-03 14:43:30 -0700563 mr.setObject(0, tableId4, "object1-1".getBytes(StandardCharsets.UTF_8));
564 mr.setObject(1, tableId5, "object2-1".getBytes(StandardCharsets.UTF_8));
Yoshi Muroi2c170602014-02-15 08:31:28 -0800565
Yoshi Muroie7693b12014-02-19 19:41:17 -0800566 JRamCloud.Object out[] = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
yoshi28bac132014-01-22 11:00:17 -0800567 for (int i = 0 ; i < 2 ; i++){
568 System.out.println("multi read object: key = [" + out[i].getKey() + "], value = ["
569 + out[i].getValue() + "]");
yoshi28bac132014-01-22 11:00:17 -0800570 }
Yoshi Muroi2c170602014-02-15 08:31:28 -0800571
yoshi28bac132014-01-22 11:00:17 -0800572 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800573 String key1 = "key1" + String.valueOf(i);
574 String key2 = "key2" + String.valueOf(i);
575
576 mw.setObject(0, tableId4, key1.getBytes(StandardCharsets.UTF_8), "v0-value".getBytes(StandardCharsets.UTF_8), null);
577 mw.setObject(1, tableId5, key2.getBytes(StandardCharsets.UTF_8), "v1".getBytes(StandardCharsets.UTF_8), null);
578
Yoshi Muroie7693b12014-02-19 19:41:17 -0800579 MultiWriteRspObject[] rsp = ramcloud.multiWrite(mw.tableId, mw.key, mw.keyLength, mw.value, mw.valueLength, 2, mw.rules);
yoshi28bac132014-01-22 11:00:17 -0800580 if (rsp != null) {
581 for (int j = 0; j < rsp.length; j++) {
582 System.out.println("multi write rsp(" + j + ") status:version " + rsp[j].getStatus() + ":" + rsp[j].getVersion());
583 }
584 }
585 }
586 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800587 String key1 = "key1" + String.valueOf(i);
588 String key2 = "key2" + String.valueOf(i);
Yoshi Muroi2c170602014-02-15 08:31:28 -0800589
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800590 mr.setObject(0, tableId4, key1.getBytes(StandardCharsets.UTF_8));
591 mr.setObject(1, tableId5, key2.getBytes(StandardCharsets.UTF_8));
592
Yoshi Muroie7693b12014-02-19 19:41:17 -0800593 out = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
yoshi28bac132014-01-22 11:00:17 -0800594 for (int j = 0; j < 2; j++) {
595 System.out.println("multi read object: key = [" + out[j].getKey() + "], value = [" + out[j].getValue() + "]");
596 }
597 }
Yoshi Muroi2c170602014-02-15 08:31:28 -0800598
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800599 tableEnumeratorTest(ramcloud);
600
yoshi28bac132014-01-22 11:00:17 -0800601 ramcloud.dropTable("table4");
602 ramcloud.dropTable("table5");
603 ramcloud.dropTable("table6");
604 ramcloud.disconnect();
605 }
606}