From 6f22fd1ec2c32c8f6de192072504b1d11a536bf6 Mon Sep 17 00:00:00 2001
From: Daniel <dl3g19@soton.ac.uk>
Date: Mon, 26 Apr 2021 19:16:39 +0100
Subject: [PATCH] Better concurrency and debugging implemented, code has been
 tested with r=3, n=5 without problems

---
 Controller$1AcksReceived.class        | Bin 562 -> 562 bytes
 Controller$1RequireHandle.class       | Bin 0 -> 523 bytes
 Controller$RebalanceThread.class      | Bin 890 -> 890 bytes
 Controller$RequireHandle.class        | Bin 0 -> 477 bytes
 Controller.class                      | Bin 16856 -> 17175 bytes
 Controller.java                       | 100 +++++++++++++++++---------
 Dstore.class                          | Bin 10646 -> 11759 bytes
 Dstore.java                           |  43 +++++++----
 DstoreConnection$ReceiveContext.class | Bin 3277 -> 3338 bytes
 DstoreConnection.class                | Bin 3634 -> 3903 bytes
 DstoreConnection.java                 |  19 ++---
 DstoreDisconnectException.class       | Bin 291 -> 729 bytes
 DstoreDisconnectException.java        |   4 +-
 Execute.sh                            |  13 ++++
 javac.20210419_161632.args            |   1 -
 15 files changed, 122 insertions(+), 58 deletions(-)
 create mode 100644 Controller$1RequireHandle.class
 create mode 100644 Controller$RequireHandle.class
 create mode 100755 Execute.sh
 delete mode 100644 javac.20210419_161632.args

diff --git a/Controller$1AcksReceived.class b/Controller$1AcksReceived.class
index de2954fe46168c4914df9082fb7b12d7647ea5ed..76f9c7cf8a9ab14a2ee5a059bcaaa1606c87a522 100644
GIT binary patch
delta 37
tcmdnQvWaEGTt-eC22Lhh20kXc$;%iGSREL+m>ehHX4GPIp3KIi0|2N!2sQu!

delta 37
tcmdnQvWaEGTt-ey22Lg`20kY1$;%iGSZx`&nCvFsX4GPIn9Rnc0|2J~2qXXi

