From 2fc4a963fbedd8b930a7d797cfb7b24d246bf88b Mon Sep 17 00:00:00 2001 From: Arunima Chaudhuri Date: Mon, 29 Jan 2024 19:50:01 +0530 Subject: [PATCH] add graphs for number of rows and columns repaired Signed-off-by: Arunima Chaudhuri --- DAS/results.py | 4 ++++ DAS/validator.py | 26 ++++++++++++++++---------- DAS/visualizor.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/DAS/results.py b/DAS/results.py index 628e8a8..6fbf3a4 100644 --- a/DAS/results.py +++ b/DAS/results.py @@ -20,6 +20,8 @@ class Result: self.msgSentCount = [0] * shape.numberNodes self.msgRecvCount = [0] * shape.numberNodes self.sampleRecvCount = [0] * shape.numberNodes + self.restoreRowCount = [0] * shape.numberNodes + self.restoreColumnCount = [0] * shape.numberNodes def copyValidators(self, validators): """Copy information from simulator.validators to result.""" @@ -28,6 +30,8 @@ class Result: self.msgSentCount[i] = validators[i].msgSentCount self.msgRecvCount[i] = validators[i].msgRecvCount self.sampleRecvCount[i] = validators[i].sampleRecvCount + self.restoreRowCount[i] = validators[i].restoreRowCount + self.restoreColumnCount[i] = validators[i].restoreColumnCount def populate(self, shape, config, missingVector): """It populates part of the result data inside a vector.""" diff --git a/DAS/validator.py b/DAS/validator.py index eaf7686..f2d8e93 100644 --- a/DAS/validator.py +++ b/DAS/validator.py @@ -60,6 +60,8 @@ class Validator: self.msgRecvCount = 0 self.sampleSentCount = 0 self.sampleRecvCount = 0 + self.restoreRowCount = 0 + self.restoreColumnCount = 0 self.logger = logger if self.shape.chi < 1: self.logger.error("Chi has to be greater than 0", extra=self.format) @@ -268,21 +270,23 @@ class Validator: def checkSegmentToNeigh(self, rID, cID, neigh): """Check if a segment should be sent to a neighbor.""" - if (neigh.sent | neigh.received).count(1) >= self.sendLineUntil: - return False # sent enough, other side can restore - i = rID if neigh.dim else cID - if not neigh.sent[i] and not neigh.received[i] : - return True + if not self.amImalicious: + if (neigh.sent | neigh.received).count(1) >= self.sendLineUntil: + return False # sent enough, other side can restore + i = rID if neigh.dim else cID + if not neigh.sent[i] and not neigh.received[i] : + return True else: return False # received or already sent def sendSegmentToNeigh(self, rID, cID, neigh): """Send segment to a neighbor (without checks).""" - self.logger.trace("sending %d/%d to %d", rID, cID, neigh.node.ID, extra=self.format) - i = rID if neigh.dim else cID - neigh.sent[i] = 1 - neigh.node.receiveSegment(rID, cID, self.ID) - self.statsTxInSlot += 1 + if not self.amImalicious: + self.logger.trace("sending %d/%d to %d", rID, cID, neigh.node.ID, extra=self.format) + i = rID if neigh.dim else cID + neigh.sent[i] = 1 + neigh.node.receiveSegment(rID, cID, self.ID) + self.statsTxInSlot += 1 def checkSendSegmentToNeigh(self, rID, cID, neigh): """Check and send a segment to a neighbor if needed.""" @@ -516,6 +520,7 @@ class Validator: if (rep.any()): # If operation is based on send queues, segments should # be queued after successful repair. + self.restoreRowCount += 1 for i in range(len(rep)): if rep[i]: self.logger.trace("Rep: %d,%d", id, i, extra=self.format) @@ -535,6 +540,7 @@ class Validator: if (rep.any()): # If operation is based on send queues, segments should # be queued after successful repair. + self.restoreColumnCount += 1 for i in range(len(rep)): if rep[i]: self.logger.trace("Rep: %d,%d", i, id, extra=self.format) diff --git a/DAS/visualizor.py b/DAS/visualizor.py index ab1e57f..50ed89f 100644 --- a/DAS/visualizor.py +++ b/DAS/visualizor.py @@ -70,6 +70,8 @@ class Visualizor: for result in self.results: plotPath = "results/"+self.execID+"/plots/"+str(result.shape) os.makedirs(plotPath, exist_ok=True) + self.plotRestoreRowCount(result, plotPath) + self.plotRestoreColumnCount(result, plotPath) self.plotMessagesSent(result, plotPath) self.plotMessagesRecv(result, plotPath) self.plotSampleRecv(result, plotPath) @@ -81,6 +83,46 @@ class Visualizor: if self.config.saveRCdist: self.plotRowCol(result, plotPath) + def plotRestoreRowCount(self, result, plotPath): + """Plots the restoreRowCount for each node""" + conf = {} + text = str(result.shape).split("-") + conf["textBox"] = "Block Size: "+text[1]+"\nNumber of nodes: "+text[3]\ + +"\nFailure rate: "+text[7]+" \nNetwork degree: "+text[23]+"\nX: "+text[11]+" rows/columns"+"\nMalicious Nodes: "+text[27]+"%" + conf["title"] = "Restore Row Count for Each Node" + conf["type"] = "individual_bar" + conf["legLoc"] = 1 + conf["desLoc"] = 1 + conf["xlabel"] = "Nodes" + conf["ylabel"] = "Restore Row Count" + conf["data"] = result.restoreRowCount + conf["xdots"] = range(result.shape.numberNodes) + conf["path"] = plotPath + "/restoreRowCount.png" + maxi = max(conf["data"]) + conf["yaxismax"] = maxi + plotData(conf) + print("Plot %s created." % conf["path"]) + + def plotRestoreColumnCount(self, result, plotPath): + """Plots the restoreColumnCount for each node""" + conf = {} + text = str(result.shape).split("-") + conf["textBox"] = "Block Size: "+text[1]+"\nNumber of nodes: "+text[3]\ + +"\nFailure rate: "+text[7]+" \nNetwork degree: "+text[23]+"\nX: "+text[11]+" rows/columns"+"\nMalicious Nodes: "+text[27]+"%" + conf["title"] = "Restore Column Count for Each Node" + conf["type"] = "individual_bar" + conf["legLoc"] = 1 + conf["desLoc"] = 1 + conf["xlabel"] = "Nodes" + conf["ylabel"] = "Restore Column Count" + conf["data"] = result.restoreColumnCount + conf["xdots"] = range(result.shape.numberNodes) + conf["path"] = plotPath + "/restoreColumnCount.png" + maxi = max(conf["data"]) + conf["yaxismax"] = maxi + plotData(conf) + print("Plot %s created." % conf["path"]) + def plotSampleRecv(self, result, plotPath): """Plots the percentage sampleRecv for each node""" conf = {}