String password;
SecureRandom random;
static final int SALT_SIZE = 8;
+ static final int TIMEOUT_MILLIS = 100;
byte salt[];
Table table;
/**
* Empty Constructor needed for child class.
*/
-
CloudComm() {
}
/**
* Constructor for actual use. Takes in the url and password.
*/
-
CloudComm(Table _table, String _baseurl, String _password) {
this.table = _table;
this.baseurl = _baseurl;
/**
* Generates Key from password.
*/
-
private SecretKeySpec initKey() {
try {
PBEKeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
/**
* Inits the HMAC generator.
*/
-
private void initCrypt() {
try {
SecretKeySpec key = initKey();
/*
* Builds the URL for the given request.
*/
-
private URL buildRequest(boolean isput, long sequencenumber, long maxentries) throws IOException {
String reqstring = isput ? "req=putslot" : "req=getslot";
String urlstr = baseurl + "?" + reqstring + "&seq=" + sequencenumber;
return new URL(urlstr);
}
- public void setSalt() throws ServerException{
+ public void setSalt() throws ServerException {
try {
- salt = new byte[SALT_SIZE];
- random.nextBytes(salt);
+ byte[] saltTmp = new byte[SALT_SIZE];
+ random.nextBytes(saltTmp);
URL url = new URL(baseurl + "?req=setsalt");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
- http.setFixedLengthStreamingMode(salt.length);
+ http.setFixedLengthStreamingMode(saltTmp.length);
http.setDoOutput(true);
+ http.setConnectTimeout(TIMEOUT_MILLIS);
http.connect();
OutputStream os = http.getOutputStream();
- os.write(salt);
+ os.write(saltTmp);
int responsecode = http.getResponseCode();
if (responsecode != HttpURLConnection.HTTP_OK) {
// TODO: Remove this print
// System.out.println(responsecode);
throw new Error("Invalid response");
}
+
+ salt = saltTmp;
} catch (Exception e) {
e.printStackTrace();
throw new ServerException("Failed setting salt");
* numbers.
*/
- Slot[] putSlot(Slot slot, int max) throws ServerException{
+ Slot[] putSlot(Slot slot, int max) throws ServerException {
try {
if (salt == null) {
getSalt();
byte[] bytes = slot.encode(mac);
bytes = encryptCipher.doFinal(bytes);
+
URL url = buildRequest(true, sequencenumber, max);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setFixedLengthStreamingMode(bytes.length);
http.setDoOutput(true);
+ http.setConnectTimeout(TIMEOUT_MILLIS);
+ // http.setReadTimeout(TIMEOUT_MILLIS);
http.connect();
OutputStream os = http.getOutputStream();
os.write(bytes);
+ os.flush();
+
InputStream is = http.getInputStream();
DataInputStream dis = new DataInputStream(is);
byte[] resptype = new byte[7];
dis.readFully(resptype);
+
if (Arrays.equals(resptype, "getslot".getBytes()))
return processSlots(dis);
else if (Arrays.equals(resptype, "putslot".getBytes()))
return null;
else
throw new Error("Bad response to putslot");
+
} catch (Exception e) {
- e.printStackTrace();
throw new ServerException("putSlot failed");
}
}
* Request the server to send all slots with the given
* sequencenumber or newer.
*/
-
Slot[] getSlots(long sequencenumber) throws ServerException {
try {
if (salt == null) {
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
+ http.setConnectTimeout(TIMEOUT_MILLIS);
+ // http.setReadTimeout(TIMEOUT_MILLIS);
http.connect();
InputStream is = http.getInputStream();
-
DataInputStream dis = new DataInputStream(is);
+ int responsecode = http.getResponseCode();
+ if (responsecode != HttpURLConnection.HTTP_OK) {
+ // TODO: Remove this print
+ // System.out.println("Code: " + responsecode);
+ throw new ServerException("getSlots failed");
+ }
+
byte[] resptype = new byte[7];
dis.readFully(resptype);
if (!Arrays.equals(resptype, "getslot".getBytes()))
else
return processSlots(dis);
} catch (Exception e) {
- e.printStackTrace();
+ // e.printStackTrace();
throw new ServerException("getSlots failed");
}
}
* Method that actually handles building Slot objects from the
* server response. Shared by both putSlot and getSlots.
*/
-
private Slot[] processSlots(DataInputStream dis) throws Exception {
int numberofslots = dis.readInt();
int[] sizesofslots = new int[numberofslots];
private int smallestTableStatusSeen = -1;
private int largestTableStatusSeen = -1;
+ private int lastSeenPendingTransactionSpeculateIndex = 0;
private PendingTransaction pendingTransBuild = null; // Pending Transaction used in building
- private Queue<PendingTransaction> pendingTransQueue = null; // Queue of pending transactions
+ private LinkedList<PendingTransaction> pendingTransQueue = null; // Queue of pending transactions
private Map<Long, Commit> commitMap = null; // List of all the most recent live commits
private Map<Long, Abort> abortMap = null; // Set of the live aborts
private Map<IoTString, Commit> committedMapByKey = null; // Table of committed KV
private Map<Long, Commit> newCommitMap = null; // Map of all the new commits
private Map<Long, Long> lastCommitSeenSeqNumMap = null; // sequence number of the last commit that was seen grouped by arbitrator
private Map<Long, Long> lastAbortSeenSeqNumMap = null; // sequence number of the last commit that was seen grouped by arbitrator
+ private Map<IoTString, KeyValue> pendingTransSpeculativeTable = null;
newCommitMap = new HashMap<Long, Commit>();
lastCommitSeenSeqNumMap = new HashMap<Long, Long>();
lastAbortSeenSeqNumMap = new HashMap<Long, Long>();
+ pendingTransSpeculativeTable = new HashMap<IoTString, KeyValue>();
}
public void rebuild() throws ServerException {
}
public IoTString getSpeculative(IoTString key) {
- KeyValue kv = speculativeTable.get(key);
+ KeyValue kv = pendingTransSpeculativeTable.get(key);
+
+ if (kv == null) {
+ kv = speculativeTable.get(key);
+ }
+
+ if (kv == null) {
+ kv = commitedTable.get(key);
+ }
+
if (kv != null) {
return kv.getValue();
} else {
throw new Error("Not all Key Values Match Arbitrator.");
}
- KeyValue kv = speculativeTable.get(key);
+ KeyValue kv = pendingTransSpeculativeTable.get(key);
+
+ if (kv == null) {
+ kv = speculativeTable.get(key);
+ }
+
if (kv == null) {
kv = commitedTable.get(key);
}
// Add the pending transaction to the queue
pendingTransQueue.add(pendingTransBuild);
+ for (int i = lastSeenPendingTransactionSpeculateIndex; i < pendingTransQueue.size(); i++) {
+ PendingTransaction pt = pendingTransQueue.get(i);
+
+ if (pt.evaluateGuard(commitedTable, speculativeTable, pendingTransSpeculativeTable)) {
+
+ lastSeenPendingTransactionSpeculateIndex = i;
+
+ for (KeyValue kv : pt.getKVUpdates()) {
+ pendingTransSpeculativeTable.put(kv.getKey(), kv);
+ }
+
+ }
+ }
+
+
// Delete since already inserted
pendingTransBuild = new PendingTransaction();
pendingTransBuild.addKV(kv);
}
- public void update() throws ServerException {
-
+ public void update() throws ServerException {
Slot[] newslots = cloud.getSlots(sequencenumber + 1);
-
validateandupdate(newslots, false);
-
if (!pendingTransQueue.isEmpty()) {
+ System.out.println("Full Update");
+
// We have a pending transaction so do full insertion
while (!pendingTransQueue.isEmpty()) {
}
}
- public boolean createNewKey(IoTString keyName, long machineId) throws ServerException {
+ public boolean createNewKey(IoTString keyName, long machineId) throws ServerException {
while (true) {
if (arbitratorTable.get(keyName) != null) {
resizethreshold = resize_lower - 1 + random.nextInt(numslots - resize_lower);
}
- private boolean tryput(PendingTransaction pendingTrans, boolean resize) throws ServerException {
+ private boolean tryput(PendingTransaction pendingTrans, boolean resize) throws ServerException {
Slot s = new Slot(this, sequencenumber + 1, localmachineid, buffer.getSlot(sequencenumber).getHMAC());
int newsize = 0;
return doSendSlotsAndInsert(s, insertedTrans, resize, newsize);
}
- private boolean tryput(IoTString keyName, long arbMachineid, boolean resize) throws ServerException {
+ private boolean tryput(IoTString keyName, long arbMachineid, boolean resize) throws ServerException {
Slot s = new Slot(this, sequencenumber + 1, localmachineid, buffer.getSlot(sequencenumber).getHMAC());
int newsize = 0;
if (liveslotcount > resizethreshold) {
int max = 0;
if (resize)
max = newsize;
+
Slot[] array = cloud.putSlot(s, max);
if (array == null) {
array = new Slot[] {s};
rejectedmessagelist.clear();
} else {
- if (array.length == 0)
- throw new Error("Server Error: Did not send any slots");
+ // if (array.length == 0)
+ // throw new Error("Server Error: Did not send any slots");
rejectedmessagelist.add(s.getSequenceNumber());
inserted = false;
}
- validateandupdate(array, true);
+ if (array.length != 0) {
+ validateandupdate(array, true);
+ }
+
return inserted;
}
sequencenumber = newslots[newslots.length - 1].getSequenceNumber();
// Process all on key value pairs
- proccessAllNewCommits();
+ boolean didCommitOrSpeculate = proccessAllNewCommits();
// Go through all uncommitted transactions and kill the ones that are dead
deleteDeadUncommittedTransactions();
// Speculate on key value pairs
- createSpeculativeTable();
+ didCommitOrSpeculate |= createSpeculativeTable();
+
+ createPendingTransactionSpeculativeTable(didCommitOrSpeculate);
}
- public void proccessAllNewCommits() {
+ public boolean proccessAllNewCommits() {
// Process only if there are commit
if (newCommitMap.keySet().size() == 0) {
- return;
+ return false;
}
List<Long> commitSeqNums = new ArrayList<Long>(newCommitMap.keySet());
// Sort from oldest to newest commit
Collections.sort(commitSeqNums);
+ boolean didProcessNewCommit = false;
+
// Go through each new commit one by one
for (Long entrySeqNum : commitSeqNums) {
Commit entry = newCommitMap.get(entrySeqNum);
- long lastCommitSeenSeqNum = 0;
+ long lastCommitSeenSeqNum = -1;
if (lastCommitSeenSeqNumMap.get(entry.getTransArbitrator()) != null) {
lastCommitSeenSeqNum = lastCommitSeenSeqNumMap.get(entry.getTransArbitrator());
}
}
- // // Remove any old commits
- // for (Iterator<Map.Entry<Long, Commit>> i = commitMap.entrySet().iterator(); i.hasNext();) {
- // Commit prevCommit = i.next().getValue();
- // prevCommit.updateLiveKeys(entry.getkeyValueUpdateSet());
-
- // if (!prevCommit.isLive()) {
- // i.remove();
- // }
- // }
-
- // Remove any old commits
- // for (Iterator<Map.Entry<Long, Commit>> i = commitMap.entrySet().iterator(); i.hasNext();) {
- // Commit prevCommit = i.next().getValue();
-
- // if (prevCommit.getTransArbitrator() != entry.getTransArbitrator()) {
- // continue;
- // }
-
- // prevCommit.updateLiveKeys(entry.getkeyValueUpdateSet());
-
- // if (!prevCommit.isLive()) {
- // i.remove();
- // }
- // }
-
-
// Add the new commit
commitMap.put(entry.getTransSequenceNumber(), entry);
lastCommitSeenSeqNumMap.put(entry.getTransArbitrator(), entry.getTransSequenceNumber());
+ didProcessNewCommit = true;
// Update the committed table list
for (KeyValue kv : entry.getkeyValueUpdateSet()) {
// Clear the new commits storage so we can use it later
newCommitMap.clear();
+
+ return didProcessNewCommit;
}
private void deleteDeadUncommittedTransactions() {
}
}
- private void createSpeculativeTable() {
-
+ private boolean createSpeculativeTable() {
if (uncommittedTransactionsMap.keySet().size() == 0) {
- // speculativeTable = commitedTable; // Ok that they are the same object
- return;
+ return false;
}
Map<IoTString, KeyValue> speculativeTableTmp = new HashMap<IoTString, KeyValue>();
speculativeTable.put(key, speculativeTableTmp.get(key));
}
- // speculativeTable = speculativeTableTmp;
+ return true;
+ }
+
+ private void createPendingTransactionSpeculativeTable(boolean didCommitOrSpeculate) {
+
+ if (didCommitOrSpeculate) {
+ pendingTransSpeculativeTable.clear();
+ lastSeenPendingTransactionSpeculateIndex = 0;
+
+ int index = 0;
+ for (PendingTransaction pt : pendingTransQueue) {
+ if (pt.evaluateGuard(commitedTable, speculativeTable, pendingTransSpeculativeTable)) {
+
+ lastSeenPendingTransactionSpeculateIndex = index;
+ index++;
+
+ for (KeyValue kv : pt.getKVUpdates()) {
+ pendingTransSpeculativeTable.put(kv.getKey(), kv);
+ }
+
+ }
+ }
+ }
}
private int expectedsize, currmaxsize;
if (machineid == localmachineid) {
if (lastmsgseqnum != seqnum && !acceptupdatestolocal)
- throw new Error("Server Error: Mismatch on local machine sequence number");
+ throw new Error("Server Error: Mismatch on local machine sequence number, needed: " + seqnum + " got: " + lastmsgseqnum);
} else {
if (lastmsgseqnum > seqnum)
throw new Error("Server Error: Rollback on remote machine sequence number");
throw new Error("Server Error: Invalid HMAC Chain" + currslot + " " + prevslot);
}
}
-}
+}
\ No newline at end of file
public class Test {
- public static final int NUMBER_OF_TESTS = 1000;
+ public static final int NUMBER_OF_TESTS = 15;
public static void main(String[] args) throws ServerException {
if (args[0].equals("2")) {
test6();
} else if (args[0].equals("7")) {
test7();
+ } else if (args[0].equals("8")) {
+ test8();
+ } else if (args[0].equals("9")) {
+ test9();
}
- // else if (args[0].equals("8")) {
- // test8();
- // } else if (args[0].equals("9")) {
- // test9();
- // }
}
// static void test9() throws ServerException {
// }
// }
+ static void test9() {
+
+ boolean foundError = false;
+
+ // Setup the 2 clients
+ Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
+
+ while (true) {
+ try {
+ t1.initTable();
+ break;
+ } catch (Exception e) {}
+ }
+
+ Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
+
+ while (true) {
+ try {
+ t2.update();
+ break;
+ } catch (Exception e) {}
+ }
+
+ // Make the Keys
+ System.out.println("Setting up keys");
+ for (int i = 0; i < 4; i++) {
+ String a = "a" + i;
+ String b = "b" + i;
+ String c = "c" + i;
+ String d = "d" + i;
+ IoTString ia = new IoTString(a);
+ IoTString ib = new IoTString(b);
+ IoTString ic = new IoTString(c);
+ IoTString id = new IoTString(d);
+ while (true) {
+ try {
+ t1.createNewKey(ia, 321);
+ break;
+ } catch (Exception e) {}
+ }
+
+ while (true) {
+ try {
+ t1.createNewKey(ib, 351);
+ break;
+ } catch (Exception e) {}
+ }
+
+ while (true) {
+ try {
+ t2.createNewKey(ic, 321);
+ break;
+ } catch (Exception e) {}
+ }
+
+ while (true) {
+ try {
+ t2.createNewKey(id, 351);
+ break;
+ } catch (Exception e) {}
+ }
+ }
+
+ // Do Updates for the keys
+ System.out.println("Setting Key-Values...");
+
+ System.out.println("Setting b...");
+ for (int t = 0; t < NUMBER_OF_TESTS; t++) {
+ for (int i = 0; i < 4; i++) {
+ String keyB = "b" + i;
+ String valueB = "b" + (i + t);
+
+ IoTString iKeyB = new IoTString(keyB);
+ IoTString iValueB = new IoTString(valueB);
+
+ try {
+ t1.startTransaction();
+ t1.getSpeculativeAtomic(iKeyB);
+ t1.addKV(iKeyB, iValueB);
+ t1.commitTransaction();
+ System.out.println("Server Success");
+ } catch (Exception e) {
+ System.out.println("Server Fail");
+ }
+
+ }
+ }
+
+ System.out.println("Checking b");
+ for (int i = 0; i < 4; i++) {
+
+ String keyB = "b" + i;
+ String valueB = "b" + (i + NUMBER_OF_TESTS - 1);
+ IoTString iKeyB = new IoTString(keyB);
+ IoTString iValueB = new IoTString(valueB);
+
+ IoTString testValB1 = t1.getSpeculative(iKeyB);
+ IoTString testValB2 = t2.getSpeculative(iKeyB);
+
+ if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyB + " " + testValB1);
+ foundError = true;
+ }
+
+ if ((testValB2 != null)) {
+ System.out.println("Key-Value t2 incorrect: " + keyB + " " + testValB2);
+ foundError = true;
+ }
+ }
+
+ System.out.println("Setting c...");
+ for (int t = 0; t < NUMBER_OF_TESTS; t++) {
+ for (int i = 0; i < 4; i++) {
+ String keyC = "c" + i;
+ String valueC = "c" + (i + t);
+
+ IoTString iKeyC = new IoTString(keyC);
+ IoTString iValueC = new IoTString(valueC);
+
+ try {
+ t2.startTransaction();
+ t2.getSpeculativeAtomic(iKeyC);
+ t2.addKV(iKeyC, iValueC);
+ t2.commitTransaction();
+ System.out.println("Server Success");
+ } catch (Exception e) {
+ System.out.println("Server Fail");
+ }
+
+ }
+ }
+
+ System.out.println("Checking c");
+ for (int i = 0; i < 4; i++) {
+ String keyC = "c" + i;
+ String valueC = "c" + (i + NUMBER_OF_TESTS - 1);
+ IoTString iKeyC = new IoTString(keyC);
+ IoTString iValueC = new IoTString(valueC);
+
+ IoTString testValC1 = t1.getSpeculative(iKeyC);
+ IoTString testValC2 = t2.getSpeculative(iKeyC);
+
+ if ((testValC1 != null)) {
+ System.out.println("Key-Value t1 incorrect: " + keyC + " " + testValC1);
+ foundError = true;
+ }
+
+ if ((testValC2 == null) || (testValC2.equals(iValueC) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyC + " " + testValC2);
+ foundError = true;
+ }
+ }
+
+ System.out.println("Setting a and b...");
+ for (int t = 0; t < NUMBER_OF_TESTS; t++) {
+ for (int i = 0; i < 4; i++) {
+ String keyA = "a" + i;
+ String keyD = "d" + i;
+ String valueA = "a" + (i + t);
+ String valueD = "d" + (i + t);
+
+ IoTString iKeyA = new IoTString(keyA);
+ IoTString iKeyD = new IoTString(keyD);
+ IoTString iValueA = new IoTString(valueA);
+ IoTString iValueD = new IoTString(valueD);
+
+ try {
+ t1.startTransaction();
+ t1.addKV(iKeyA, iValueA);
+ t1.commitTransaction();
+ System.out.println("Server Success");
+
+ } catch (Exception e) {
+ System.out.println("Server Fail");
+ }
+
+ try {
+ t2.startTransaction();
+ t2.addKV(iKeyD, iValueD);
+ t2.commitTransaction();
+ System.out.println("Server Success");
+
+ } catch (Exception e) {
+ System.out.println("Server Fail");
+ }
+
+ }
+ }
+
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+ System.out.println("Updating Clients...");
+
+ try {
+ Thread.sleep(3000);
+ } catch (Exception e) {
+
+ }
+
+ System.out.println("Updating Clients... T1 first");
+ while (true) {
+ try {
+ t1.update();
+ break;
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Fail");
+ }
+ }
+
+ System.out.println("Updating Clients... T2 first");
+ while (true) {
+ try {
+ t2.update();
+ break;
+ } catch (Exception e) {
+ System.out.println("Fail");
+ }
+ }
+
+ System.out.println("Updating Clients... T1 second");
+ while (true) {
+ try {
+ t1.update();
+ break;
+ } catch (Exception e) {
+ System.out.println("Fail");
+ }
+ }
+
+ System.out.println("Updating Clients... T2 second");
+ while (true) {
+ try {
+ t2.update();
+ break;
+ } catch (Exception e) {
+ System.out.println("Fail");
+ }
+ }
+
+ System.out.println("Checking Key-Values...");
+ for (int i = 0; i < 4; i++) {
+
+ String keyA = "a" + i;
+ String keyB = "b" + i;
+ String keyC = "c" + i;
+ String keyD = "d" + i;
+ String valueA = "a" + (i + NUMBER_OF_TESTS - 1);
+ String valueB = "b" + (i + NUMBER_OF_TESTS - 1);
+ String valueC = "c" + (i + NUMBER_OF_TESTS - 1);
+ String valueD = "d" + (i + NUMBER_OF_TESTS - 1);
+
+ IoTString iKeyA = new IoTString(keyA);
+ IoTString iKeyB = new IoTString(keyB);
+ IoTString iKeyC = new IoTString(keyC);
+ IoTString iKeyD = new IoTString(keyD);
+ IoTString iValueA = new IoTString(valueA);
+ IoTString iValueB = new IoTString(valueB);
+ IoTString iValueC = new IoTString(valueC);
+ IoTString iValueD = new IoTString(valueD);
+
+
+ IoTString testValA1 = t1.getCommitted(iKeyA);
+ IoTString testValB1 = t1.getCommitted(iKeyB);
+ IoTString testValC1 = t1.getCommitted(iKeyC);
+ IoTString testValD1 = t1.getCommitted(iKeyD);
+
+ IoTString testValA2 = t2.getCommitted(iKeyA);
+ IoTString testValB2 = t2.getCommitted(iKeyB);
+ IoTString testValC2 = t2.getCommitted(iKeyC);
+ IoTString testValD2 = t2.getCommitted(iKeyD);
+
+ if ((testValA1 == null) || (testValA1.equals(iValueA) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyA + " " + testValA1 + " " + iValueA);
+ foundError = true;
+ }
+
+ if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyB + " " + testValB1 + " " + iValueB);
+ foundError = true;
+ }
+
+ if ((testValC1 == null) || (testValC1.equals(iValueC) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyC + " " + testValC1 + " " + iValueC);
+ foundError = true;
+ }
+
+ if ((testValD1 == null) || (testValD1.equals(iValueD) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyD + " " + testValD1 + " " + iValueD);
+ foundError = true;
+ }
+
+ if ((testValA2 == null) || (testValA2.equals(iValueA) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyA + " " + testValA2 + " " + iValueA);
+ foundError = true;
+ }
+
+ if ((testValB2 == null) || (testValB2.equals(iValueB) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyB + " " + testValB2 + " " + iValueB);
+ foundError = true;
+ }
+
+ if ((testValC2 == null) || (testValC2.equals(iValueC) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyC + " " + testValC2 + " " + iValueC);
+ foundError = true;
+ }
+
+ if ((testValD2 == null) || (testValD2.equals(iValueD) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyD + " " + testValD2 + " " + iValueD);
+ foundError = true;
+ }
+ }
+
+ if (foundError) {
+ System.out.println("Found Errors...");
+ } else {
+ System.out.println("No Errors Found...");
+ }
+ }
+
+ static void test8() {
+ boolean foundError = false;
+
+
+ // Setup the 2 clients
+ Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
+ while (true) {
+ try {
+ t1.initTable();
+ break;
+ } catch (Exception e) {}
+ }
+
+ Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
+ while (true) {
+ try {
+ t2.update();
+ break;
+ } catch (Exception e) {}
+ }
+
+ // Make the Keys
+ System.out.println("Setting up keys");
+ for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+ System.out.println(i);
+
+ String a = "a" + i;
+ String b = "b" + i;
+ String c = "c" + i;
+ String d = "d" + i;
+ IoTString ia = new IoTString(a);
+ IoTString ib = new IoTString(b);
+ IoTString ic = new IoTString(c);
+ IoTString id = new IoTString(d);
+
+ while (true) {
+ try {
+ t1.createNewKey(ia, 321);
+ break;
+ } catch (Exception e) {}
+ }
+
+ while (true) {
+ try {
+ t1.createNewKey(ib, 351);
+ break;
+ } catch (Exception e) {}
+ }
+
+ while (true) {
+ try {
+ t2.createNewKey(ic, 321);
+ break;
+ } catch (Exception e) {}
+ }
+
+ while (true) {
+ try {
+ t2.createNewKey(id, 351);
+ break;
+ } catch (Exception e) {}
+ }
+ }
+
+ // Do Updates for the keys
+ System.out.println("Setting Key-Values...");
+ for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+ System.out.println(i);
+ String keyA = "a" + i;
+ String keyB = "b" + i;
+ String keyC = "c" + i;
+ String keyD = "d" + i;
+ String valueA = "a" + i;
+ String valueB = "b" + i;
+ String valueC = "c" + i;
+ String valueD = "d" + i;
+
+ IoTString iKeyA = new IoTString(keyA);
+ IoTString iKeyB = new IoTString(keyB);
+ IoTString iKeyC = new IoTString(keyC);
+ IoTString iKeyD = new IoTString(keyD);
+ IoTString iValueA = new IoTString(valueA);
+ IoTString iValueB = new IoTString(valueB);
+ IoTString iValueC = new IoTString(valueC);
+ IoTString iValueD = new IoTString(valueD);
+
+
+ String keyAPrev = "a" + (i - 1);
+ String keyBPrev = "b" + (i - 1);
+ String keyCPrev = "c" + (i - 1);
+ String keyDPrev = "d" + (i - 1);
+ String valueAPrev = "a" + (i - 1);
+ String valueBPrev = "b" + (i - 1);
+ String valueCPrev = "c" + (i - 1);
+ String valueDPrev = "d" + (i - 1);
+
+ IoTString iKeyAPrev = new IoTString(keyAPrev);
+ IoTString iKeyBPrev = new IoTString(keyBPrev);
+ IoTString iKeyCPrev = new IoTString(keyCPrev);
+ IoTString iKeyDPrev = new IoTString(keyDPrev);
+ IoTString iValueAPrev = new IoTString(valueAPrev);
+ IoTString iValueBPrev = new IoTString(valueBPrev);
+ IoTString iValueCPrev = new IoTString(valueCPrev);
+ IoTString iValueDPrev = new IoTString(valueDPrev);
+
+ try {
+ t1.startTransaction();
+ if (i != 0) {
+ IoTString tmp = t1.getSpeculative(iKeyAPrev);
+ if ((tmp == null) || !tmp.equals(iValueAPrev)) {
+ System.out.println("Key a Error: " + i);
+ foundError = true;
+ }
+ }
+ t1.addKV(iKeyA, iValueA);
+ t1.commitTransaction();
+ } catch (Exception e) {
+ System.out.println("Connection Failure!");
+ }
+
+ try {
+ t1.startTransaction();
+ if (i != 0) {
+ IoTString tmp = t1.getSpeculative(iKeyBPrev);
+ if ((tmp == null) || !tmp.equals(iValueBPrev)) {
+ System.out.println("Key b Error: " + i);
+ foundError = true;
+ }
+ }
+ t1.addKV(iKeyB, iValueB);
+ t1.commitTransaction();
+ } catch (Exception e) {
+ System.out.println("Connection Failure!");
+ }
+
+ try {
+ t2.startTransaction();
+ if (i != 0) {
+ IoTString tmp = t2.getSpeculative(iKeyCPrev);
+ if ((tmp == null) || !tmp.equals(iValueCPrev)) {
+ System.out.println("Key c Error: " + i);
+ foundError = true;
+ }
+ }
+ t2.addKV(iKeyC, iValueC);
+ t2.commitTransaction();
+ } catch (Exception e) {
+ System.out.println("Connection Failure!");
+ }
+
+ try {
+ t2.startTransaction();
+ if (i != 0) {
+ IoTString tmp = t2.getSpeculative(iKeyDPrev);
+ if ((tmp == null) || !tmp.equals(iValueDPrev)) {
+ System.out.println("Key d Error: " + i);
+ foundError = true;
+ }
+ }
+ t2.addKV(iKeyD, iValueD);
+ t2.commitTransaction();
+ } catch (Exception e) {
+ System.out.println("Connection Failure!");
+ }
+ }
+
+ while (true) {
+ try {
+ t1.update();
+ break;
+ } catch (Exception e) {
+
+ }
+ }
+
+ while (true) {
+ try {
+ t2.update();
+ break;
+ } catch (Exception e) {
+
+ }
+ }
+
+ while (true) {
+ try {
+ t1.update();
+ break;
+ } catch (Exception e) {
+
+ }
+ }
+
+ while (true) {
+ try {
+ t2.update();
+ break;
+ } catch (Exception e) {
+
+ }
+ }
+
+
+ System.out.println("Checking Key-Values...");
+ for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+
+ String keyA = "a" + i;
+ String keyB = "b" + i;
+ String keyC = "c" + i;
+ String keyD = "d" + i;
+ String valueA = "a" + i;
+ String valueB = "b" + i;
+ String valueC = "c" + i;
+ String valueD = "d" + i;
+
+ IoTString iKeyA = new IoTString(keyA);
+ IoTString iKeyB = new IoTString(keyB);
+ IoTString iKeyC = new IoTString(keyC);
+ IoTString iKeyD = new IoTString(keyD);
+ IoTString iValueA = new IoTString(valueA);
+ IoTString iValueB = new IoTString(valueB);
+ IoTString iValueC = new IoTString(valueC);
+ IoTString iValueD = new IoTString(valueD);
+
+
+ IoTString testValA1 = t1.getCommitted(iKeyA);
+ IoTString testValB1 = t1.getCommitted(iKeyB);
+ IoTString testValC1 = t1.getCommitted(iKeyC);
+ IoTString testValD1 = t1.getCommitted(iKeyD);
+
+ IoTString testValA2 = t2.getCommitted(iKeyA);
+ IoTString testValB2 = t2.getCommitted(iKeyB);
+ IoTString testValC2 = t2.getCommitted(iKeyC);
+ IoTString testValD2 = t2.getCommitted(iKeyD);
+
+ if ((testValA1 == null) || (testValA1.equals(iValueA) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyA);
+ foundError = true;
+ }
+
+ if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyB);
+ foundError = true;
+ }
+
+ if ((testValC1 == null) || (testValC1.equals(iValueC) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyC);
+ foundError = true;
+ }
+
+ if ((testValD1 == null) || (testValD1.equals(iValueD) == false)) {
+ System.out.println("Key-Value t1 incorrect: " + keyD);
+ foundError = true;
+ }
+
+
+ if ((testValA2 == null) || (testValA2.equals(iValueA) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyA + " " + testValA2);
+ foundError = true;
+ }
+
+ if ((testValB2 == null) || (testValB2.equals(iValueB) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyB + " " + testValB2);
+ foundError = true;
+ }
+
+ if ((testValC2 == null) || (testValC2.equals(iValueC) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyC + " " + testValC2);
+ foundError = true;
+ }
+
+ if ((testValD2 == null) || (testValD2.equals(iValueD) == false)) {
+ System.out.println("Key-Value t2 incorrect: " + keyD + " " + testValD2);
+ foundError = true;
+ }
+ }
+
+ if (foundError) {
+ System.out.println("Found Errors...");
+ } else {
+ System.out.println("No Errors Found...");
+ }
+ }
+
static void test7() throws ServerException {
long startTime = 0;