more code
authorbdemsky <bdemsky@uci.edu>
Sun, 24 Jul 2016 03:20:37 +0000 (20:20 -0700)
committerbdemsky <bdemsky@uci.edu>
Sun, 24 Jul 2016 03:20:37 +0000 (20:20 -0700)
src/java/iotcloud/CloudComm.java
src/java/iotcloud/Slot.java
src/java/iotcloud/Table.java

index ca17ffb..1993a8d 100644 (file)
@@ -25,7 +25,7 @@ class CloudComm {
                return new URL(urlstr);
        }
 
-       public Slot[] putSlot(Slot slot, int max) throws IOException {
+       public Slot[] putSlot(Slot slot, int max) {
                try {
                        long sequencenumber=slot.getSequenceNumber();
                        byte[] bytes=slot.encode(mac);
index ff0e901..dc5389e 100644 (file)
@@ -6,6 +6,7 @@ import java.util.Arrays;
 
 class Slot implements Liveness {
        static final int SLOT_SIZE=2048;
+       static final int RESERVED_SPACE=64;
        static final int HMAC_SIZE=32;
 
        private long seqnum;
@@ -15,6 +16,7 @@ class Slot implements Liveness {
        private Vector<Entry> entries;
        private int livecount;
        private boolean seqnumlive;
+       private int freespace;
        
        Slot(long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac) {
                seqnum=_seqnum;
@@ -24,6 +26,7 @@ class Slot implements Liveness {
                entries=new Vector<Entry>();
                livecount=1;
                seqnumlive=true;
+               freespace = SLOT_SIZE - getBaseSize();
        }
 
        Slot(long _seqnum, long _machineid, byte[] _prevhmac) {
@@ -41,8 +44,19 @@ class Slot implements Liveness {
        void addEntry(Entry e) {
                entries.add(e);
                livecount++;
+               freespace -= e.getSize();
        }
 
+       boolean hasSpace(Entry e) {
+               int newfreespace = freespace - e.getSize();
+               return newfreespace > RESERVED_SPACE;
+       }
+
+       boolean canFit(Entry e) {
+               int newfreespace = freespace - e.getSize();
+               return newfreespace >= 0;
+       }
+       
        Vector<Entry> getEntries() {
                return entries;
        }
@@ -90,6 +104,22 @@ class Slot implements Liveness {
                return array;
        }
 
+       int getBaseSize() {
+               return 2*HMAC_SIZE+2*Long.BYTES+Integer.BYTES;
+       }
+       
+       Vector<Entry> getLiveEntries() {
+               Vector<Entry> liveEntries=new Vector<Entry>();
+               for(Entry entry: entries)
+                       if (entry.isLive())
+                               liveEntries.add(entry);
+
+               if (seqnumlive)
+                       liveEntries.add(new LastMessage(this, machineid, seqnum));
+               
+               return liveEntries;
+       }
+       
        long getSequenceNumber() {
                return seqnum;
        }
index d4da5db..c2adbc9 100644 (file)
@@ -1,6 +1,7 @@
 package iotcloud;
 import java.util.HashMap;
 import java.util.Arrays;
+import java.util.Vector;
 import javax.crypto.spec.*;
 import javax.crypto.*;
 
@@ -15,6 +16,7 @@ final public class Table {
        private long localmachineid;
   private TableStatus lastTableStatus;
   static final int FREE_SLOTS = 10;
+  static final int FORCED_RESIZE_INCREMENT = 20;
   
        public Table(String baseurl, String password, long _localmachineid) {
                localmachineid=_localmachineid;
@@ -63,21 +65,74 @@ final public class Table {
        }
 
        public IoTString put(IoTString key, IoTString value) {
+    while(true) {
+      KeyValue oldvalue=table.get(key);
+      if (tryput(key, value)) {
+        return oldvalue.getValue();
+      }
+    }
+  }
+
+  private boolean tryput(IoTString key, IoTString value) {
     Slot s=new Slot(sequencenumber+1, localmachineid, buffer.getSlot(sequencenumber).getHMAC());
+    boolean forcedresize = false;
 
+    long seqn = buffer.getOldestSeqNum();
+    
     if ((numslots - buffer.size()) < FREE_SLOTS) {
       //have to check whether we have enough free slots
-      long seqn = buffer.getNewestSeqNum() + 1 - numslots;
-      for(int i=0; i < FREE_SLOTS; i++, seqn--) {
+      seqn = buffer.getNewestSeqNum() + 1 - numslots;
+      for(int i=0; i < FREE_SLOTS; i++, seqn++) {
         Slot prevslot=buffer.getSlot(seqn);
         if (!prevslot.isLive())
           continue;
-        
+        Vector<Entry> liveentries = prevslot.getLiveEntries();
+        for(Entry liveentry:liveentries) {
+          if (s.hasSpace(liveentry))
+            s.addEntry(liveentry);
+          else if (i==0) {
+            if (s.canFit(liveentry))
+              s.addEntry(liveentry);
+            else
+              forcedresize = true;
+          }
+        }
       }
     }
+    KeyValue kv=new KeyValue(s, key, value);
+    boolean insertedkv=false;
+    if (s.hasSpace(kv)) {
+      s.addEntry(kv);
+      insertedkv=true;
+    }
 
-
-    return null;
+    long newestseqnum=buffer.getNewestSeqNum();
+    search:
+    for(;seqn<=newestseqnum;seqn++) {
+      Slot prevslot=buffer.getSlot(seqn);
+      if (!prevslot.isLive())
+        continue;
+      Vector<Entry> liveentries = prevslot.getLiveEntries();
+      for(Entry liveentry:liveentries) {
+        if (s.hasSpace(liveentry))
+          s.addEntry(liveentry);
+        else
+          break search;
+      }
+    }
+    
+    int max=0;
+    if (forcedresize)
+      max = numslots + FORCED_RESIZE_INCREMENT;
+    Slot[] array=cloud.putSlot(s, max);
+    if (array == null)
+      array = new Slot[] {s};
+    else
+      insertedkv=false;
+    
+               validateandupdate(array); // update data structure
+    
+    return insertedkv;
        }
 
        private void validateandupdate(Slot[] newslots) {