diff --git a/Controller$1RequireHandle.class b/Controller$1RequireHandle.class
new file mode 100644
index 0000000000000000000000000000000000000000..43fd8ea05aa94b6a0013a6c872b46ea016bd4086
GIT binary patch
literal 523
zcmX^0Z`VEs1_mnzB~At=24;2!79Ivx1~x_pN$32$lA`>aoYW!}!=Ti{(#)b%kHox`
zoK!{zwvvp@Vif~M1|A=TDr+tV4hBwk1}+{3ZU!Dk27#=^vPAuy#JqHU|D>$c<Pt^(
zHk-`6%o00B24)S-FpzzGJPiB{0*nkCX_+~xd5O8Hj0{3P2z|jNMVWc&)*zKaJPg7N
zB8&{|8DKZ0FfuSkF)}D>AUgn4r)C%<1B-KhN-84*zfWdfs$XetQfg61ViL#~T*3LJ
zMaijdnIH~7!XtVh2QV`5yXGb5<QHe=rTeCqWaOu?GsrM9a3PfOFvx+t$yt<|l$ev4
zmz>JTz~Pr#T;h>mT*An}<C&M2TI8IQSX`W1%*eot5`qj03``6h3=9m+42+-vU|?Wi
z1bL5vK|lZ$`d~gI12=;x10#bN0|SEvC~g=S7(}$Rw=ytlZD(ND(%H(utHr#PL2x5j
zwKxL<gAfA?0|S#Z11FOV10RztgD{gE0}F!$0|NsSgCv6#0|NsKgEWIIgFIM7nn8hq
Rfq{#Gk%5VUfkBah0RXR)Y$5;v

literal 0
HcmV?d00001

diff --git a/Controller$RebalanceThread.class b/Controller$RebalanceThread.class
index 25e1c787e72efd4e87508bd8fff5ab539839fb1a..d2090d52270f1056374e16e0e80540658b15610f 100644
GIT binary patch
delta 43
zcmeyx_KR)9G$zK=lczH^OP*ukX1Kt>$8e5;pW!@%9K$6B6NbwS)(qDs8#B8D07zU7
ASO5S3

delta 43
zcmeyx_KR)9G$zJVlczH^OP*!mW;oBl$8eT`pWz&X9K%Hh6NXC+)(lrC8#B8D07t?N
APyhe`

diff --git a/Controller$RequireHandle.class b/Controller$RequireHandle.class
new file mode 100644
index 0000000000000000000000000000000000000000..d10860a1501c7cd444e6230df4a9437cf76f3b3a
GIT binary patch
literal 477
zcmX^0Z`VEs1_mnzc}@l<24;2!79Ivx1~x_p3FrL0lA`>aoYW$fpwz<B%%W6}#JrT8
zR7M82l8nq^6$3^F9v_4vYc2*322OScE*=JM1|CKRfvm)`ME#t^ymWp4q^#8B5=I6#
zo6Nk-5<5l)W)00Skac`K4EziNj0_xUnK`L>iMgqa3_?B#eZeI~nR)5fAeBNq48jZ|
zj124<U^k>NGB8FlGAL>wI{;IsW*8#_i*tTTDkB5GPi9`KUukYqYEejH637=^!TF^{
z$*FFcAPzsmBYGeQFfwrXr52ZX<QJE)GsrM9a3SOw8F)PN@=}YOa}tY-Q;QiHcu|6f
zL6L!pfrEj8fti63<U0li21bzE85jfvKp_j}Gcs^9h%zuTh%qoQSb)Nvfq_9pOM5E=
zqt<o?b}gN)47^&*TNwm5f>nz%Ffa%)urM$%y<y;FddtAa^o~K8={*B8g9HNu0~3QJ
ZgA|ySW{_oIVBlh4WME>DW{_iG0RTQ2Wd8sF

literal 0
HcmV?d00001

diff --git a/Controller.class b/Controller.class
index f8f4f7fba84db7c0c456b8882bec45b194ed4beb..d9b8ef8a7fda28c4397e7c61a2fd5d1f92209ffe 100644
GIT binary patch
delta 9302
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
Ofq|)tsfMYJK@tFUkU#bS

delta 8813
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

diff --git a/Controller.java b/Controller.java
index de3651a..9b13ac0 100644
--- a/Controller.java
+++ b/Controller.java
@@ -155,8 +155,9 @@ public class Controller {
 					BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
 					String[] message = in.readLine().split(" ");
 					if(message[0].equals("JOIN")) {
-						dstores.put(Integer.parseInt(message[1]), new DstoreConnection(client, timeout));
-						System.out.println("Dstore at " + message[1] + " joined");
+						int portNumber = Integer.parseInt(message[1]);
+						dstores.put(portNumber, new DstoreConnection(client, portNumber, timeout));
+						System.out.println("Dstore at " + portNumber + " joined");
 						try {rebalanceThread.interrupt();} catch(SecurityException e) {e.printStackTrace();}
 					}
 					else {
@@ -189,7 +190,7 @@ public class Controller {
 				}
 				catch(Exception e) {
 					//Log error
-					System.out.println("Controller error while accepting connections!");
+					System.out.println("Error accepting new connection");
 					System.out.println("Continue...");
 				}
 			}
@@ -521,42 +522,43 @@ public class Controller {
 				  //Each file appears rFactor times
 				  //Each file appears at most once on each datastore
 				  //Files are evenly distributed (Dstores differ in capacity by at most 1, no 2 datastores have identical file lists)
-				List<Integer> storeOrder = reshuffle(dstoreFiles.keySet());
+				
+				//First, compile all the received files from all dstores into one list
+				//(This should contain all the elements of index.keySet(), so is probably made redundant)
 				List<String> fileList = new ArrayList<String>();
-				for(Integer i : storeOrder) {
-					for(String s : dstoreFiles.get(i)) {
+				for(List<String> l : dstoreFiles.values()) {
+					for(String s : l) {
 						if(!fileList.contains(s)) {
 							fileList.add(s);
 						}
 					}
 				}
 				
-				Map<Integer,List<String>> requireIndex = new HashMap<Integer,List<String>>();
+				//Create a new index each for files required and files to remove
+				Map<Integer,List<RequireHandle>> requireIndex = new HashMap<Integer,List<RequireHandle>>();
 				Map<Integer,List<String>> removeIndex = new HashMap<Integer,List<String>>();
 				int pos = 0;
 				int storeSize = (int) Math.ceil((fileList.size() * rFactor) / dstores.size());
 				for(Integer i : dstoreFiles.keySet()) {
-					requireIndex.put(i, new ArrayList<String>());
+					requireIndex.put(i, new ArrayList<RequireHandle>());
 					removeIndex.put(i, new ArrayList<String>());
 				}
-				Iterator<Integer> it = null;
+				
+				//Insert files into the new indexes. These are allocated according to the new store order
+				List<Integer> storeOrder;
+				Iterator<Integer> it;
 				for(String file : fileList) {
+					storeOrder = reshuffle(dstoreFiles.keySet());
+					it = storeOrder.iterator();
 					for(int j=0; j<rFactor; j++) {
-						if(it == null || !it.hasNext()) {
-							it = storeOrder.iterator();
-						}
 						//If indexed dstore does not have the file, add it to its requireIndex entry
 						Integer thisStore = it.next();
 						if(!dstoreFiles.get(thisStore).contains(file)) {
-							requireIndex.get(thisStore).add(file);
+							requireIndex.get(thisStore).add(new RequireHandle(file));
 						}
 					}
 					//Dstores not chosen in the above loop must have an entry added to removeIndex, if they have the file
-					for(int j=0; j<(requireIndex.size() - rFactor); j++) {
-						if(it == null || !it.hasNext()) {
-							it = storeOrder.iterator();
-						}
-						
+					while(it.hasNext()) {
 						Integer thisStore = it.next();
 						if(dstoreFiles.get(thisStore).contains(file)) {
 							removeIndex.get(thisStore).add(file);
@@ -564,6 +566,7 @@ public class Controller {
 					}
 				}
 				
+				//This class acts as a holder for a modifiable integer value, so that threads can synchronize on its lock
 				class AcksReceived {
 					int value;
 					public AcksReceived() {
@@ -576,24 +579,31 @@ public class Controller {
 						return value;
 					}
 				}
+				
+				//For each dstore, compile a new message based on the contents of the indexes then send this message and receive a reply
 				AcksReceived acksReceived = new AcksReceived();
-				for(Integer thisStore : storeOrder) {
+				for(Integer thisStore : dstoreFiles.keySet()) {
+					//Compose files to send
 					List<String> sendMessages = new ArrayList<String>();
 					for(String file : dstoreFiles.get(thisStore)) {
-						if(isEmptyListMap(requireIndex)) break;
+						//All files required by other dstores are getting sent = no need for the following computation
+						if(allHandled(requireIndex)) break;
 						
 						String fileMessage = "";
 						for(Integer otherStore : requireIndex.keySet()) {
 							if(thisStore.equals(otherStore)) continue;
-							for(String otherFile : requireIndex.get(otherStore)) {
-								if(file.equals(otherFile)) {
-									requireIndex.get(otherStore).remove(otherFile);
-									fileMessage = fileMessage + " " + otherStore.toString();
+							for(RequireHandle otherHandle : requireIndex.get(otherStore)) {
+								if(file.equals(otherHandle.filename)) {
+									if(!otherHandle.handled) {
+										//Another store requires a file that this store has - send it there
+										otherHandle.handled = true;
+										fileMessage = fileMessage + " " + otherStore.toString();
+									}
 									break;
 								}
 							}
 						}
-						if(fileMessage.equals("")) continue;
+						if(fileMessage.equals("")) continue; //No files to send
 						fileMessage = file + " " + (fileMessage.trim().split(" ").length) + fileMessage;
 						sendMessages.add(fileMessage);
 					}
@@ -602,6 +612,7 @@ public class Controller {
 					for(String s : sendMessages) {
 						message = message + " " + s;
 					}
+					//Compose files to remove
 					message = message + " " + removeIndex.get(thisStore).size();
 					for(String f : removeIndex.get(thisStore)) {
 						message = message + " " + f;
@@ -611,7 +622,8 @@ public class Controller {
 					String finalMessage = message;
 					new Thread(() -> {
 						try {
-							String returnMessage = dstores.get(thisStore).sendAndReceive(finalMessage, "REBALANCE_COMPLETE");
+							DstoreConnection connection = dstores.get(thisStore);
+							String returnMessage = connection.sendAndReceive(finalMessage, "REBALANCE_COMPLETE");
 							if(!returnMessage.equals("REBALANCE_COMPLETE")) {
 								//Log error
 								System.out.println("Dstore " + thisStore + " should have sent REBALANCE_COMPLETE but Controller received " + returnMessage);
@@ -619,10 +631,18 @@ public class Controller {
 							
 							synchronized(acksReceived) {
 								acksReceived.incr();
-								if(acksReceived.getValue() == storeOrder.size()) {
+								if(acksReceived.getValue() == dstoreFiles.size()) {
 									acksReceived.notifyAll();
 								}
 							}
+							
+							for(int i=0; i<requireIndex.get(thisStore).size(); i++) {
+								returnMessage = connection.receive("STORE_ACK");
+								if(!returnMessage.split(" ")[0].equals("STORE_ACK")) {
+									//Log error
+									System.out.println("Dstore " + thisStore + " should have sent STORE_ACK but Controller received " + returnMessage);
+								}
+							}
 						}
 						catch(DstoreDisconnectException e) {
 							e.printStackTrace();
@@ -636,12 +656,12 @@ public class Controller {
 					try {
 						System.out.println("Waiting for REBALANCE_COMPLETE...");
 						acksReceived.wait(timeout);
-						if(acksReceived.getValue() < storeOrder.size()) {
+						if(acksReceived.getValue() < dstoreFiles.size()) {
 							//Restart rebalance operation
 							System.out.println("Not all REBALANCE_COMPLETEs received. Restarting rebalance operation...");
 							success = false;
 						}
-						else if(acksReceived.getValue() > storeOrder.size()) {
+						else if(acksReceived.getValue() > dstoreFiles.size()) {
 							System.out.println("Too many REBALANCE_COMPLETEs received");
 						}
 					}
@@ -655,8 +675,8 @@ public class Controller {
 						Iterator<Integer> jt = requireIndex.keySet().iterator();
 						while(jt.hasNext()) {
 							Integer dstore = jt.next();
-							for(String file : requireIndex.get(dstore)) {
-								index.get(file).addStoredBy(Integer.valueOf(dstore), false);
+							for(RequireHandle handle : requireIndex.get(dstore)) {
+								index.get(handle.filename).addStoredBy(Integer.valueOf(dstore), false);
 							}
 							for(String file : removeIndex.get(dstore)) {
 								index.get(file).removeStoredBy(Integer.valueOf(dstore));
@@ -721,10 +741,20 @@ public class Controller {
 		return list;
 	}
 	
-	<T,U> boolean isEmptyListMap(Map<T,List<U>> map) {
-		for(List<U> list : map.values()) {
-			if(!list.isEmpty()) {
-				return false;
+	//Helper class for rebalance method - contains a filename and a boolean which is true if a dstore is going to send this file
+	protected class RequireHandle {
+		public String filename;
+		public boolean handled;
+		public RequireHandle(String filename) {
+			this.filename = filename;
+			handled = false;
+		}
+	}
+	
+	boolean allHandled(Map<Integer,List<RequireHandle>> map) {
+		for(List<RequireHandle> list : map.values()) {
+			for(RequireHandle handle : list) {
+				if(!handle.handled) return false;
 			}
 		}
 		return true;
diff --git a/Dstore.class b/Dstore.class
index ff1e5b46bfd884be9e7581f53b80d4c57d1bce07..18d98f5ac91d2e18bbf60ed629b2f407af49e0ce 100644
GIT binary patch
delta 6516
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

delta 5444
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
BzuN!+

diff --git a/Dstore.java b/Dstore.java
index f9c6770..4bdde39 100644
--- a/Dstore.java
+++ b/Dstore.java
@@ -7,6 +7,8 @@ import java.util.List;
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
 
 public class Dstore {
 	protected int port; //Port to listen on
@@ -68,8 +70,8 @@ public class Dstore {
 	}
 	
 	public void start() {
-		try {
-			controllerSocket = new Socket(InetAddress.getLocalHost(), cport);
+		try(Socket controllerSocket = new Socket(InetAddress.getLocalHost(), cport)) {
+			this.controllerSocket = controllerSocket;
 			controllerIn = new BufferedReader(new InputStreamReader(controllerSocket.getInputStream()));
 			controllerOut = new PrintWriter(controllerSocket.getOutputStream());
 			controllerOut.println("JOIN " + port);
@@ -151,8 +153,10 @@ public class Dstore {
 				writer.close();
 				
 				//Send STORE_ACK message to the Controller
-				controllerOut.println("STORE_ACK " + filename);
-				controllerOut.flush();
+				synchronized(controllerOut) {
+					controllerOut.println("STORE_ACK " + filename);
+					controllerOut.flush();
+				}
 				
 				if(fileSizes.containsKey(filename)) fileSizes.remove(filename);
 				fileSizes.put(filename, Long.valueOf(filesize));
@@ -211,14 +215,18 @@ public class Dstore {
 				
 				if(Files.deleteIfExists(path)) {
 					//Send REMOVE_ACK message to client (the controller)
-					controllerOut.println("REMOVE_ACK " + filename);
+					synchronized(controllerOut) {
+						controllerOut.println("REMOVE_ACK " + filename);
+						controllerOut.flush();
+					}
 				}
 				else {
 					//Send DOES NOT EXIST error
-					controllerOut.println("ERROR DOES_NOT_EXIST " + filename);
+					synchronized(controllerOut) {
+						controllerOut.println("ERROR DOES_NOT_EXIST " + filename);
+						controllerOut.flush();
+					}
 				}
-				
-				controllerOut.flush();
 			}
 			catch(IOException e) {
 				e.printStackTrace();
@@ -234,8 +242,10 @@ public class Dstore {
 				message = message + " " + file.getName();
 			}
 			if(message.equals("")) message = "ERROR_EMPTY";
-			controllerOut.println(message.trim());
-			controllerOut.flush();
+			synchronized(controllerOut) {
+				controllerOut.println(message.trim());
+				controllerOut.flush();
+			}
 		}).start();
 	}
 	
@@ -253,6 +263,7 @@ public class Dstore {
 			}
 			System.out.println("Interpreting message:" + tmessage);
 			int numberToSend = Integer.parseInt(message[1]);
+			int totalReceivers = 0;
 			index = 2;
 			filesToSend = new HashMap<Integer,List<String>>();
 			for(int i=0; i<numberToSend; i++) {
@@ -260,6 +271,7 @@ public class Dstore {
 				index++;
 				
 				int numberOfReceivers = Integer.parseInt(message[index]);
+				totalReceivers += numberOfReceivers;
 				index++;
 				for(int j=0; j<numberOfReceivers; j++) {
 					Integer receiver = Integer.parseInt(message[index]);
@@ -281,6 +293,7 @@ public class Dstore {
 			System.out.println("Interpreting complete, will send " + numberToSend + " and remove " + numberToRemove);
 			
 			//Send each file to send to the Dstore at the specified port number
+			CyclicBarrier barrier = new CyclicBarrier(totalReceivers + 1);
 			for(Integer dstore : filesToSend.keySet()) {
 				for(String filename : filesToSend.get(dstore)) {
 					new Thread(() -> {
@@ -314,9 +327,13 @@ public class Dstore {
 						catch(IOException e) {
 							e.printStackTrace();
 						}
+						finally {
+							try {barrier.await();} catch(Exception e) {}
+						}
 					}).start();
 				}
 			}
+			try {barrier.await((long) timeout, TimeUnit.MILLISECONDS);} catch(Exception e) {e.printStackTrace();}
 			
 			//Remove each file to remove from fileFolder
 			for(String filename : filesToRemove) {
@@ -325,8 +342,10 @@ public class Dstore {
 			}
 			
 			//Send REBALANCE_COMPLETE message to client (the controller)
-			controllerOut.println("REBALANCE_COMPLETE");
-			controllerOut.flush();
+			synchronized(controllerOut) {
+				controllerOut.println("REBALANCE_COMPLETE");
+				controllerOut.flush();
+			}
 			System.out.println("Sent message REBALANCE_COMPLETE");
 			//TO DO: WAIT FOR RESPONSES BEFORE SENDING REBALANCE_COMPLETE
 		}).start();
diff --git a/DstoreConnection$ReceiveContext.class b/DstoreConnection$ReceiveContext.class
index 29a6f8871a554ee11deeab64ee52990e0810f08f..6276604e77c845f0e2b76c24946dc27deae658f0 100644
GIT binary patch
delta 1418
zcmX>r*(Jqw>ff$?3=9lb3@bKr<ulbYGT8Aj*fTgVGH@oAC1&O%Cgr3uGB8GQGB7eY
z@h~_uxG*vZr(_l<=jY|6CYQKYB&QaXWaj5FGD!Ql6qn=|rMh5BT5~YCF)}bJa4~o=
zc(OBi@i2HZ_%JdEWF?j*>gOcprRxWm6lLb6GcruBVm9LNVDRH%@Mj2^yoFhnEr^F9
zm?32HeP&tbFotk;h6o;pNQMAL20pOn(vr*^eV@$Y5=I8*#FP|nhA@U`9)=i(SVjhx
z;>@a4Mh0dLO;3<;JP$(xL*it67DZl8hGd2mc7{|QhBSus$t_HV@*v-3@-SpEWHU0b
z6yz6`FfuTD3NbJ;<nl1&G2~CqVv(8L#4MuXsp$i@7Rk-lTnvQ_MeGd4JPaiarHl;1
zlNT}xPyWcHWWvS3#Zb<}P{F{*$iSADUy_+t$<9#4$RG?hA~Rp#(;psuTnv>AH9QQp
zlOM8(Ftan%Pc~qdW3FSUnf!|-gRy;bGHWqkKNrIUhKcM9lXw^=Gfdh1gq4F)W;z!G
z3&RW^hE4`Pel~_#Tnw`r=CCu&1vz@&WDfQtEDIPJ6enL`7v)k&E6UGR0C{clV|Epm
zC5#NJll$3Z`HEG1^7FGx3)mT!F*3-3geC`bII}h~Ffuevp3PyX+RVVfAjZJTz`)SW
zz{$|Vz{k+bAi~hcAkWaxz{t?TU;|e9k;B9kq>_(;nSp^}5(7KKWClKlDGaR)3=BdH
zjQ<(<7?{`@SlAi37#P_Z+87uav>EuoI-@wXWDz=NFbFd2WRPIk#lXnW0adY(Q@I|b
zf{THPfq`K!gCN5`u(`|(jDiA8AiskQVqjpJ!@$hI!N9;M!04m3g@JhsgYh;7b06*F
z48kBT^Hv615WR)Lalh6U2L59VE+9%<$aNcoJG0R?2H#l>Mi2#o+B+FSnHa*Myqyg7
zQH%@%MoSn3p(4yX8RD22!Wn(EkNuyqi6KcFBA&5}A%}rs8$*GX_ErW_tt|`^kv@k&
z)Ha4P?Ze9%IDEAa>+E07P~@Y%jiFjgNEo{+KkdW1`<FBLfK)YTF>YlL<pUXlFl+Kf
zE_ueX$sf5y>w6fcGR$CLV3@%$8%#4Wv@$GUsASm0u$uvtulF$=1k)h#V+?f+*BKr#
zJZ4~Ec+Bt|OoPPVGB7YKU|7unqK`3L0Mp+Y85vm^7#LX?IYBhTTZZ>waV7>(RP-?@
zGcYjBVqmIgn8U!!Fqc7)VIG4d!+ZushJ_4P42u{%7#1_6Gb~}qWLVCS%dmo>fng;>
zE5jCs9)_(9lNq)#%w^aPwsIlE8iu6|YZ+EEY+=~Mu$5sa!#0M)4BHuwF|21e&ai>u
zG{Z)Q3k+Krt}|?9xW}-K;T6MnhPMn`7``)XW%$Rijj^7GVLKx~!wztQC}R-#14?Ed
za=#f|8UHirfjICq_ltqWiJhVHKZ7h5;ky3}GHAkVPV5YA{~5#>*x4Ca7#J8B*csYj
z>Gu}{`+o)|21a%_uoMeJ7Xt$W6GJyc513|T=mn>HCWbx+W`?N@(-@{Q%w%9>n9r~f
VD$c^d$gqfkg<&znQikOWk^tYONSFWs

delta 1391
zcmeB@IxER_>ff$?3=9lb42w5%<uh^HG1#*+IPfqyGB{0s&1|T~!QjHkAna0Hl3$dn
zkdj%PoS&DMnp~2a!o}dm;LgtA!NcIm;5E62#X^>ofsw(7hryS@kCA~hu`Dq&Cow4}
zm63rlik%@~GC!-FxIY6o2SYF;1ET^LLnuQSJ3}}RLj*(Q<i||z9H9)+JPa`mv6GFM
zRoUWs7!nu~C&x0&Iwv!vurs9cFr+cWGBWUGC6*=XmzHGa==)?AmoPFgC#IxuGbA%)
z@GxXDWHB<Z6lYeYGBPl0XnKN#b9fkX8S*CYWme=8Vqjz_;9)3aD4J}|BEzUQnUPr}
z-Un=6PGVlVesD=qW?s5A7XueV2@gXl10N#;TV8%iW?CgXLpdXZFj!?~zP_iwYejNu
zK}lwQ9v4FyLnRMG6-X_AK~ZL2NpMMGa&|~jVsa`MgFi#%WCPX=#-_<LS&R9)xEQ(_
zde|9yc^LW_`Zr6laWKkE;$mQ7n9Re_!obJR#xRwOVH(49c7_=sN6wsV$9_b7HY0<m
zbADb)QGQNNYLP-wYI163S!&8;RSp%#`IEgkv{)80GRRH#<&c{^jl+qxhJlfxcJf^g
zL)AJ41_m((Rt5%!b_Py{4hBAkP6iQ%E(UpqZU#n%dIlS?N@GqFQ;<qN24)5ZhCT*%
zhJFS<h6xM}3=9lH42=I7_!yYj8CcjExEL7O85$WF8MGPrz&ht}YRMvWPGJya*v25i
zu$_UCp&6>;F{g4pNCg)I69WUoE(Sq{-C%Q>85jixm_S|z8N|TAw2*<BfrEj8QIOF`
zYYPMO76#*O4CX%C#~GwIG1v+@Z)0!;2{UhH@ZQbfAGw_&aKF|T2L59VE+9%<C}<l)
z2(!^PhNxK#Mj(Y-7~-^dG9)oEglpA<jf>mKkj}^;V6=om5Gv2SlOdalA)L`i``G^p
zn;2}hcQNEMFn}!5-pU}VwS_?<(&rF}+Qv|<eRw$ohp+Zwo&C!hihQ)UF;r*?31e5~
zr+rv=|8fQ&kg94e#;pwXSj^(GV$nV<$+CYrgQ^uP$c{)WHke(KY=@UKa9goUvK^LW
z-!I9!e<K4QLodTLhM5cu3^N(#fN2JXHim@^Wel4c_Au;cU|`tKa0pC;#E&!hGu&W!
z$nb=Lf#C_mi+V5vB=L@cfng!T8U_%3oZ%vv{=vw^$jZRL$jZnCq8Z*Xd;p6xF@U0N
z5`zi@1H&{1CWaXdybLoL1Q}*ANHWZ3P-K|Hpvf?g!HHo$Ljc19hJ1#F4229!7)lwI
zGBh$QV`yX8$k5BMiD3%EW`_EC3|kl$GOS=&#ITZK8N(`uH4GaWHZyEu*u}7!;RwSP
zhT{xt7)~&(WjMpIj^QH1Mur;<n;7mhY-V`Pu!Z3r!$yW544WAKGi+w$W!S<fz_1mZ
ze##gG{(w?tsM>D^SH}Mg>L3n0iT+|>abjmE`_CZDz{FmUNV*Vl|Njg!Xv*1~*clrC
zGl(&;voo+TFfcH%Gc>}|`!5Fe{|ro^qz{r|VQ6JwU|?csV`vA{j0_#%Y{JCQ$-vAo
kfng%U1coULj103F=0L^ySr`}@<}$D_%wt%<u!unt0AxHpHvj+t

diff --git a/DstoreConnection.class b/DstoreConnection.class
index 78bdda2b66cc70e62e1b5a96c7af9d389228ec03..26f8d2d10198470a3bbf2d10eb9e8a59c8d2a38f 100644
GIT binary patch
delta 2315
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

delta 2119
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

diff --git a/DstoreConnection.java b/DstoreConnection.java
index 4778e99..2db4b30 100644
--- a/DstoreConnection.java
+++ b/DstoreConnection.java
@@ -11,20 +11,24 @@ public class DstoreConnection {
 	protected final int MAX_QUEUE_SIZE = 50;
 	
 	protected Socket socket;
+	protected int port; //Solely used for debugging purposes
 	protected BufferedReader reader;
 	protected PrintWriter writer;
 	protected boolean available;
 	protected List<String> queue;
 	protected int timeout;
+	protected DstoreDisconnectException disconnectException;
 	
-	public DstoreConnection(Socket socket, int timeout) {
+	public DstoreConnection(Socket socket, int port, int timeout) {
 		this.socket = socket;
+		this.port = port;
 		this.timeout = timeout;
 		try {
 			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 			writer = new PrintWriter(socket.getOutputStream());
 			available = true;
 			queue = new ArrayList<String>();
+			disconnectException = new DstoreDisconnectException(port);
 		}
 		catch(IOException e) {
 			e.printStackTrace();
@@ -44,13 +48,13 @@ public class DstoreConnection {
 				if(!available) return "ERROR";
 				writer.println(message);
 				writer.flush();
-				System.out.println("Controller sent " + message);
+				System.out.println("Controller sent " + message + " to port " + port);
 				return localReceive(expectedMessage);
 			}
 			catch(NullPointerException e) {
-				System.out.println("Dstore disconnected");
+				System.out.println("Dstore at port " + port + " disconnected");
 				available = false;
-				throw new DstoreDisconnectException();
+				throw disconnectException;
 			}
 		}
 	}
@@ -91,7 +95,7 @@ public class DstoreConnection {
 				rc.end();
 			}
 			String returnMessage = rc.getReturnMessage();
-			if(returnMessage == null) throw new DstoreDisconnectException();
+			if(returnMessage == null) throw disconnectException;
 			else return returnMessage;
 		}
 		catch(InterruptedException e) {
@@ -151,9 +155,8 @@ public class DstoreConnection {
 					do {
 						message = reader.readLine();
 						if(message == null) {
-							System.out.println("Dstore disconnected");
 							available = false;
-							throw new DstoreDisconnectException();
+							throw disconnectException;
 						}
 						if(expectedMessage != null && !expectedMessage.equals(message.split(" ")[0])) {
 							queue.add(message);
@@ -162,7 +165,7 @@ public class DstoreConnection {
 						}
 					}
 					while(message == null);
-					System.out.println("Controller received " + message);
+					System.out.println("Controller received " + message + " from port " + port);
 					returnMessage = message;
 				}
 				catch(IOException e) {
diff --git a/DstoreDisconnectException.class b/DstoreDisconnectException.class
index f1a70dafe9f2cfe9e9879cbf5b4fc17a31599470..22b4ca5149e1537a79318afa75ce420aba79414b 100644
GIT binary patch
literal 729
zcmX^0Z`VEs1_mnzMIi<T1|}W`W(F2U2Jzg)>{RFcyyV1^@XV47=ls0llEl1{Vnzm0
z4Npy<ti-ZJ{hY+Sbp7CxqRhN>Yc2*h26lD^4ju+h1};VhVT1zLisaOSlFa-(Mg}&U
z%)HDJJCGTeCTNDSGw?7nNV*i4<QJv7WELmq=jEj)mmuk9(eTs^V`N})&QD2YWZ?J7
z%uDqv%}q)z3Q0`LNo8c<3eGPrN=|jl1aahW8l(qu93z8(Q+|F)aY<2Pfp2O_Mt({$
zKO2Jx7lSB+7(0VFC>SId8B{<@As)@lE6dMLh58o~GH!{<CHX~_j0`h0ko*Hx2r<+n
zF)t-2wOGX`KR>&)z#2&zG~kd#P&9^A7NlZP9*v~lKPf9Uxx^YdHlRj0C+6e?XO^T|
zb1+CTGN?g9LLsq4p&-AgM1fHuBe7T^DK#}uAq5`HsVR&MJf3-ZsYT8?iN(dK#q12S
zj0~z6{>SDmb_RJy208pn85!6hVZflsz|FwM00N8*j0~I%ybO#Cd<+Z>>I_T_ObiSR
z+*;DR7#JBCwllD9WME)mWZ-9DVBi8vu`+<t88d?bD5Ww8GJsMn2LmI6FasllB!e_q
O9V3GbgB*hbgCqc<U&;dj

delta 148
zcmcb~x|qrG)W2Q(7#J9=7z8*Nm>3ykT#8Hbi&7Ob5{ng*Qd9F3QZkE^^YijjlS@)l
zxENR%SlJoaco^6jI3@;LGICAqm1APon7Gc<ok5X-lYxZ+1Q;0@8Q2-P85kLO7#J9o
y8JHLt85kJYwS*YAGca#tU|?Wm;ALQ7;9_86U|?WnU}IooU}WH9U|?Wk;0FMD6BiNy

diff --git a/DstoreDisconnectException.java b/DstoreDisconnectException.java
index 085512f..82cd0fd 100644
--- a/DstoreDisconnectException.java
+++ b/DstoreDisconnectException.java
@@ -1,7 +1,7 @@
 import java.lang.Throwable;
 
 public class DstoreDisconnectException extends Exception {
-	public DstoreDisconnectException() {
-		super("Dstore has been disconnected");
+	public DstoreDisconnectException(int port) {
+		super("Dstore at port " + port + " has been disconnected");
 	}
 }
diff --git a/Execute.sh b/Execute.sh
new file mode 100755
index 0000000..0f70e0c
--- /dev/null
+++ b/Execute.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+java Controller 8080 $1 $3 $4 &
+echo $!
+for((i=1; i<=$2; i++)) do
+	sleep 0.2
+	n=$((8080+$i))
+	echo $n
+	s="store$i"
+	java Dstore $n 8080 $3 $s &
+	echo $!
+done
+sleep 2
+java -cp .:client-1.0.0.jar ClientMain 8080 $3
diff --git a/javac.20210419_161632.args b/javac.20210419_161632.args
deleted file mode 100644
index 159b393..0000000
--- a/javac.20210419_161632.args
+++ /dev/null
@@ -1 +0,0 @@
-Controller.java
-- 
GitLab