From 967e3a8a71bf358fb4227fcbe895b69ff1c69d7b Mon Sep 17 00:00:00 2001 From: bdemsky Date: Sat, 23 Jul 2016 20:20:37 -0700 Subject: [PATCH] more code --- src/java/iotcloud/CloudComm.java | 2 +- src/java/iotcloud/Slot.java | 30 +++++++++++++++ src/java/iotcloud/Table.java | 65 +++++++++++++++++++++++++++++--- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/java/iotcloud/CloudComm.java b/src/java/iotcloud/CloudComm.java index ca17ffb..1993a8d 100644 --- a/src/java/iotcloud/CloudComm.java +++ b/src/java/iotcloud/CloudComm.java @@ -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); diff --git a/src/java/iotcloud/Slot.java b/src/java/iotcloud/Slot.java index ff0e901..dc5389e 100644 --- a/src/java/iotcloud/Slot.java +++ b/src/java/iotcloud/Slot.java @@ -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 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(); 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 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 getLiveEntries() { + Vector liveEntries=new Vector(); + 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; } diff --git a/src/java/iotcloud/Table.java b/src/java/iotcloud/Table.java index d4da5db..c2adbc9 100644 --- a/src/java/iotcloud/Table.java +++ b/src/java/iotcloud/Table.java @@ -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 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 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) { -- 2.34.1