blob: d7a1f63560c8a515bcd2c3d50fc5055369861e1f [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
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700281 JRamCloud(String coordinatorLocator, String clusterName)
282 {
283 ramcloudObjectPointer = connect(coordinatorLocator, clusterName);
284 }
285
286 public
yoshi28bac132014-01-22 11:00:17 -0800287 JRamCloud(String coordinatorLocator)
288 {
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700289 this(coordinatorLocator, "main");
yoshi28bac132014-01-22 11:00:17 -0800290 }
291
292 /**
293 * Disconnect from the RAMCloud cluster. This causes the JNI code to
294 * destroy the underlying RamCloud C++ object.
295 */
296 public void
297 disconnect()
298 {
299 if (ramcloudObjectPointer != 0) {
300 disconnect(ramcloudObjectPointer);
301 ramcloudObjectPointer = 0;
302 }
303 }
304
305 /**
306 * This method is called by the garbage collector before destroying the
307 * object. The user really should have called disconnect, but in case
308 * they did not, be sure to clean up after them.
309 */
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800310 @Override
311 protected void
yoshi28bac132014-01-22 11:00:17 -0800312 finalize()
313 {
314 System.err.println("warning: JRamCloud::disconnect() was not called " +
315 "prior to the finalizer. You should disconnect " +
316 "your JRamCloud object when you're done with it.");
317 disconnect();
318 }
319
320 /**
321 * Convenience read() wrapper that take a String key argument.
322 */
323 public Object
324 read(long tableId, String key)
325 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800326 return read(tableId, key.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800327 }
328
329 /**
330 * Convenience read() wrapper that take a String key argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800331 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800332 */
333 public Object
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800334 read(long tableId, String key, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800335 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800336 return read(tableId, key.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800337 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800338
yoshi28bac132014-01-22 11:00:17 -0800339 /**
340 * Convenience remove() wrapper that take a String key argument.
341 */
342 public long
343 remove(long tableId, String key)
344 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800345 return remove(tableId, key.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800346 }
347
348 /**
349 * Convenience remove() wrapper that take a String key argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800350 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800351 */
352 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800353 remove(long tableId, String key, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800354 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800355 return remove(tableId, key.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800356 }
357
358 /**
359 * Convenience write() wrapper that take String key and value arguments.
360 */
361 public long
362 write(long tableId, String key, String value)
363 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800364 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8));
yoshi28bac132014-01-22 11:00:17 -0800365 }
366
367 /**
368 * Convenience write() wrapper that take String key and value arguments.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800369 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800370 */
371 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800372 write(long tableId, String key, String value, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800373 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800374 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8), rules);
yoshi28bac132014-01-22 11:00:17 -0800375 }
376
377 /**
378 * Convenience write() wrapper that takes a String key and a byte[] value
379 * argument.
380 */
381 public long
382 write(long tableId, String key, byte[] value)
383 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800384 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value);
yoshi28bac132014-01-22 11:00:17 -0800385 }
386
387 /**
388 * Convenience write() wrapper that takes a String key and a byte[] value
389 * argument.
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800390 * @throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800391 */
392 public long
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800393 write(long tableId, String key, byte[] value, RejectRules rules) throws RejectRulesException
yoshi28bac132014-01-22 11:00:17 -0800394 {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800395 return write(tableId, key.getBytes(StandardCharsets.UTF_8), value, rules);
yoshi28bac132014-01-22 11:00:17 -0800396 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800397
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700398 private static native long connect(String coordinatorLocator, String clusterName);
yoshi28bac132014-01-22 11:00:17 -0800399 private static native void disconnect(long ramcloudObjectPointer);
400
401 public native long createTable(String name);
402 public native long createTable(String name, int serverSpan);
403 public native void dropTable(String name);
404 public native long getTableId(String name);
405 public native Object read(long tableId, byte[] key);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800406 public native Object read(long tableId, byte[] key, RejectRules rules) throws RejectRulesException;
Yoshi Muroi2c170602014-02-15 08:31:28 -0800407 public native Object[] multiRead(long[] tableId, byte[] keydata[], short[] keyDataSize, int requestNum);
yoshi28bac132014-01-22 11:00:17 -0800408 public native long remove(long tableId, byte[] key);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800409 public native long remove(long tableId, byte[] key, RejectRules rules) throws RejectRulesException;
yoshi28bac132014-01-22 11:00:17 -0800410 public native long write(long tableId, byte[] key, byte[] value);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800411 public native long write(long tableId, byte[] key, byte[] value, RejectRules rules) throws RejectRulesException;
412 @Deprecated
yoshi28bac132014-01-22 11:00:17 -0800413 public native long writeRule(long tableId, byte[] key, byte[] value, RejectRules rules);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800414 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 -0800415 public native TableEnumeratorObject getTableObjects(long tableId, long nextHash);
Yuta HIGUCHId47eac32014-04-07 13:44:47 -0700416 public native long increment(long tableId, byte[] key, long incrementValue) throws ObjectDoesntExistException;
yoshi28bac132014-01-22 11:00:17 -0800417
418 /*
419 * The following exceptions may be thrown by the JNI functions:
420 */
421
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800422 public static class TableDoesntExistException extends RuntimeException {
yoshi28bac132014-01-22 11:00:17 -0800423 public TableDoesntExistException(String message)
424 {
425 super(message);
426 }
427 }
428
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800429 public static class ObjectDoesntExistException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800430 public ObjectDoesntExistException(String message)
431 {
432 super(message);
433 }
434 }
435
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800436 public static class ObjectExistsException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800437 public ObjectExistsException(String message)
438 {
439 super(message);
440 }
441 }
442
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800443 public static class WrongVersionException extends RejectRulesException {
yoshi28bac132014-01-22 11:00:17 -0800444 public WrongVersionException(String message)
445 {
446 super(message);
447 }
448 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800449
450 public static class InvalidObjectException extends RuntimeException {
yoshi28bac132014-01-22 11:00:17 -0800451 public InvalidObjectException(String message) {
452 super(message);
453 }
454 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800455
456 public static class RejectRulesException extends Exception {
yoshi28bac132014-01-22 11:00:17 -0800457 public RejectRulesException(String message) {
458 super(message);
459 }
460 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800461
Yuta HIGUCHId150ece2014-04-29 16:25:36 -0700462 // TODO Define and support some of ClientException sub-classes.
463 public static class ClientException extends Exception {
464 public ClientException(String message) {
465 super(message);
466 }
467 }
468
Yoshi Muroie7693b12014-02-19 19:41:17 -0800469 public static void tableEnumeratorTest(JRamCloud ramcloud) {
470 long startTime = 0;
471 for (int x = 0 ; x < 2 ; x ++){
472 for(int N = 1000; N < 10000; N += 1000) {
473 long EnumerateTesttable = ramcloud.createTable("EnumerateTest");
474 for(int i = 0 ; i < N ; ++i) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800475 String key = String.valueOf(i);
476 ramcloud.write(EnumerateTesttable, key.getBytes(StandardCharsets.UTF_8), "Hello, World!".getBytes(StandardCharsets.UTF_8));
Yoshi Muroie7693b12014-02-19 19:41:17 -0800477 }
yoshi28bac132014-01-22 11:00:17 -0800478
Yoshi Muroie7693b12014-02-19 19:41:17 -0800479 long tableIdList[] = new long[N];
480 byte[] keydata[] = new byte[N][];
481 short keydataSize[] = new short[N];
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800482 startTime = System.nanoTime();
Yoshi Muroie7693b12014-02-19 19:41:17 -0800483 for (int j = 0 ; j < N ; ++j) {
484 tableIdList[j] = EnumerateTesttable;
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800485 String key = String.valueOf(j);
486 keydata[j] = key.getBytes(StandardCharsets.UTF_8);
Yoshi Muroie7693b12014-02-19 19:41:17 -0800487 keydataSize[j] = (short) keydata[j].length;
488 }
489 JRamCloud.Object out[] = ramcloud.multiRead(tableIdList, keydata, keydataSize, N);
490 for (int i = 0; i < N; ++i) {
491 if(out[i].version == 0) {
492 System.out.println("Verify fail " + out[i].getKey() + " V:" + out[i].getValue());
493 }
494 }
495
496 System.out.println("multiRead : " + N + " Time : " + (System.nanoTime()-startTime));
497
498 startTime = System.nanoTime();
499 JRamCloud.TableEnumerator tableEnum = ramcloud.new TableEnumerator(EnumerateTesttable);
500 while (tableEnum.hasNext()) {
501 Object tableEntry = tableEnum.next();
502 if (tableEntry != null) {
503 System.out.println("tableEnumerator object: key = [" + tableEntry.getKey() + "], value = [" + tableEntry.getValue() + "]");
504 }
505 }
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800506 System.out.println("old TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
Yoshi Muroie7693b12014-02-19 19:41:17 -0800507
508 startTime = System.nanoTime();
509 JRamCloud.TableEnumerator2 tableEnum2 = ramcloud.new TableEnumerator2(EnumerateTesttable);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800510 while (tableEnum2.hasNext()) {
511 Object tableEntry2 = tableEnum2.next();
512 if (tableEntry2 != null) {
Yoshi Muroie7693b12014-02-19 19:41:17 -0800513 System.out.println("tableEnumerator2 object: key = [" + tableEntry2.getKey() + "], value = [" + tableEntry2.getValue() + "]");
514 }
515 }
516 System.out.println("new TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
517 ramcloud.dropTable("EnumerateTest");
518 }
519 }
520 }
yoshi28bac132014-01-22 11:00:17 -0800521 /**
522 * A simple end-to-end test of the java bindings.
523 */
524 public static void
525 main(String argv[])
526 {
527 JRamCloud ramcloud = new JRamCloud(argv[0]);
528 long tableId = ramcloud.createTable("hi");
529 System.out.println("created table, id = " + tableId);
530 long tableId2 = ramcloud.getTableId("hi");
531 System.out.println("getTableId says tableId = " + tableId2);
532
533 System.out.println("wrote obj version = " +
534 ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue"));
535
536 JRamCloud.Object o = ramcloud.read(tableId, "thisIsTheKey");
537 System.out.println("read object: key = [" + o.getKey() + "], value = ["
538 + o.getValue() + "], version = " + o.version);
539
540 ramcloud.remove(tableId, "thisIsTheKey");
541
542 try {
543 ramcloud.read(tableId, "thisIsTheKey");
544 System.out.println("Error: shouldn't have read successfully!");
545 } catch (Exception e) {
546 // OK
547 }
548
549 ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800550
yoshi28bac132014-01-22 11:00:17 -0800551 long before = System.nanoTime();
552 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800553 @SuppressWarnings("unused")
yoshi28bac132014-01-22 11:00:17 -0800554 JRamCloud.Object unused = ramcloud.read(tableId, "thisIsTheKey");
555 }
556 long after = System.nanoTime();
557 System.out.println("Avg read latency: " +
558 ((double)(after - before) / 1000 / 1000) + " usec");
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800559
yoshi28bac132014-01-22 11:00:17 -0800560 // multiRead test
561 long tableId4 = ramcloud.createTable("table4");
562 System.out.println("table4 id " + tableId4);
563 ramcloud.write(tableId4, "object1-1", "value:1-1");
564 ramcloud.write(tableId4, "object1-2", "value:1-2");
565 ramcloud.write(tableId4, "object1-3", "value:1-3");
566 long tableId5 = ramcloud.createTable("table5");
567 System.out.println("table5 id " + tableId5);
568 ramcloud.write(tableId5, "object2-1", "value:2-1");
569 long tableId6 = ramcloud.createTable("table6");
570 ramcloud.write(tableId6, "object3-1", "value:3-1");
571 ramcloud.write(tableId6, "object3-2", "value:3-2");
572
Ray Milkey269ffb92014-04-03 14:43:30 -0700573 MultiReadObject mr = new MultiReadObject(2);
574 MultiWriteObject mw = new MultiWriteObject(2);
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800575
Ray Milkey269ffb92014-04-03 14:43:30 -0700576 mr.setObject(0, tableId4, "object1-1".getBytes(StandardCharsets.UTF_8));
577 mr.setObject(1, tableId5, "object2-1".getBytes(StandardCharsets.UTF_8));
Yoshi Muroi2c170602014-02-15 08:31:28 -0800578
Yoshi Muroie7693b12014-02-19 19:41:17 -0800579 JRamCloud.Object out[] = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
yoshi28bac132014-01-22 11:00:17 -0800580 for (int i = 0 ; i < 2 ; i++){
581 System.out.println("multi read object: key = [" + out[i].getKey() + "], value = ["
582 + out[i].getValue() + "]");
yoshi28bac132014-01-22 11:00:17 -0800583 }
Yoshi Muroi2c170602014-02-15 08:31:28 -0800584
yoshi28bac132014-01-22 11:00:17 -0800585 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800586 String key1 = "key1" + String.valueOf(i);
587 String key2 = "key2" + String.valueOf(i);
588
589 mw.setObject(0, tableId4, key1.getBytes(StandardCharsets.UTF_8), "v0-value".getBytes(StandardCharsets.UTF_8), null);
590 mw.setObject(1, tableId5, key2.getBytes(StandardCharsets.UTF_8), "v1".getBytes(StandardCharsets.UTF_8), null);
591
Yoshi Muroie7693b12014-02-19 19:41:17 -0800592 MultiWriteRspObject[] rsp = ramcloud.multiWrite(mw.tableId, mw.key, mw.keyLength, mw.value, mw.valueLength, 2, mw.rules);
yoshi28bac132014-01-22 11:00:17 -0800593 if (rsp != null) {
594 for (int j = 0; j < rsp.length; j++) {
595 System.out.println("multi write rsp(" + j + ") status:version " + rsp[j].getStatus() + ":" + rsp[j].getVersion());
596 }
597 }
598 }
599 for (int i = 0; i < 1000; i++) {
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800600 String key1 = "key1" + String.valueOf(i);
601 String key2 = "key2" + String.valueOf(i);
Yoshi Muroi2c170602014-02-15 08:31:28 -0800602
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800603 mr.setObject(0, tableId4, key1.getBytes(StandardCharsets.UTF_8));
604 mr.setObject(1, tableId5, key2.getBytes(StandardCharsets.UTF_8));
605
Yoshi Muroie7693b12014-02-19 19:41:17 -0800606 out = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
yoshi28bac132014-01-22 11:00:17 -0800607 for (int j = 0; j < 2; j++) {
608 System.out.println("multi read object: key = [" + out[j].getKey() + "], value = [" + out[j].getValue() + "]");
609 }
610 }
Yoshi Muroi2c170602014-02-15 08:31:28 -0800611
Yuta HIGUCHI1d6a22a2014-02-21 19:17:42 -0800612 tableEnumeratorTest(ramcloud);
613
yoshi28bac132014-01-22 11:00:17 -0800614 ramcloud.dropTable("table4");
615 ramcloud.dropTable("table5");
616 ramcloud.dropTable("table6");
617 ramcloud.disconnect();
618 }
619}