Changed way Guard works, Sped up code
authorAli Younis <ayounis@uci.edu>
Sat, 31 Dec 2016 09:32:22 +0000 (01:32 -0800)
committerAli Younis <ayounis@uci.edu>
Sat, 31 Dec 2016 09:32:22 +0000 (01:32 -0800)
version2/src/java/iotcloud/CloudComm.java
version2/src/java/iotcloud/Guard.java [deleted file]
version2/src/java/iotcloud/KeyValue.java
version2/src/java/iotcloud/PendingTransaction.java
version2/src/java/iotcloud/ServerException.java [new file with mode: 0644]
version2/src/java/iotcloud/SlotBuffer.java
version2/src/java/iotcloud/Table.java
version2/src/java/iotcloud/Test.java
version2/src/java/iotcloud/Transaction.java

index 33e3d00..2db5ad9 100644 (file)
@@ -90,7 +90,7 @@ class CloudComm {
                return new URL(urlstr);
        }
 
-       public void setSalt() {
+       public void setSalt() throws ServerException{
                try {
                        salt = new byte[SALT_SIZE];
                        random.nextBytes(salt);
@@ -111,7 +111,7 @@ class CloudComm {
                        }
                } catch (Exception e) {
                        e.printStackTrace();
-                       throw new Error("Failed setting salt");
+                       throw new ServerException("Failed setting salt");
                }
                initCrypt();
        }
@@ -137,7 +137,7 @@ class CloudComm {
         * numbers.
         */
 
-       Slot[] putSlot(Slot slot, int max) {
+       Slot[] putSlot(Slot slot, int max)  throws ServerException{
                try {
                        if (salt == null) {
                                getSalt();
@@ -172,16 +172,17 @@ class CloudComm {
                                throw new Error("Bad response to putslot");
                } catch (Exception e) {
                        e.printStackTrace();
-                       throw new Error("putSlot failed");
+                       throw new ServerException("putSlot failed");
                }
        }
 
+
        /**
         * Request the server to send all slots with the given
         * sequencenumber or newer.
         */
 
-       Slot[] getSlots(long sequencenumber) {
+       Slot[] getSlots(long sequencenumber) throws ServerException {
                try {
                        if (salt == null) {
                                getSalt();
@@ -205,7 +206,7 @@ class CloudComm {
                                return processSlots(dis);
                } catch (Exception e) {
                        e.printStackTrace();
-                       throw new Error("getSlots failed");
+                       throw new ServerException("getSlots failed");
                }
        }
 
diff --git a/version2/src/java/iotcloud/Guard.java b/version2/src/java/iotcloud/Guard.java
deleted file mode 100644 (file)
index f768b7f..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-package iotcloud;
-
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collection;
-import java.util.List;
-import java.util.ArrayList;
-
-import java.nio.ByteBuffer;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import java.lang.NullPointerException;
-
-
-class Guard {
-
-    static final byte Equal = 1;
-    static final byte NotEqual = 2;
-    private IoTString booleanExpression;
-    private List<KeyValue> keyValsNeeded = null;
-
-    public Guard() {
-        booleanExpression = null;
-    }
-
-    public Guard(IoTString _booleanExpression) {
-        booleanExpression = _booleanExpression;
-    }
-
-    /**
-     * Create an equality expression for a key value.
-     *
-     */
-    public static String createExpression(IoTString keyName, IoTString keyValue, byte op) {
-        if (op == Equal) {
-            return keyName.toString() + "=='" + keyValue.toString() + "'";
-        } else if (op == NotEqual) {
-            return keyName.toString() + "!='" + keyValue.toString() + "'";
-        }
-
-        // Unrecognized op
-        return null;
-    }
-
-    /**
-     * Add a boolean expression to the guard.
-     *
-     */
-    public void setGuardExpression(String expr) {
-        booleanExpression = new IoTString(expr);
-    }
-
-    /**
-     * Evaluate the guard expression for a given set of key value pairs.
-     *
-     */
-    public boolean evaluate(Collection<KeyValue> kvSet) throws ScriptException, NullPointerException {
-
-        // There are no conditions to evaluate
-        if (booleanExpression == null) {
-            return true;
-        }
-
-        ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
-
-        if (keyValsNeeded == null) {
-            keyValsNeeded = new ArrayList<KeyValue>();
-
-            String booleanExprString = booleanExpression.toString();
-            for (KeyValue kv : kvSet) {
-                if (booleanExprString.contains(kv.getKey().toString())) {
-                    keyValsNeeded.add(kv);
-                }
-            }
-        }
-
-        // All the current key value pairs that we need to evaluate the condition
-        // String[] variables = new String[kvSet.size()];
-
-        // Fill the variables array
-        // int i = 0;
-        // for (KeyValue kv : kvSet) {
-        // for (KeyValue kv : keyValsNeeded) {
-        //     variables[i] = kv.getKey() + " ='" + kv.getValue() + "'";
-        //     i++;
-        // }
-
-        String varEval = "";
-        for (KeyValue kv : keyValsNeeded) {
-            varEval += "var " + kv.getKey() + " ='" + kv.getValue() + "'; \n";
-        }
-
-        varEval += booleanExpression.toString();
-
-        // Prep the evaluation engine (script engine)
-
-        // for (String s : variables) {
-        //     engine.eval(s);
-        // }
-        // engine.eval(varEval);
-
-
-
-        // boolean engineEval = (Boolean)engine.eval(booleanExpression.toString());
-        boolean engineEval = false;
-
-        try {
-            engineEval = (Boolean)engine.eval(varEval);
-        } catch (Exception e) {
-            // If there was an error then the script evaluated to false 
-            engineEval = false;
-        }
-
-        // Evaluate the guard condition
-        // return 1 == (Integer)engine.eval(booleanExpression.toString());
-        return engineEval;
-    }
-
-    /**
-     * Get the size of the guard condition
-     *
-     */
-    public int getSize() {
-
-        if (booleanExpression == null) {
-            return Integer.BYTES;
-        }
-
-        return Integer.BYTES + booleanExpression.length();
-    }
-
-    public void encode(ByteBuffer bb) {
-        if (booleanExpression == null) {
-            bb.putInt(0);
-        } else {
-            bb.putInt(booleanExpression.length());
-            bb.put(booleanExpression.internalBytes());
-        }
-    }
-
-    static Guard decode(ByteBuffer bb) {
-        int exprLength = bb.getInt();
-
-        if (exprLength != 0) {
-            byte[] expr = new byte[exprLength];
-            bb.get(expr);
-            return new Guard(IoTString.shallow(expr));
-        }
-        return new Guard(null);
-    }
-
-    public Guard getCopy() {
-
-        if (booleanExpression == null) {
-            return new Guard(null);
-        }
-
-        return new Guard(IoTString.shallow(booleanExpression.internalBytes()));
-    }
-
-}
\ No newline at end of file
index 79b9e60..cd4821a 100644 (file)
@@ -28,24 +28,45 @@ class KeyValue { /*extends Entry */
                int keylength = bb.getInt();
                int valuelength = bb.getInt();
                byte[] key = new byte[keylength];
-               byte[] value = new byte[valuelength];
                bb.get(key);
-               bb.get(value);
-               return new KeyValue(IoTString.shallow(key), IoTString.shallow(value));
+
+               if (valuelength != 0) {
+                       byte[] value = new byte[valuelength];
+                       bb.get(value);
+                       return new KeyValue(IoTString.shallow(key), IoTString.shallow(value));
+               }
+
+               return new KeyValue(IoTString.shallow(key), null);
        }
 
        public void encode(ByteBuffer bb) {
                bb.putInt(key.length());
-               bb.putInt(value.length());
+
+               if (value != null) {
+                       bb.putInt(value.length());
+               } else {
+                       bb.putInt(0);
+               }
+
                bb.put(key.internalBytes());
-               bb.put(value.internalBytes());
+
+               if (value != null) {
+                       bb.put(value.internalBytes());
+               }
        }
 
        public int getSize() {
-               return 2 * Integer.BYTES + key.length() + value.length();
+               if (value != null) {
+                       return 2 * Integer.BYTES + key.length() + value.length();
+               }
+
+               return 2 * Integer.BYTES + key.length();
        }
 
        public String toString() {
+               if (value == null) {
+                       return "null";
+               }
                return value.toString();
        }
 
index 24c4ad7..f80845f 100644 (file)
@@ -9,16 +9,13 @@ import java.lang.NullPointerException;
 
 class PendingTransaction {
 
-    static final byte Equal = Guard.Equal;
-    static final byte NotEqual = Guard.NotEqual;
-
-    private Set<KeyValue> keyValueUpdateSet;
-    private Guard guard;
+    private Set<KeyValue> keyValueUpdateSet = null;
+    private Set<KeyValue> keyValueGuardSet = null;
     private long arbitrator = -1;
 
     public PendingTransaction() {
         keyValueUpdateSet = new HashSet<KeyValue>();
-        guard = new Guard();
+        keyValueGuardSet = new HashSet<KeyValue>();
     }
 
     /**
@@ -48,6 +45,20 @@ class PendingTransaction {
         keyValueUpdateSet.add(newKV);
     }
 
+
+    /**
+     * Add a new key value to the guard set
+     *
+     */
+    public void addKVGuard(KeyValue newKV) {
+        // Add the key to the hash set
+        keyValueGuardSet.add(newKV);
+    }
+
+    /**
+     * Checks if the arbitrator is the same
+     *
+     */
     public boolean checkArbitrator(long arb) {
         if (arbitrator == -1) {
             arbitrator = arb;
@@ -57,6 +68,10 @@ class PendingTransaction {
         return arb == arbitrator;
     }
 
+    /**
+     * Get the transaction arbitrator
+     *
+     */
     public long getArbitrator() {
         return arbitrator;
     }
@@ -69,45 +84,12 @@ class PendingTransaction {
         return keyValueUpdateSet;
     }
 
-    /**
-    * Get the guard
-    *
-    */
-    public Guard getGuard() {
-        return guard;
-    }
-
-    /**
-     * Add a guard to this transaction
-     *
-     */
-    public void addGuard(Guard _guard) {
-        guard = _guard;
-    }
 
     /**
-     * Evaluate the guard expression for a given transaction using a set of key value pairs.
-     *
-     */
-    public boolean evaluate(Set<KeyValue> kvSet) throws ScriptException, NullPointerException {
-
-        // Evaluate the guard using the current KV Set
-        return guard.evaluate(kvSet);
-    }
-
-    /**
-     * Add a boolean expression to the guard.
-     *
-     */
-    public void setGuardExpression(String expr) {
-        guard.setGuardExpression(expr);
-    }
-
-    /**
-     * Trampoline static method.
-     *
-     */
-    public static String createExpression(IoTString keyName, IoTString keyValue, byte op) {
-        return Guard.createExpression(keyName, keyValue, op);
+       * Get the key value update set
+       *
+       */
+    public Set<KeyValue> getKVGuard() {
+        return keyValueGuardSet;
     }
 }
\ No newline at end of file
diff --git a/version2/src/java/iotcloud/ServerException.java b/version2/src/java/iotcloud/ServerException.java
new file mode 100644 (file)
index 0000000..6d35c43
--- /dev/null
@@ -0,0 +1,8 @@
+package iotcloud;
+
+public class ServerException extends Exception {
+    
+    public ServerException(String message) {
+        super(message);
+    }
+}
index ba6c3de..716d0f2 100644 (file)
@@ -33,6 +33,7 @@ class SlotBuffer {
        void resize(int newsize) {
                if (newsize == (array.length - 1))
                        return;
+
                Slot[] newarray = new Slot[newsize + 1];
                int currsize = size();
                int index = tail;
index d42679d..4f0fe95 100644 (file)
@@ -39,7 +39,7 @@ final public class Table {
        private TableStatus lastTableStatus;
        static final int FREE_SLOTS = 10; //number of slots that should be kept free
        static final int SKIP_THRESHOLD = 10;
-       private long liveslotcount = 0; 
+       private long liveslotcount = 0;
        private int chance;
        static final double RESIZE_MULTIPLE = 1.2;
        static final double RESIZE_THRESHOLD = 0.75;
@@ -49,12 +49,15 @@ final public class Table {
        private Random random = new Random();
        private long lastUncommittedTransaction = 0;
 
+       private int smallestTableStatusSeen = -1;
+       private int largestTableStatusSeen = -1;
+
        private PendingTransaction pendingTransBuild = null; // Pending Transaction used in building
        private Queue<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<IoTString, KeyValue> commitedTable = null; // Table of committed KV    
+       private Map<IoTString, Commit> committedMapByKey = null; // Table of committed KV
+       private Map<IoTString, KeyValue> commitedTable = null; // Table of committed KV
        private Map<IoTString, KeyValue> speculativeTable = null; // Table of speculative KV
        private Map<Long, Transaction> uncommittedTransactionsMap = null;
        private Map<IoTString, Long> arbitratorTable = null; // Table of arbitrators
@@ -103,12 +106,12 @@ final public class Table {
                lastAbortSeenSeqNumMap = new HashMap<Long, Long>();
        }
 
-       public void rebuild() {
+       public void rebuild() throws ServerException {
                Slot[] newslots = cloud.getSlots(sequencenumber + 1);
                validateandupdate(newslots, true);
        }
 
-       // TODO: delete method
+       // // TODO: delete method
        // public void printSlots() {
        //      long o = buffer.getOldestSeqNum();
        //      long n = buffer.getNewestSeqNum();
@@ -166,11 +169,59 @@ final public class Table {
                }
        }
 
+       public IoTString getCommittedAtomic(IoTString key) {
+               KeyValue kv = commitedTable.get(key);
+
+               if (arbitratorTable.get(key) == null) {
+                       throw new Error("Key not Found.");
+               }
+
+               // Make sure new key value pair matches the current arbitrator
+               if (!pendingTransBuild.checkArbitrator(arbitratorTable.get(key))) {
+                       // TODO: Maybe not throw en error
+                       throw new Error("Not all Key Values Match Arbitrator.");
+               }
+
+               if (kv != null) {
+                       pendingTransBuild.addKVGuard(new KeyValue(key, kv.getValue()));
+                       return kv.getValue();
+               } else {
+                       pendingTransBuild.addKVGuard(new KeyValue(key, null));
+                       return null;
+               }
+       }
+
+       public IoTString getSpeculativeAtomic(IoTString key) {
+
+               if (arbitratorTable.get(key) == null) {
+                       throw new Error("Key not Found.");
+               }
+
+               // Make sure new key value pair matches the current arbitrator
+               if (!pendingTransBuild.checkArbitrator(arbitratorTable.get(key))) {
+                       // TODO: Maybe not throw en error
+                       throw new Error("Not all Key Values Match Arbitrator.");
+               }
+
+               KeyValue kv = speculativeTable.get(key);
+               if (kv == null) {
+                       kv = commitedTable.get(key);
+               }
+
+               if (kv != null) {
+                       pendingTransBuild.addKVGuard(new KeyValue(key, kv.getValue()));
+                       return kv.getValue();
+               } else {
+                       pendingTransBuild.addKVGuard(new KeyValue(key, null));
+                       return null;
+               }
+       }
+
        public Long getArbitrator(IoTString key) {
                return arbitratorTable.get(key);
        }
 
-       public void initTable() {
+       public void initTable() throws ServerException {
                cloud.setSalt();//Set the salt
                Slot s = new Slot(this, 1, localmachineid);
                TableStatus status = new TableStatus(s, numslots);
@@ -204,7 +255,7 @@ final public class Table {
                pendingTransBuild = new PendingTransaction();
        }
 
-       public void commitTransaction() {
+       public void commitTransaction() throws ServerException {
 
                if (pendingTransBuild.getKVUpdates().size() == 0) {
                        // If no updates are made then there is no point inserting into the chain
@@ -214,6 +265,9 @@ final public class Table {
                // Add the pending transaction to the queue
                pendingTransQueue.add(pendingTransBuild);
 
+               // Delete since already inserted
+               pendingTransBuild = new PendingTransaction();
+
                while (!pendingTransQueue.isEmpty()) {
                        if (tryput( pendingTransQueue.peek(), false)) {
                                pendingTransQueue.poll();
@@ -230,85 +284,93 @@ final public class Table {
                // Make sure new key value pair matches the current arbitrator
                if (!pendingTransBuild.checkArbitrator(arbitratorTable.get(key))) {
                        // TODO: Maybe not throw en error
-                       throw new Error("Not all Key Values Match.");
+                       throw new Error("Not all Key Values Match Arbitrator.");
                }
 
                KeyValue kv = new KeyValue(key, value);
                pendingTransBuild.addKV(kv);
        }
 
-       public void addGuard(Guard guard) {
-               pendingTransBuild.addGuard(guard);
-       }
-
-       public void update() {
+       public void update()  throws ServerException {
 
                Slot[] newslots = cloud.getSlots(sequencenumber + 1);
 
                validateandupdate(newslots, false);
 
-               if (uncommittedTransactionsMap.keySet().size() > 0) {
 
-                       boolean doEnd = false;
-                       boolean needResize = false;
-                       while (!doEnd && (uncommittedTransactionsMap.keySet().size() > 0)) {
-                               boolean resize = needResize;
-                               needResize = false;
+               if (!pendingTransQueue.isEmpty()) {
+                       // We have a pending transaction so do full insertion
 
-                               Slot s = new Slot(this, sequencenumber + 1, localmachineid, buffer.getSlot(sequencenumber).getHMAC());
-                               int newsize = 0;
-                               if (liveslotcount > resizethreshold) {
-                                       resize = true; //Resize is forced
+                       while (!pendingTransQueue.isEmpty()) {
+                               if (tryput( pendingTransQueue.peek(), false)) {
+                                       pendingTransQueue.poll();
                                }
+                       }
+               } else {
+                       // We dont have a pending transaction so do minimal effort
+                       if (uncommittedTransactionsMap.keySet().size() > 0) {
+
+                               boolean doEnd = false;
+                               boolean needResize = false;
+                               while (!doEnd && (uncommittedTransactionsMap.keySet().size() > 0)) {
+                                       boolean resize = needResize;
+                                       needResize = false;
+
+                                       Slot s = new Slot(this, sequencenumber + 1, localmachineid, buffer.getSlot(sequencenumber).getHMAC());
+                                       int newsize = 0;
+                                       if (liveslotcount > resizethreshold) {
+                                               resize = true; //Resize is forced
+                                       }
 
-                               if (resize) {
-                                       newsize = (int) (numslots * RESIZE_MULTIPLE);
-                                       TableStatus status = new TableStatus(s, newsize);
-                                       s.addEntry(status);
-                               }
+                                       if (resize) {
+                                               newsize = (int) (numslots * RESIZE_MULTIPLE);
+                                               TableStatus status = new TableStatus(s, newsize);
+                                               s.addEntry(status);
+                                       }
 
-                               doRejectedMessages(s);
+                                       doRejectedMessages(s);
 
-                               ThreeTuple<Boolean, Boolean, Long> retTup = doMandatoryResuce(s, resize);
+                                       ThreeTuple<Boolean, Boolean, Long> retTup = doMandatoryResuce(s, resize);
 
-                               // Resize was needed so redo call
-                               if (retTup.getFirst()) {
-                                       needResize = true;
-                                       continue;
-                               }
+                                       // Resize was needed so redo call
+                                       if (retTup.getFirst()) {
+                                               needResize = true;
+                                               continue;
+                                       }
 
-                               // Extract working variables
-                               boolean seenliveslot = retTup.getSecond();
-                               long seqn = retTup.getThird();
+                                       // Extract working variables
+                                       boolean seenliveslot = retTup.getSecond();
+                                       long seqn = retTup.getThird();
 
-                               // Did need to arbitrate
-                               doEnd = !doArbitration(s);
+                                       // Did need to arbitrate
+                                       doEnd = !doArbitration(s);
 
-                               doOptionalRescue(s, seenliveslot, seqn, resize);
+                                       doOptionalRescue(s, seenliveslot, seqn, resize);
 
-                               int max = 0;
-                               if (resize) {
-                                       max = newsize;
-                               }
+                                       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");
-                                       rejectedmessagelist.add(s.getSequenceNumber());
-                                       doEnd = false;
-                               }
+                                       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");
+                                               rejectedmessagelist.add(s.getSequenceNumber());
+                                               doEnd = false;
+                                       }
 
-                               /* update data structure */
-                               validateandupdate(array, true);
+                                       /* update data structure */
+                                       validateandupdate(array, true);
+                               }
                        }
                }
        }
 
-       public boolean createNewKey(IoTString keyName, long machineId) {
+       public boolean createNewKey(IoTString keyName, long machineId)  throws ServerException {
 
                while (true) {
                        if (arbitratorTable.get(keyName) != null) {
@@ -332,7 +394,7 @@ final public class Table {
                resizethreshold = resize_lower - 1 + random.nextInt(numslots - resize_lower);
        }
 
-       private boolean tryput(PendingTransaction pendingTrans, boolean resize) {
+       private boolean tryput(PendingTransaction pendingTrans, boolean resize)  throws ServerException {
                Slot s = new Slot(this, sequencenumber + 1, localmachineid, buffer.getSlot(sequencenumber).getHMAC());
 
                int newsize = 0;
@@ -359,7 +421,6 @@ final public class Table {
                boolean seenliveslot = retTup.getSecond();
                long seqn = retTup.getThird();
 
-
                doArbitration(s);
 
                Transaction trans = new Transaction(s,
@@ -367,7 +428,7 @@ final public class Table {
                                                    localmachineid,
                                                    pendingTrans.getArbitrator(),
                                                    pendingTrans.getKVUpdates(),
-                                                   pendingTrans.getGuard());
+                                                   pendingTrans.getKVGuard());
                boolean insertedTrans = false;
                if (s.hasSpace(trans)) {
                        s.addEntry(trans);
@@ -378,7 +439,7 @@ final public class Table {
                return doSendSlotsAndInsert(s, insertedTrans, resize, newsize);
        }
 
-       private boolean tryput(IoTString keyName, long arbMachineid, boolean resize) {
+       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) {
@@ -403,7 +464,6 @@ final public class Table {
                boolean seenliveslot = retTup.getSecond();
                long seqn = retTup.getThird();
 
-
                doArbitration(s);
 
                NewKey newKey = new NewKey(s, keyName, arbMachineid);
@@ -498,21 +558,18 @@ final public class Table {
 
        private boolean doArbitration(Slot s) {
                // Arbitrate
-               Map speculativeTableTmp = new HashMap<IoTString, KeyValue>(commitedTable);
-
+               Map<IoTString, KeyValue> speculativeTableTmp = new HashMap<IoTString, KeyValue>();
                List<Long> transSeqNums = new ArrayList<Long>(uncommittedTransactionsMap.keySet());
 
                // Sort from oldest to newest
                Collections.sort(transSeqNums);
 
-
                boolean didNeedArbitration = false;
                for (Long transNum : transSeqNums) {
                        Transaction ut = uncommittedTransactionsMap.get(transNum);
 
-                       KeyValue keyVal = (KeyValue)(ut.getkeyValueUpdateSet().toArray())[0];
                        // Check if this machine arbitrates for this transaction
-                       if (arbitratorTable.get( keyVal.getKey() ) != localmachineid ) {
+                       if (ut.getArbitrator() != localmachineid ) {
                                continue;
                        }
 
@@ -521,25 +578,21 @@ final public class Table {
 
                        Entry newEntry = null;
 
-                       try {
-                               if ( ut.getGuard().evaluate(speculativeTableTmp.values())) {
-                                       // Guard evaluated as true
+                       if (ut.evaluateGuard(commitedTable, speculativeTableTmp)) {
+                               // Guard evaluated as true
 
-                                       // update the local tmp current key set
-                                       for (KeyValue kv : ut.getkeyValueUpdateSet()) {
-                                               speculativeTableTmp.put(kv.getKey(), kv);
-                                       }
+                               // update the local tmp current key set
+                               for (KeyValue kv : ut.getkeyValueUpdateSet()) {
+                                       speculativeTableTmp.put(kv.getKey(), kv);
+                               }
 
-                                       // create the commit
-                                       newEntry = new Commit(s, ut.getSequenceNumber(), ut.getArbitrator(), ut.getkeyValueUpdateSet());
-                               } else {
-                                       // Guard was false
+                               // create the commit
+                               newEntry = new Commit(s, ut.getSequenceNumber(), ut.getArbitrator(), ut.getkeyValueUpdateSet());
+                       } else {
+                               // Guard was false
 
-                                       // create the abort
-                                       newEntry = new Abort(s, ut.getSequenceNumber(), ut.getMachineID(), ut.getArbitrator());
-                               }
-                       } catch (Exception e) {
-                               e.printStackTrace();
+                               // create the abort
+                               newEntry = new Abort(s, ut.getSequenceNumber(), ut.getMachineID(), ut.getArbitrator());
                        }
 
                        if ((newEntry != null) && s.hasSpace(newEntry)) {
@@ -581,7 +634,7 @@ final public class Table {
                }
        }
 
-       private boolean doSendSlotsAndInsert(Slot s, boolean inserted, boolean resize, int newsize) {
+       private boolean doSendSlotsAndInsert(Slot s, boolean inserted, boolean resize, int newsize)  throws ServerException {
                int max = 0;
                if (resize)
                        max = newsize;
@@ -605,6 +658,10 @@ final public class Table {
                         before decoding */
                if (newslots.length == 0) return;
 
+               // Reset the table status declared sizes
+               smallestTableStatusSeen = -1;
+               largestTableStatusSeen = -1;
+
                long firstseqnum = newslots[0].getSequenceNumber();
                if (firstseqnum <= sequencenumber) {
                        throw new Error("Server Error: Sent older slots!");
@@ -615,14 +672,12 @@ final public class Table {
 
                HashSet<Long> machineSet = new HashSet<Long>(lastmessagetable.keySet()); //
 
-               initExpectedSize(firstseqnum);
+               // initExpectedSize(firstseqnum);
                for (Slot slot : newslots) {
                        processSlot(indexer, slot, acceptupdatestolocal, machineSet);
-                       updateExpectedSize();
+                       // updateExpectedSize();
                }
 
-
-               boolean hasGap = false;
                /* If there is a gap, check to see if the server sent us everything. */
                if (firstseqnum != (sequencenumber + 1)) {
 
@@ -633,6 +688,7 @@ final public class Table {
                        }
                }
 
+
                commitNewMaxSize();
 
                /* Commit new to slots. */
@@ -766,38 +822,34 @@ final public class Table {
        private void createSpeculativeTable() {
 
                if (uncommittedTransactionsMap.keySet().size() == 0) {
-                       speculativeTable = commitedTable; // Ok that they are the same object
+                       //      speculativeTable = commitedTable; // Ok that they are the same object
                        return;
                }
 
-               Map speculativeTableTmp = null;
+               Map<IoTString, KeyValue> speculativeTableTmp = new HashMap<IoTString, KeyValue>();
                List<Long> utSeqNums = new ArrayList<Long>(uncommittedTransactionsMap.keySet());
 
                // Sort from oldest to newest commit
                Collections.sort(utSeqNums);
 
                if (utSeqNums.get(0) > (lastUncommittedTransaction)) {
-                       speculativeTableTmp = new HashMap<IoTString, KeyValue>(commitedTable);
+
+                       speculativeTable.clear();
+                       lastUncommittedTransaction = -1;
 
                        for (Long key : utSeqNums) {
                                Transaction trans = uncommittedTransactionsMap.get(key);
 
                                lastUncommittedTransaction = key;
 
-                               try {
-                                       if (trans.getGuard().evaluate(speculativeTableTmp.values())) {
-                                               for (KeyValue kv : trans.getkeyValueUpdateSet()) {
-                                                       speculativeTableTmp.put(kv.getKey(), kv);
-                                               }
+                               if (trans.evaluateGuard(commitedTable, speculativeTableTmp)) {
+                                       for (KeyValue kv : trans.getkeyValueUpdateSet()) {
+                                               speculativeTableTmp.put(kv.getKey(), kv);
                                        }
-
-                               } catch (Exception e) {
-                                       e.printStackTrace();
                                }
+
                        }
                } else {
-                       speculativeTableTmp = new HashMap<IoTString, KeyValue>(speculativeTable);
-
                        for (Long key : utSeqNums) {
 
                                if (key <= lastUncommittedTransaction) {
@@ -808,28 +860,41 @@ final public class Table {
 
                                Transaction trans = uncommittedTransactionsMap.get(key);
 
-                               try {
-                                       if (trans.getGuard().evaluate(speculativeTableTmp.values())) {
-                                               for (KeyValue kv : trans.getkeyValueUpdateSet()) {
-                                                       speculativeTableTmp.put(kv.getKey(), kv);
-                                               }
+                               if (trans.evaluateGuard(speculativeTable, speculativeTableTmp)) {
+                                       for (KeyValue kv : trans.getkeyValueUpdateSet()) {
+                                               speculativeTableTmp.put(kv.getKey(), kv);
                                        }
-
-                               } catch (Exception e) {
-                                       e.printStackTrace();
                                }
                        }
                }
 
-               speculativeTable = speculativeTableTmp;
+               for (IoTString key : speculativeTableTmp.keySet()) {
+                       speculativeTable.put(key, speculativeTableTmp.get(key));
+               }
+
+               // speculativeTable = speculativeTableTmp;
        }
 
        private int expectedsize, currmaxsize;
 
        private void checkNumSlots(int numslots) {
-               if (numslots != expectedsize) {
-                       throw new Error("Server Error: Server did not send all slots.  Expected: " + expectedsize + " Received:" + numslots);
+
+
+               // We only have 1 size so we must have this many slots
+               if (largestTableStatusSeen == smallestTableStatusSeen) {
+                       if (numslots != smallestTableStatusSeen) {
+                               throw new Error("Server Error: Server did not send all slots.  Expected: " + smallestTableStatusSeen + " Received:" + numslots);
+                       }
+               } else {
+                       // We have more than 1
+                       if (numslots < smallestTableStatusSeen) {
+                               throw new Error("Server Error: Server did not send all slots.  Expected at least: " + smallestTableStatusSeen + " Received:" + numslots);
+                       }
                }
+
+               // if (numslots != expectedsize) {
+               // throw new Error("Server Error: Server did not send all slots.  Expected: " + expectedsize + " Received:" + numslots);
+               // }
        }
 
        private void initExpectedSize(long firstsequencenumber) {
@@ -841,6 +906,7 @@ final public class Table {
        private void updateExpectedSize() {
                expectedsize++;
                if (expectedsize > currmaxsize) {
+                       System.out.println("Maxing Out: " + expectedsize + "   " + currmaxsize);
                        expectedsize = currmaxsize;
                }
        }
@@ -850,6 +916,13 @@ final public class Table {
        }
 
        private void commitNewMaxSize() {
+
+               if (largestTableStatusSeen == -1) {
+                       currmaxsize = numslots;
+               } else {
+                       currmaxsize = largestTableStatusSeen;
+               }
+
                if (numslots != currmaxsize) {
                        buffer.resize(currmaxsize);
                }
@@ -908,7 +981,20 @@ final public class Table {
        }
 
        private void processEntry(Transaction entry) {
-               Transaction prevTrans = uncommittedTransactionsMap.put(entry.getSequenceNumber(), entry);
+
+               long arb = entry.getArbitrator();
+               Long comLast = lastCommitSeenSeqNumMap.get(arb);
+               Long abLast = lastAbortSeenSeqNumMap.get(arb);
+
+               Transaction prevTrans = null;
+
+               if ((comLast != null) && (comLast >= entry.getSequenceNumber())) {
+                       prevTrans = uncommittedTransactionsMap.remove(entry.getSequenceNumber());
+               } else if ((abLast != null) && (abLast >= entry.getSequenceNumber())) {
+                       prevTrans = uncommittedTransactionsMap.remove(entry.getSequenceNumber());
+               } else {
+                       prevTrans = uncommittedTransactionsMap.put(entry.getSequenceNumber(), entry);
+               }
 
                // Duplicate so delete old copy
                if (prevTrans != null) {
@@ -930,7 +1016,9 @@ final public class Table {
                        entry.setDead();
                }
 
-               lastAbortSeenSeqNumMap.put(entry.getTransArbitrator(), entry.getTransSequenceNumber());
+               if ((lastAbortSeenSeqNumMap.get(entry.getTransArbitrator()) != null) &&   (entry.getTransSequenceNumber() > lastAbortSeenSeqNumMap.get(entry.getTransArbitrator()))) {
+                       lastAbortSeenSeqNumMap.put(entry.getTransArbitrator(), entry.getTransSequenceNumber());
+               }
        }
 
        private void processEntry(Commit entry, Slot s) {
@@ -942,10 +1030,20 @@ final public class Table {
 
        private void processEntry(TableStatus entry) {
                int newnumslots = entry.getMaxSlots();
-               updateCurrMaxSize(newnumslots);
+               // updateCurrMaxSize(newnumslots);
                if (lastTableStatus != null)
                        lastTableStatus.setDead();
                lastTableStatus = entry;
+
+               if ((smallestTableStatusSeen == -1) || (newnumslots < smallestTableStatusSeen)) {
+                       smallestTableStatusSeen = newnumslots;
+               }
+
+               if ((largestTableStatusSeen == -1) || (newnumslots > largestTableStatusSeen)) {
+                       largestTableStatusSeen = newnumslots;
+               }
+
+               // System.out.println("Table Stat: " + newnumslots + "   large: " + largestTableStatusSeen + "   small: " + smallestTableStatusSeen);
        }
 
        private void addWatchList(long machineid, RejectedMessage entry) {
index fcbc44d..60f9a25 100644 (file)
@@ -10,7 +10,7 @@ public class Test {
 
        public static final  int NUMBER_OF_TESTS = 1000;
 
-       public static void main(String[] args) {
+       public static void main(String[] args)  throws ServerException {
                if (args[0].equals("2")) {
                        test2();
                } else if (args[0].equals("3")) {
@@ -23,136 +23,660 @@ public class Test {
                        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() {
-
-               // Setup the 2 clients
-               Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
-               t1.initTable();
-               Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
-               t2.update();
-
-
-               // Make the Keys
-               System.out.println("Setting up keys");
-               for (int i = 0; i < NUMBER_OF_TESTS; 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);
-                       t1.createNewKey(ia, 321);
-                       t1.createNewKey(ib, 351);
-                       t2.createNewKey(ic, 321);
-                       t2.createNewKey(id, 351);
-               }
-
-               for (int i = 0; i < NUMBER_OF_TESTS; 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);
-                       t1.createNewKey(ia, 1000);
-                       t1.createNewKey(ib, 1000);
-                       t2.createNewKey(ic, 1000);
-                       t2.createNewKey(id, 1000);
-               }
-
-               System.out.println("Updating Clients...");
-               t1.update();
-               t2.update();
-               t1.update();
-               t2.update();
-
-               boolean foundError = false;
-
-               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;
-
-                       IoTString iKeyA = new IoTString(keyA);
-                       IoTString iKeyB = new IoTString(keyB);
-                       IoTString iKeyC = new IoTString(keyC);
-                       IoTString iKeyD = new IoTString(keyD);
-
-
-                       Long testValA1 = t1.getArbitrator(iKeyA);
-                       Long testValB1 = t1.getArbitrator(iKeyB);
-                       Long testValC1 = t1.getArbitrator(iKeyC);
-                       Long testValD1 = t1.getArbitrator(iKeyD);
-
-                       Long testValA2 = t2.getArbitrator(iKeyA);
-                       Long testValB2 = t2.getArbitrator(iKeyB);
-                       Long testValC2 = t2.getArbitrator(iKeyC);
-                       Long testValD2 = t2.getArbitrator(iKeyD);
-
-                       if ((testValA1 == null) || (testValA1 != 321)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyA + "    " + testValA1);
-                               foundError = true;
-                       }
-
-                       if ((testValB1 == null) || (testValB1 != 351)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyB + "    " + testValB1);
-                               foundError = true;
-                       }
-
-                       if ((testValC1 == null) || (testValC1 != 321)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyC + "    " + testValC1);
-                               foundError = true;
-                       }
-
-                       if ((testValD1 == null) || (testValD1 != 351)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyD + "    " + testValD1);
-                               foundError = true;
-                       }
-
-                       if ((testValA2 == null) || (testValA2 != 321)) {
-                               System.out.println("Key-Value t2 incorrect: " + keyA + "    " + testValA2);
-                               foundError = true;
-                       }
-
-                       if ((testValB2 == null) || (testValB2 != 351)) {
-                               System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
-                               foundError = true;
-                       }
-
-                       if ((testValC2 == null) || (testValC2 != 321)) {
-                               System.out.println("Key-Value t2 incorrect: " + keyC + "    " + testValC2);
-                               foundError = true;
-                       }
-
-                       if ((testValD2 == null) || (testValD2 != 351)) {
-                               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 test8() {
+       // static void test9()  throws ServerException {
+       //      // Setup the 2 clients
+       //      Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
+       //      t1.initTable();
+       //      Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
+       //      t2.update();
+
+
+       //      // Make the Keys
+       //      System.out.println("Setting up keys");
+       //      for (int i = 0; i < NUMBER_OF_TESTS; 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);
+       //              t1.createNewKey(ia, 321);
+       //              t1.createNewKey(ib, 351);
+       //              t2.createNewKey(ic, 321);
+       //              t2.createNewKey(id, 351);
+       //      }
+
+       //      for (int i = 0; i < NUMBER_OF_TESTS; 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);
+       //              t1.createNewKey(ia, 1000);
+       //              t1.createNewKey(ib, 1000);
+       //              t2.createNewKey(ic, 1000);
+       //              t2.createNewKey(id, 1000);
+       //      }
+
+       //      System.out.println("Updating Clients...");
+       //      t1.update();
+       //      t2.update();
+       //      t1.update();
+       //      t2.update();
+
+       //      boolean foundError = false;
+
+       //      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;
+
+       //              IoTString iKeyA = new IoTString(keyA);
+       //              IoTString iKeyB = new IoTString(keyB);
+       //              IoTString iKeyC = new IoTString(keyC);
+       //              IoTString iKeyD = new IoTString(keyD);
+
+
+       //              Long testValA1 = t1.getArbitrator(iKeyA);
+       //              Long testValB1 = t1.getArbitrator(iKeyB);
+       //              Long testValC1 = t1.getArbitrator(iKeyC);
+       //              Long testValD1 = t1.getArbitrator(iKeyD);
+
+       //              Long testValA2 = t2.getArbitrator(iKeyA);
+       //              Long testValB2 = t2.getArbitrator(iKeyB);
+       //              Long testValC2 = t2.getArbitrator(iKeyC);
+       //              Long testValD2 = t2.getArbitrator(iKeyD);
+
+       //              if ((testValA1 == null) || (testValA1 != 321)) {
+       //                      System.out.println("Key-Value t1 incorrect: " + keyA + "    " + testValA1);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValB1 == null) || (testValB1 != 351)) {
+       //                      System.out.println("Key-Value t1 incorrect: " + keyB + "    " + testValB1);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValC1 == null) || (testValC1 != 321)) {
+       //                      System.out.println("Key-Value t1 incorrect: " + keyC + "    " + testValC1);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValD1 == null) || (testValD1 != 351)) {
+       //                      System.out.println("Key-Value t1 incorrect: " + keyD + "    " + testValD1);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValA2 == null) || (testValA2 != 321)) {
+       //                      System.out.println("Key-Value t2 incorrect: " + keyA + "    " + testValA2);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValB2 == null) || (testValB2 != 351)) {
+       //                      System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValC2 == null) || (testValC2 != 321)) {
+       //                      System.out.println("Key-Value t2 incorrect: " + keyC + "    " + testValC2);
+       //                      foundError = true;
+       //              }
+
+       //              if ((testValD2 == null) || (testValD2 != 351)) {
+       //                      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 test8()  throws ServerException {
+
+       //      boolean foundError = false;
+
+       //      // Setup the 2 clients
+       //      Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
+       //      t1.initTable();
+       //      Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
+       //      t2.update();
+
+       //      // t1.rebuild();
+       //      // t2.rebuild();
+
+       //      // Make the Keys
+       //      System.out.println("Setting up keys");
+       //      for (int i = 0; i < NUMBER_OF_TESTS; 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);
+       //              t1.createNewKey(ia, 321);
+       //              t1.createNewKey(ib, 351);
+       //              t2.createNewKey(ic, 321);
+       //              t2.createNewKey(id, 351);
+       //      }
+
+
+       //      // Do Updates for the keys
+       //      System.out.println("Setting Key-Values...");
+
+
+       //      String keyA0 = "a0";
+       //      String keyB0 = "b0";
+       //      String keyC0 = "c0";
+       //      String keyD0 = "d0";
+       //      String valueA0 = "a0";
+       //      String valueB0 = "b0";
+       //      String valueC0 = "c0";
+       //      String valueD0 = "d0";
+
+       //      IoTString iKeyA0 = new IoTString(keyA0);
+       //      IoTString iKeyB0 = new IoTString(keyB0);
+       //      IoTString iKeyC0 = new IoTString(keyC0);
+       //      IoTString iKeyD0 = new IoTString(keyD0);
+       //      IoTString iValueA0 = new IoTString(valueA0);
+       //      IoTString iValueB0 = new IoTString(valueB0);
+       //      IoTString iValueC0 = new IoTString(valueC0);
+       //      IoTString iValueD0 = new IoTString(valueD0);
+
+       //      t1.startTransaction();
+       //      t1.addKV( iKeyA0, iValueA0);
+       //      t1.commitTransaction();
+
+       //      t1.startTransaction();
+       //      t1.addKV(iKeyB0, iValueB0);
+       //      t1.commitTransaction();
+
+       //      t2.startTransaction();
+       //      t2.addKV(iKeyC0, iValueC0);
+       //      t2.commitTransaction();
+
+       //      t2.startTransaction();
+       //      t2.addKV(iKeyD0, iValueD0);
+       //      t2.commitTransaction();
+
+       //      for (int i = 1; i < NUMBER_OF_TESTS; i++) {
+       //              String keyB = "b" + i;
+       //              String valueB = "b" + i;
+       //              IoTString iKeyB = new IoTString(keyB);
+       //              IoTString iValueB = new IoTString(valueB);
+
+       //              String keyBOld = "b" + (i - 1);
+       //              String valueBOld = "b" + (i - 1);
+       //              IoTString iKeyBOld = new IoTString(keyBOld);
+       //              IoTString iValueBOld = new IoTString(valueBOld);
+
+
+       //              t1.startTransaction();
+       //              t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyBOld, iValueBOld, Guard.Equal))));
+       //              t1.addKV(iKeyB, iValueB);
+       //              t1.commitTransaction();
+       //      }
+
+       //      System.out.println("Checking Key-Values...");
+       //      for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+
+       //              String keyB = "b" + i;
+       //              String valueB = "b" + i;
+
+       //              IoTString iKeyB = new IoTString(keyB);
+       //              IoTString iValueB = new IoTString(valueB);
+
+       //              IoTString testValB1 = t1.getSpeculative(iKeyB);
+
+       //              if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
+       //                      System.out.println("Key-Value t1 incorrect: " + keyB);
+       //                      foundError = true;
+
+       //              }
+       //      }
+
+
+       //      System.out.println("Updating Clients...");
+       //      t1.update();
+       //      t2.update();
+       //      t1.update();
+       //      t2.update();
+
+       //      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 (i == 0) {
+       //                      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;
+       //                      }
+       //              } else {
+       //                      if (testValA1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyA);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValB1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyB);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValC1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyC);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValD1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyD);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValA2 != null) {
+       //                              System.out.println("Key-Value t2 incorrect: " + keyA + "    " + testValA2);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValB2 != null) {
+       //                              System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValC2 != null) {
+       //                              System.out.println("Key-Value t2 incorrect: " + keyC + "    " + testValC2);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValD2 != null) {
+       //                              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;
+       //      long endTime = 0;
+
+       //      // Setup the 2 clients
+       //      Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
+       //      t1.initTable();
+       //      Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
+       //      t2.update();
+
+       //      // t1.rebuild();
+       //      // t2.rebuild();
+
+       //      // Make the Keys
+       //      System.out.println("Setting up keys");
+       //      startTime = System.currentTimeMillis();
+       //      for (int i = 0; i < NUMBER_OF_TESTS; 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);
+       //              t1.createNewKey(ia, 321);
+       //              t1.createNewKey(ib, 351);
+       //              t2.createNewKey(ic, 321);
+       //              t2.createNewKey(id, 351);
+       //      }
+       //      endTime = System.currentTimeMillis();
+
+       //      System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
+       //      System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
+       //      System.out.println();
+
+
+       //      // Do Updates for the keys
+       //      System.out.println("Setting Key-Values...");
+       //      startTime = System.currentTimeMillis();
+
+
+
+       //      String keyA0 = "a0";
+       //      String keyB0 = "b0";
+       //      String keyC0 = "c0";
+       //      String keyD0 = "d0";
+       //      String valueA0 = "a0";
+       //      String valueB0 = "b0";
+       //      String valueC0 = "c0";
+       //      String valueD0 = "d0";
+
+       //      IoTString iKeyA0 = new IoTString(keyA0);
+       //      IoTString iKeyB0 = new IoTString(keyB0);
+       //      IoTString iKeyC0 = new IoTString(keyC0);
+       //      IoTString iKeyD0 = new IoTString(keyD0);
+       //      IoTString iValueA0 = new IoTString(valueA0);
+       //      IoTString iValueB0 = new IoTString(valueB0);
+       //      IoTString iValueC0 = new IoTString(valueC0);
+       //      IoTString iValueD0 = new IoTString(valueD0);
+
+       //      t1.startTransaction();
+       //      t1.addKV( iKeyA0, iValueA0);
+       //      t1.commitTransaction();
+
+       //      t1.startTransaction();
+       //      t1.addKV(iKeyB0, iValueB0);
+       //      t1.commitTransaction();
+
+       //      t2.startTransaction();
+       //      t2.addKV(iKeyC0, iValueC0);
+       //      t2.commitTransaction();
+
+       //      t2.startTransaction();
+       //      t2.addKV(iKeyD0, iValueD0);
+       //      t2.commitTransaction();
+
+       //      for (int i = 1; i < NUMBER_OF_TESTS; i++) {
+       //              String keyB = "b" + i;
+       //              String valueB = "b" + i;
+       //              IoTString iKeyB = new IoTString(keyB);
+       //              IoTString iValueB = new IoTString(valueB);
+
+       //              String keyBOld = "b" + (i - 1);
+       //              String valueBOld = "b" + (i - 2);
+       //              IoTString iKeyBOld = new IoTString(keyBOld);
+       //              IoTString iValueBOld = new IoTString(valueBOld);
+
+
+       //              t1.startTransaction();
+       //              t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyBOld, iValueBOld, Guard.Equal))));
+       //              t1.addKV(iKeyB, iValueB);
+       //              t1.commitTransaction();
+       //      }
+
+       //      for (int i = 1; i < NUMBER_OF_TESTS; i++) {
+       //              String keyC = "c" + i;
+       //              String valueC = "c" + i;
+       //              IoTString iKeyC = new IoTString(keyC);
+       //              IoTString iValueC = new IoTString(valueC);
+
+       //              String keyCOld = "c" + (i - 1);
+       //              String valueCOld = "c" + (i - 2);
+       //              IoTString iKeyCOld = new IoTString(keyCOld);
+       //              IoTString iValueCOld = new IoTString(valueCOld);
+
+
+       //              t2.startTransaction();
+       //              t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyCOld, iValueCOld, Guard.Equal))));
+       //              t2.addKV(iKeyC, iValueC);
+       //              t2.commitTransaction();
+       //      }
+
+       //      for (int i = 1; i < NUMBER_OF_TESTS; i++) {
+       //              String keyA = "a" + i;
+       //              String keyD = "d" + i;
+       //              String valueA = "a" + i;
+       //              String valueD = "d" + i;
+
+       //              IoTString iKeyA = new IoTString(keyA);
+       //              IoTString iKeyD = new IoTString(keyD);
+       //              IoTString iValueA = new IoTString(valueA);
+       //              IoTString iValueD = new IoTString(valueD);
+
+
+       //              String keyAOld = "a" + (i - 1);
+       //              String keyDOld = "d" + (i - 1);
+       //              String valueAOld = "a" + (i - 2);
+       //              String valueDOld = "d" + (i - 2);
+       //              IoTString iKeyAOld = new IoTString(keyAOld);
+       //              IoTString iKeyDOld = new IoTString(keyDOld);
+       //              IoTString iValueAOld = new IoTString(valueAOld);
+       //              IoTString iValueDOld = new IoTString(valueDOld);
+
+
+       //              t1.startTransaction();
+       //              t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyAOld, iValueAOld, Guard.Equal))));
+       //              t1.addKV(iKeyA, iValueA);
+       //              t1.commitTransaction();
+
+       //              t2.startTransaction();
+       //              t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyDOld, iValueDOld, Guard.Equal))));
+       //              t2.addKV(iKeyD, iValueD);
+       //              t2.commitTransaction();
+       //      }
+
+       //      endTime = System.currentTimeMillis();
+
+       //      System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
+       //      System.out.println("Time Taken Per Update: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
+       //      System.out.println();
+
+
+       //      System.out.println("Updating Clients...");
+       //      t1.update();
+       //      t2.update();
+       //      t1.update();
+       //      t2.update();
+
+       //      boolean foundError = false;
+
+       //      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 (i == 0) {
+       //                      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;
+       //                      }
+       //              } else {
+       //                      if (testValA1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyA);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValB1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyB);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValC1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyC);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValD1 != null) {
+       //                              System.out.println("Key-Value t1 incorrect: " + keyD);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValA2 != null) {
+       //                              System.out.println("Key-Value t2 incorrect: " + keyA + "    " + testValA2);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValB2 != null) {
+       //                              System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValC2 != null) {
+       //                              System.out.println("Key-Value t2 incorrect: " + keyC + "    " + testValC2);
+       //                              foundError = true;
+       //                      }
+
+       //                      if (testValD2 != null) {
+       //                              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;
+               long endTime = 0;
                boolean foundError = false;
 
                // Setup the 2 clients
@@ -161,12 +685,10 @@ public class Test {
                Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
                t2.update();
 
-               // t1.rebuild();
-               // t2.rebuild();
-
+               startTime = System.currentTimeMillis();
                // Make the Keys
                System.out.println("Setting up keys");
-               for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+               for (int i = 0; i < 4; i++) {
                        String a = "a" + i;
                        String b = "b" + i;
                        String c = "c" + i;
@@ -180,366 +702,124 @@ public class Test {
                        t2.createNewKey(ic, 321);
                        t2.createNewKey(id, 351);
                }
-
+               endTime = System.currentTimeMillis();
+               System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
+               System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (4))   );
+               System.out.println();
 
                // Do Updates for the keys
                System.out.println("Setting Key-Values...");
 
+               startTime = System.currentTimeMillis();
+               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);
 
-               String keyA0 = "a0";
-               String keyB0 = "b0";
-               String keyC0 = "c0";
-               String keyD0 = "d0";
-               String valueA0 = "a0";
-               String valueB0 = "b0";
-               String valueC0 = "c0";
-               String valueD0 = "d0";
-
-               IoTString iKeyA0 = new IoTString(keyA0);
-               IoTString iKeyB0 = new IoTString(keyB0);
-               IoTString iKeyC0 = new IoTString(keyC0);
-               IoTString iKeyD0 = new IoTString(keyD0);
-               IoTString iValueA0 = new IoTString(valueA0);
-               IoTString iValueB0 = new IoTString(valueB0);
-               IoTString iValueC0 = new IoTString(valueC0);
-               IoTString iValueD0 = new IoTString(valueD0);
-
-               t1.startTransaction();
-               t1.addKV( iKeyA0, iValueA0);
-               t1.commitTransaction();
-
-               t1.startTransaction();
-               t1.addKV(iKeyB0, iValueB0);
-               t1.commitTransaction();
-
-               t2.startTransaction();
-               t2.addKV(iKeyC0, iValueC0);
-               t2.commitTransaction();
-
-               t2.startTransaction();
-               t2.addKV(iKeyD0, iValueD0);
-               t2.commitTransaction();
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
-                       String keyB = "b" + i;
-                       String valueB = "b" + i;
-                       IoTString iKeyB = new IoTString(keyB);
-                       IoTString iValueB = new IoTString(valueB);
+                               IoTString iKeyB = new IoTString(keyB);
+                               IoTString iValueB = new IoTString(valueB);
 
-                       String keyBOld = "b" + (i - 1);
-                       String valueBOld = "b" + (i - 1);
-                       IoTString iKeyBOld = new IoTString(keyBOld);
-                       IoTString iValueBOld = new IoTString(valueBOld);
+                               t1.startTransaction();
+                               t1.getSpeculativeAtomic(iKeyB);
+                               t1.addKV(iKeyB, iValueB);
+                               t1.commitTransaction();
+                       }
+               }
+               endTime = System.currentTimeMillis();
+               System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
+               System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (4 * NUMBER_OF_TESTS))   );
+               System.out.println();
 
 
-                       t1.startTransaction();
-                       t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyBOld, iValueBOld, Guard.Equal))));
-                       t1.addKV(iKeyB, iValueB);
-                       t1.commitTransaction();
-               }
 
-               System.out.println("Checking Key-Values...");
-               for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+               System.out.println("Checking b");
+               for (int i = 0; i < 4; i++) {
 
                        String keyB = "b" + i;
-                       String valueB = "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);
+                               System.out.println("Key-Value t1 incorrect: " + keyB + "    " + testValB1);
                                foundError = true;
-
                        }
-               }
-
-
-               System.out.println("Updating Clients...");
-               t1.update();
-               t2.update();
-               t1.update();
-               t2.update();
 
-               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 (i == 0) {
-                               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;
-                               }
-                       } else {
-                               if (testValA1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyA);
-                                       foundError = true;
-                               }
-
-                               if (testValB1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyB);
-                                       foundError = true;
-                               }
-
-                               if (testValC1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyC);
-                                       foundError = true;
-                               }
-
-                               if (testValD1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyD);
-                                       foundError = true;
-                               }
-
-                               if (testValA2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyA + "    " + testValA2);
-                                       foundError = true;
-                               }
-
-                               if (testValB2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
-                                       foundError = true;
-                               }
-
-                               if (testValC2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyC + "    " + testValC2);
-                                       foundError = true;
-                               }
-
-                               if (testValD2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyD + "    " + testValD2);
-                                       foundError = true;
-                               }
+                       if ((testValB2 != null)) {
+                               System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
+                               foundError = true;
                        }
                }
 
-               if (foundError) {
-                       System.out.println("Found Errors...");
-               } else {
-                       System.out.println("No Errors Found...");
-               }
-       }
-
-       static void test7() {
-
-               long startTime = 0;
-               long endTime = 0;
-
-               // Setup the 2 clients
-               Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
-               t1.initTable();
-               Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
-               t2.update();
-
-               // t1.rebuild();
-               // t2.rebuild();
-
-               // Make the Keys
-               System.out.println("Setting up keys");
-               startTime = System.currentTimeMillis();
-               for (int i = 0; i < NUMBER_OF_TESTS; 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);
-                       t1.createNewKey(ia, 321);
-                       t1.createNewKey(ib, 351);
-                       t2.createNewKey(ic, 321);
-                       t2.createNewKey(id, 351);
-               }
-               endTime = System.currentTimeMillis();
-
-               System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
-               System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
-               System.out.println();
-
-
-               // Do Updates for the keys
-               System.out.println("Setting Key-Values...");
                startTime = System.currentTimeMillis();
+               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);
 
-
-               String keyA0 = "a0";
-               String keyB0 = "b0";
-               String keyC0 = "c0";
-               String keyD0 = "d0";
-               String valueA0 = "a0";
-               String valueB0 = "b0";
-               String valueC0 = "c0";
-               String valueD0 = "d0";
-
-               IoTString iKeyA0 = new IoTString(keyA0);
-               IoTString iKeyB0 = new IoTString(keyB0);
-               IoTString iKeyC0 = new IoTString(keyC0);
-               IoTString iKeyD0 = new IoTString(keyD0);
-               IoTString iValueA0 = new IoTString(valueA0);
-               IoTString iValueB0 = new IoTString(valueB0);
-               IoTString iValueC0 = new IoTString(valueC0);
-               IoTString iValueD0 = new IoTString(valueD0);
-
-               t1.startTransaction();
-               t1.addKV( iKeyA0, iValueA0);
-               t1.commitTransaction();
-
-               t1.startTransaction();
-               t1.addKV(iKeyB0, iValueB0);
-               t1.commitTransaction();
-
-               t2.startTransaction();
-               t2.addKV(iKeyC0, iValueC0);
-               t2.commitTransaction();
-
-               t2.startTransaction();
-               t2.addKV(iKeyD0, iValueD0);
-               t2.commitTransaction();
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
-                       String keyB = "b" + i;
-                       String valueB = "b" + i;
-                       IoTString iKeyB = new IoTString(keyB);
-                       IoTString iValueB = new IoTString(valueB);
-
-                       String keyBOld = "b" + (i - 1);
-                       String valueBOld = "b" + (i - 2);
-                       IoTString iKeyBOld = new IoTString(keyBOld);
-                       IoTString iValueBOld = new IoTString(valueBOld);
-
-
-                       t1.startTransaction();
-                       t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyBOld, iValueBOld, Guard.Equal))));
-                       t1.addKV(iKeyB, iValueB);
-                       t1.commitTransaction();
-               }
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
-                       String keyC = "c" + i;
-                       String valueC = "c" + i;
-                       IoTString iKeyC = new IoTString(keyC);
-                       IoTString iValueC = new IoTString(valueC);
-
-                       String keyCOld = "c" + (i - 1);
-                       String valueCOld = "c" + (i - 2);
-                       IoTString iKeyCOld = new IoTString(keyCOld);
-                       IoTString iValueCOld = new IoTString(valueCOld);
-
-
-                       t2.startTransaction();
-                       t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyCOld, iValueCOld, Guard.Equal))));
-                       t2.addKV(iKeyC, iValueC);
-                       t2.commitTransaction();
+                               t2.startTransaction();
+                               t2.getSpeculativeAtomic(iKeyC);
+                               t2.addKV(iKeyC, iValueC);
+                               t2.commitTransaction();
+                       }
                }
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
-                       String keyA = "a" + i;
-                       String keyD = "d" + i;
-                       String valueA = "a" + i;
-                       String valueD = "d" + i;
-
-                       IoTString iKeyA = new IoTString(keyA);
-                       IoTString iKeyD = new IoTString(keyD);
-                       IoTString iValueA = new IoTString(valueA);
-                       IoTString iValueD = new IoTString(valueD);
+               endTime = System.currentTimeMillis();
+               System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
+               System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (4 * NUMBER_OF_TESTS))   );
+               System.out.println();
 
 
-                       String keyAOld = "a" + (i - 1);
-                       String keyDOld = "d" + (i - 1);
-                       String valueAOld = "a" + (i - 2);
-                       String valueDOld = "d" + (i - 2);
-                       IoTString iKeyAOld = new IoTString(keyAOld);
-                       IoTString iKeyDOld = new IoTString(keyDOld);
-                       IoTString iValueAOld = new IoTString(valueAOld);
-                       IoTString iValueDOld = new IoTString(valueDOld);
+               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);
 
-                       t1.startTransaction();
-                       t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyAOld, iValueAOld, Guard.Equal))));
-                       t1.addKV(iKeyA, iValueA);
-                       t1.commitTransaction();
+                       if ((testValC1 != null)) {
+                               System.out.println("Key-Value t1 incorrect: " + keyC + "   " + testValC1);
+                               foundError = true;
+                       }
 
-                       t2.startTransaction();
-                       t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyDOld, iValueDOld, Guard.Equal))));
-                       t2.addKV(iKeyD, iValueD);
-                       t2.commitTransaction();
+                       if ((testValC2 == null) || (testValC2.equals(iValueC) == false)) {
+                               System.out.println("Key-Value t2 incorrect: " + keyC + "   " + testValC2);
+                               foundError = true;
+                       }
                }
 
-               endTime = System.currentTimeMillis();
+               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);
 
-               System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
-               System.out.println("Time Taken Per Update: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
-               System.out.println();
+                               IoTString iKeyA = new IoTString(keyA);
+                               IoTString iKeyD = new IoTString(keyD);
+                               IoTString iValueA = new IoTString(valueA);
+                               IoTString iValueD = new IoTString(valueD);
+
+                               t1.startTransaction();
+                               t1.addKV(iKeyA, iValueA);
+                               t1.commitTransaction();
 
+                               t2.startTransaction();
+                               t2.addKV(iKeyD, iValueD);
+                               t2.commitTransaction();
+                       }
+               }
 
                System.out.println("Updating Clients...");
                t1.update();
@@ -547,19 +827,17 @@ public class Test {
                t1.update();
                t2.update();
 
-               boolean foundError = false;
-
                System.out.println("Checking Key-Values...");
-               for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+               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;
-                       String valueB = "b" + i;
-                       String valueC = "c" + i;
-                       String valueD = "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);
@@ -581,88 +859,44 @@ public class Test {
                        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);
+                               foundError = true;
+                       }
+
+                       if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
+                               System.out.println("Key-Value t1 incorrect: " + keyB + "    " + testValB1);
+                               foundError = true;
+                       }
+
+                       if ((testValC1 == null) || (testValC1.equals(iValueC) == false)) {
+                               System.out.println("Key-Value t1 incorrect: " + keyC + "    " + testValC1);
+                               foundError = true;
+                       }
+
+                       if ((testValD1 == null) || (testValD1.equals(iValueD) == false)) {
+                               System.out.println("Key-Value t1 incorrect: " + keyD + "    " + testValD1);
+                               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 (i == 0) {
-                               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;
-                               }
-                       } else {
-                               if (testValA1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyA);
-                                       foundError = true;
-                               }
-
-                               if (testValB1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyB);
-                                       foundError = true;
-                               }
-
-                               if (testValC1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyC);
-                                       foundError = true;
-                               }
-
-                               if (testValD1 != null) {
-                                       System.out.println("Key-Value t1 incorrect: " + keyD);
-                                       foundError = true;
-                               }
-
-                               if (testValA2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyA + "    " + testValA2);
-                                       foundError = true;
-                               }
-
-                               if (testValB2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyB + "    " + testValB2);
-                                       foundError = true;
-                               }
-
-                               if (testValC2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyC + "    " + testValC2);
-                                       foundError = true;
-                               }
-
-                               if (testValD2 != null) {
-                                       System.out.println("Key-Value t2 incorrect: " + keyD + "    " + testValD2);
-                                       foundError = true;
-                               }
+                       if ((testValD2 == null) || (testValD2.equals(iValueD) == false)) {
+                               System.out.println("Key-Value t2 incorrect: " + keyD + "    " + testValD2);
+                               foundError = true;
                        }
                }
 
@@ -673,8 +907,7 @@ public class Test {
                }
        }
 
-       static void test6() {
-
+       static void test6()  throws ServerException {
                long startTime = 0;
                long endTime = 0;
 
@@ -684,8 +917,6 @@ public class Test {
                Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
                t2.update();
 
-               // t1.rebuild();
-               // t2.rebuild();
 
                // Make the Keys
                System.out.println("Setting up keys");
@@ -706,6 +937,8 @@ public class Test {
                }
                endTime = System.currentTimeMillis();
 
+
+
                System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
                System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
                System.out.println();
@@ -714,93 +947,45 @@ public class Test {
                // Do Updates for the keys
                System.out.println("Setting Key-Values...");
                startTime = System.currentTimeMillis();
-
-
-               t1.startTransaction();
-               t1.addKV( new IoTString("a0"), new IoTString("a0"));
-               t1.commitTransaction();
-
-               t1.startTransaction();
-               t1.addKV(new IoTString("b0"), new IoTString("b0"));
-               t1.commitTransaction();
-
-               t2.startTransaction();
-               t2.addKV(new IoTString("c0"), new IoTString("c0"));
-               t2.commitTransaction();
-
-               t2.startTransaction();
-               t2.addKV(new IoTString("d0"), new IoTString("d0"));
-               t2.commitTransaction();
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
+               for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+                       String keyA = "a" + i;
                        String keyB = "b" + i;
-                       String valueB = "b" + i;
-                       IoTString iKeyB = new IoTString(keyB);
-                       IoTString iValueB = new IoTString(valueB);
-
-                       String keyBOld = "b" + (i - 1);
-                       String valueBOld = "b" + (i - 1);
-                       IoTString iKeyBOld = new IoTString(keyBOld);
-                       IoTString iValueBOld = new IoTString(valueBOld);
-
-
-                       t1.startTransaction();
-                       t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyBOld, iValueBOld, Guard.Equal))));
-                       t1.addKV(iKeyB, iValueB);
-                       t1.commitTransaction();
-               }
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
                        String keyC = "c" + i;
-                       String valueC = "c" + i;
-                       IoTString iKeyC = new IoTString(keyC);
-                       IoTString iValueC = new IoTString(valueC);
-
-                       String keyCOld = "c" + (i - 1);
-                       String valueCOld = "c" + (i - 1);
-                       IoTString iKeyCOld = new IoTString(keyCOld);
-                       IoTString iValueCOld = new IoTString(valueCOld);
-
-
-                       t2.startTransaction();
-                       t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyCOld, iValueCOld, Guard.Equal))));
-                       t2.addKV(iKeyC, iValueC);
-                       t2.commitTransaction();
-               }
-
-               for (int i = 1; i < NUMBER_OF_TESTS; i++) {
-                       String keyA = "a" + 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 keyAOld = "a" + (i - 1);
-                       String keyDOld = "d" + (i - 1);
-                       String valueAOld = "a" + (i - 1);
-                       String valueDOld = "d" + (i - 1);
-                       IoTString iKeyAOld = new IoTString(keyAOld);
-                       IoTString iKeyDOld = new IoTString(keyDOld);
-                       IoTString iValueAOld = new IoTString(valueAOld);
-                       IoTString iValueDOld = new IoTString(valueDOld);
-
-
                        t1.startTransaction();
-                       t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyAOld, iValueAOld, Guard.Equal))));
+                       t1.getCommittedAtomic(iKeyA);
                        t1.addKV(iKeyA, iValueA);
                        t1.commitTransaction();
 
+                       t1.startTransaction();
+                       t1.getCommittedAtomic(iKeyB);
+                       t1.addKV(iKeyB, iValueB);
+                       t1.commitTransaction();
+
+                       t2.startTransaction();
+                       t2.getCommittedAtomic(iKeyC);
+                       t2.addKV(iKeyC, iValueC);
+                       t2.commitTransaction();
+
                        t2.startTransaction();
-                       t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyDOld, iValueDOld, Guard.Equal))));
+                       t2.getCommittedAtomic(iKeyD);
                        t2.addKV(iKeyD, iValueD);
                        t2.commitTransaction();
                }
-
                endTime = System.currentTimeMillis();
 
                System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
@@ -895,12 +1080,22 @@ public class Test {
                } else {
                        System.out.println("No Errors Found...");
                }
+
+               // System.out.println();
+               // System.out.println();
+               // System.out.println();
+               // t1.printSlots();
+               // System.out.println();
+               // System.out.println();
+               // System.out.println();
+               // t2.printSlots();
        }
 
-       static void test5() {
+       static void test5() throws ServerException {
 
                long startTime = 0;
                long endTime = 0;
+               boolean foundError = false;
 
                // Setup the 2 clients
                Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
@@ -908,15 +1103,10 @@ public class Test {
                Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
                t2.update();
 
-               // t1.rebuild();
-               // t2.rebuild();
-
-
 
                // Make the Keys
                System.out.println("Setting up keys");
-               startTime = System.currentTimeMillis();
-               for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+               for (int i = 0; i < 4; i++) {
                        String a = "a" + i;
                        String b = "b" + i;
                        String c = "c" + i;
@@ -935,98 +1125,103 @@ public class Test {
 
 
                System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
-               System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
+               System.out.println("Time Taken Per Key: " + (double)  (((endTime - startTime) / 1000.0) / (4))   );
                System.out.println();
 
 
                // Do Updates for the keys
                System.out.println("Setting Key-Values...");
-               startTime = System.currentTimeMillis();
-               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);
+               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);
+
+                               t1.startTransaction();
+                               t1.addKV(iKeyB, iValueB);
+                               t1.commitTransaction();
+                       }
+               }
+
+               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 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 testValB1 = t1.getSpeculative(iKeyB);
+                       IoTString testValB2 = t2.getSpeculative(iKeyB);
 
-                       if (i != 0) {
-                               String keyAOld = "a" + (i - 1);
-                               String keyBOld = "b" + (i - 1);
-                               String keyCOld = "c" + (i - 1);
-                               String keyDOld = "d" + (i - 1);
-                               String valueAOld = "a" + (i - 1);
-                               String valueBOld = "b" + (i - 1);
-                               String valueCOld = "c" + (i - 1);
-                               String valueDOld = "d" + (i - 1);
+                       if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
+                               System.out.println("Key-Value t1 incorrect: " + keyB);
+                               foundError = true;
+                       }
 
-                               IoTString iKeyAOld = new IoTString(keyAOld);
-                               IoTString iKeyBOld = new IoTString(keyBOld);
-                               IoTString iKeyCOld = new IoTString(keyCOld);
-                               IoTString iKeyDOld = new IoTString(keyDOld);
-                               IoTString iValueAOld = new IoTString(valueAOld);
-                               IoTString iValueBOld = new IoTString(valueBOld);
-                               IoTString iValueCOld = new IoTString(valueCOld);
-                               IoTString iValueDOld = new IoTString(valueDOld);
+                       if ((testValB2 != null)) {
+                               System.out.println("Key-Value t2 incorrect: " + keyB);
+                               foundError = true;
+                       }
+               }
 
-                               t1.startTransaction();
-                               t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyAOld, iValueAOld, Guard.Equal))));
-                               t1.addKV(iKeyA, iValueA);
-                               t1.commitTransaction();
+               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);
 
-                               t1.startTransaction();
-                               t1.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyBOld, iValueBOld, Guard.Equal))));
-                               t1.addKV(iKeyB, iValueB);
-                               t1.commitTransaction();
+                               IoTString iKeyC = new IoTString(keyC);
+                               IoTString iValueC = new IoTString(valueC);
 
                                t2.startTransaction();
-                               t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyCOld, iValueCOld, Guard.Equal))));
                                t2.addKV(iKeyC, iValueC);
                                t2.commitTransaction();
+                       }
+               }
 
-                               t2.startTransaction();
-                               t2.addGuard(new Guard(new IoTString(Guard.createExpression(iKeyDOld, iValueDOld, Guard.Equal))));
-                               t2.addKV(iKeyD, iValueD);
-                               t2.commitTransaction();
+               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);
 
-                       } else {
-                               t1.startTransaction();
-                               t1.addKV(iKeyA, iValueA);
-                               t1.commitTransaction();
+                       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;
+                       }
+               }
+
+               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);
 
                                t1.startTransaction();
-                               t1.addKV(iKeyB, iValueB);
+                               t1.addKV(iKeyA, iValueA);
                                t1.commitTransaction();
 
-                               t2.startTransaction();
-                               t2.addKV(iKeyC, iValueC);
-                               t2.commitTransaction();
-
                                t2.startTransaction();
                                t2.addKV(iKeyD, iValueD);
                                t2.commitTransaction();
                        }
                }
-               endTime = System.currentTimeMillis();
-
-               System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
-               System.out.println("Time Taken Per Update: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 4))   );
-               System.out.println();
-
 
                System.out.println("Updating Clients...");
                t1.update();
@@ -1034,19 +1229,18 @@ public class Test {
                t1.update();
                t2.update();
 
-               boolean foundError = false;
 
                System.out.println("Checking Key-Values...");
-               for (int i = 0; i < NUMBER_OF_TESTS; i++) {
+               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;
-                       String valueB = "b" + i;
-                       String valueC = "c" + i;
-                       String valueD = "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);
@@ -1069,22 +1263,22 @@ public class Test {
                        IoTString testValD2 = t2.getCommitted(iKeyD);
 
                        if ((testValA1 == null) || (testValA1.equals(iValueA) == false)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyA);
+                               System.out.println("Key-Value t1 incorrect: " + keyA + "    " + testValA1);
                                foundError = true;
                        }
 
                        if ((testValB1 == null) || (testValB1.equals(iValueB) == false)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyB);
+                               System.out.println("Key-Value t1 incorrect: " + keyB + "    " + testValB1);
                                foundError = true;
                        }
 
                        if ((testValC1 == null) || (testValC1.equals(iValueC) == false)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyC);
+                               System.out.println("Key-Value t1 incorrect: " + keyC + "    " + testValC1);
                                foundError = true;
                        }
 
                        if ((testValD1 == null) || (testValD1.equals(iValueD) == false)) {
-                               System.out.println("Key-Value t1 incorrect: " + keyD);
+                               System.out.println("Key-Value t1 incorrect: " + keyD + "    " + testValD1);
                                foundError = true;
                        }
 
@@ -1117,7 +1311,7 @@ public class Test {
                }
        }
 
-       static void test4() {
+       static void test4() throws ServerException {
 
                long startTime = 0;
                long endTime = 0;
@@ -1198,7 +1392,7 @@ public class Test {
                endTime = System.currentTimeMillis();
 
                System.out.println("Time Taken: " + (double)   ((endTime - startTime) / 1000.0)    );
-               System.out.println("Time Taken Per Update: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 8))   );
+               System.out.println("Time Taken Per Update: " + (double)  (((endTime - startTime) / 1000.0) / (NUMBER_OF_TESTS * 16))   );
                System.out.println();
 
 
@@ -1291,10 +1485,11 @@ public class Test {
                }
        }
 
-       static void test3() {
+       static void test3() throws ServerException {
 
                long startTime = 0;
                long endTime = 0;
+               boolean foundError = false;
 
                // Setup the 2 clients
                Table t1 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 321);
@@ -1388,7 +1583,6 @@ public class Test {
                t1.update();
                t2.update();
 
-               boolean foundError = false;
 
                System.out.println("Checking Key-Values...");
                for (int i = 0; i < NUMBER_OF_TESTS; i++) {
@@ -1471,7 +1665,7 @@ public class Test {
                }
        }
 
-       static void test2() {
+       static void test2() throws ServerException {
 
                long startTime = 0;
                long endTime = 0;
@@ -1482,11 +1676,6 @@ public class Test {
                Table t2 = new Table("http://127.0.0.1/test.iotcloud/", "reallysecret", 351);
                t2.update();
 
-               // t1.rebuild();
-               // t2.rebuild();
-
-
-
                // Make the Keys
                System.out.println("Setting up keys");
                startTime = System.currentTimeMillis();
index 2167d7d..72aed03 100644 (file)
@@ -3,28 +3,36 @@ package iotcloud;
 import java.nio.ByteBuffer;
 import java.util.Set;
 import java.util.HashSet;
+import java.util.Map;
 
 class Transaction extends Entry {
 
     private long seqnum;
     private long machineid;
     private Set<KeyValue> keyValueUpdateSet = null;
-    private Guard guard;
+    private Set<KeyValue> keyValueGuardSet = null;
     private Long arbitrator;
 
-    public Transaction(Slot slot, long _seqnum, long _machineid, Long _arbitrator, Set<KeyValue> _keyValueUpdateSet, Guard _guard) {
+    public Transaction(Slot slot, long _seqnum, long _machineid, Long _arbitrator, Set<KeyValue> _keyValueUpdateSet, Set<KeyValue> _keyValueGuardSet) {
         super(slot);
         seqnum = _seqnum;
         machineid = _machineid;
         arbitrator = _arbitrator;
-        keyValueUpdateSet = new HashSet<KeyValue>();
+        // keyValueUpdateSet = new HashSet<KeyValue>();
+        // keyValueGuardSet = new HashSet<KeyValue>();
 
-        for (KeyValue kv : _keyValueUpdateSet) {
-            KeyValue kvCopy = kv.getCopy();
-            keyValueUpdateSet.add(kvCopy);
-        }
+        // for (KeyValue kv : _keyValueUpdateSet) {
+        //     KeyValue kvCopy = kv.getCopy();
+        //     keyValueUpdateSet.add(kvCopy);
+        // }
+
+        // for (KeyValue kv : _keyValueGuardSet) {
+        //     KeyValue kvCopy = kv.getCopy();
+        //     keyValueGuardSet.add(kvCopy);
+        // }
 
-        guard = _guard.getCopy();
+        keyValueUpdateSet = _keyValueUpdateSet;
+        keyValueGuardSet = _keyValueGuardSet;
     }
 
     public long getMachineID() {
@@ -43,8 +51,37 @@ class Transaction extends Entry {
         return keyValueUpdateSet;
     }
 
-    public Guard getGuard() {
-        return guard;
+    public Set<KeyValue> getkeyValueGuardSet() {
+        return keyValueGuardSet;
+    }
+
+    public boolean evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative) {
+        for (KeyValue kvGuard : keyValueGuardSet) {
+
+            // First check if the key is in the speculative table, this is the value of the latest assumption
+            KeyValue kv = keyValTableSpeculative.get(kvGuard.getKey());
+
+            if (kv == null) {
+
+                // if it is not in the speculative table then check the committed table and use that
+                // value as our latest assumption
+                kv = keyValTableCommitted.get(kvGuard.getKey());
+                // System.out.println("Replaced With Commit Table");
+            }
+
+            if (kvGuard.getValue() != null) {
+                if ((kv == null) || (!kvGuard.getValue().equals(kv.getValue()))) {
+                    // System.out.println("Fail 1       " + (kv == null) + "   " + kvGuard.getValue() + "    " + kv.getValue());
+                    return false;
+                }
+            } else {
+                if (kv != null) {
+                    // System.out.println("Fail 2    " + kv.getValue());
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
     public byte getType() {
@@ -54,19 +91,21 @@ class Transaction extends Entry {
     public int getSize() {
         int size = 3 * Long.BYTES + Byte.BYTES; // seq, machine id, entry type
         size += Integer.BYTES; // number of KV's
+        size += Integer.BYTES; // number of Guard KV's
 
         // Size of each KV
         for (KeyValue kv : keyValueUpdateSet) {
             size += kv.getSize();
         }
 
-        // Size of the guard
-        size += guard.getSize();
+        // Size of each Guard KV
+        for (KeyValue kv : keyValueGuardSet) {
+            size += kv.getSize();
+        }
 
         return size;
     }
 
-
     public void encode(ByteBuffer bb) {
         bb.put(Entry.TypeTransaction);
         bb.putLong(seqnum);
@@ -78,7 +117,10 @@ class Transaction extends Entry {
             kv.encode(bb);
         }
 
-        guard.encode(bb);
+        bb.putInt(keyValueGuardSet.size());
+        for (KeyValue kv : keyValueGuardSet) {
+            kv.encode(bb);
+        }
     }
 
     static Entry decode(Slot slot, ByteBuffer bb) {
@@ -87,18 +129,23 @@ class Transaction extends Entry {
         long arbitrator = bb.getLong();
         int numberOfKeys = bb.getInt();
 
-        Set<KeyValue> kvSet = new HashSet<KeyValue>();
+        Set<KeyValue> kvSetUpdates = new HashSet<KeyValue>();
         for (int i = 0; i < numberOfKeys; i++) {
             KeyValue kv = KeyValue.decode(bb);
-            kvSet.add(kv);
+            kvSetUpdates.add(kv);
         }
 
-        Guard guard = Guard.decode(bb);
+        int numberOfGuards = bb.getInt();
+        Set<KeyValue> kvSetGuards = new HashSet<KeyValue>();
+        for (int i = 0; i < numberOfGuards; i++) {
+            KeyValue kv = KeyValue.decode(bb);
+            kvSetGuards.add(kv);
+        }
 
-        return new Transaction(slot, seqnum, machineid, arbitrator, kvSet, guard);
+        return new Transaction(slot, seqnum, machineid, arbitrator, kvSetUpdates, kvSetGuards);
     }
 
     public Entry getCopy(Slot s) {
-        return new Transaction(s, seqnum, machineid, arbitrator, keyValueUpdateSet, guard);
+        return new Transaction(s, seqnum, machineid, arbitrator, keyValueUpdateSet, keyValueGuardSet);
     }
 }
\ No newline at end of file