diff --git a/DAS/block.py b/DAS/block.py index aa5fe01..1cea8c0 100644 --- a/DAS/block.py +++ b/DAS/block.py @@ -6,8 +6,6 @@ from bitarray.util import zeros class Block: - blockSize = 0 - data = bitarray() def __init__(self, blockSize): self.blockSize = blockSize diff --git a/DAS/configuration.py b/DAS/configuration.py index 91df16f..d3647a4 100644 --- a/DAS/configuration.py +++ b/DAS/configuration.py @@ -4,7 +4,6 @@ import configparser class Configuration: - deterministic = 0 def __init__(self, fileName): @@ -33,6 +32,7 @@ class Configuration: self.numberRuns = int(config.get("Advanced", "numberRuns")) self.deterministic = config.get("Advanced", "deterministic") + self.dumpXML = config.get("Advanced", "dumpXML") if self.nvStop < (self.blockSizeStart*4): print("ERROR: The number of validators cannot be lower than the block size * 4") diff --git a/DAS/observer.py b/DAS/observer.py index ad9052b..515fe09 100644 --- a/DAS/observer.py +++ b/DAS/observer.py @@ -4,18 +4,16 @@ from DAS.block import * class Observer: - block = [] - rows = [] - columns = [] - goldenData = [] - broadcasted = [] - config = [] - logger = [] - def __init__(self, logger, config): self.config = config self.format = {"entity": "Observer"} self.logger = logger + self.block = [] + self.rows = [] + self.columns = [] + self.goldenData = [] + self.broadcasted = [] + def reset(self): self.block = [0] * self.config.blockSize * self.config.blockSize diff --git a/DAS/results.py b/DAS/results.py index 8468b09..174e5e9 100644 --- a/DAS/results.py +++ b/DAS/results.py @@ -1,17 +1,46 @@ #!/bin/python3 +import os +from xml.dom import minidom +from dicttoxml import dicttoxml class Result: - config = [] - missingVector = [] - blockAvailable = -1 - def __init__(self, config): - self.config = config + def __init__(self, shape): + self.shape = shape self.blockAvailable = -1 + self.tta = -1 self.missingVector = [] - - def addMissing(self, missingVector): + def populate(self, shape, missingVector): + self.shape = shape self.missingVector = missingVector + missingSamples = missingVector[-1] + if missingSamples == 0: + self.blockAvailable = 1 + self.tta = len(missingVector) + else: + self.blockAvailable = 0 + self.tta = -1 + + def dump(self, execID): + if not os.path.exists("results"): + os.makedirs("results") + if not os.path.exists("results/"+execID): + os.makedirs("results/"+execID) + resd1 = self.shape.__dict__ + resd2 = self.__dict__.copy() + resd2.pop("shape") + resd1.update(resd2) + resXml = dicttoxml(resd1) + xmlstr = minidom.parseString(resXml) + xmlPretty = xmlstr.toprettyxml() + filePath = "results/"+execID+"/nbv-"+str(self.shape.numberValidators)+\ + "-bs-"+str(self.shape.blockSize)+\ + "-nd-"+str(self.shape.netDegree)+\ + "-fr-"+str(self.shape.failureRate)+\ + "-chi-"+str(self.shape.chi)+\ + "-r-"+str(self.shape.run)+".xml" + with open(filePath, "w") as f: + f.write(xmlPretty) diff --git a/DAS/shape.py b/DAS/shape.py index 2918422..84efc1e 100644 --- a/DAS/shape.py +++ b/DAS/shape.py @@ -1,16 +1,12 @@ #!/bin/python3 class Shape: - numberValidators = 0 - failureRate = 0 - blockSize = 0 - netDegree = 0 - chi = 0 - def __init__(self, blockSize, numberValidators, failureRate, chi, netDegree): + def __init__(self, blockSize, numberValidators, failureRate, chi, netDegree, run): + self.run = run self.numberValidators = numberValidators - self.failureRate = failureRate self.blockSize = blockSize + self.failureRate = failureRate self.netDegree = netDegree self.chi = chi diff --git a/DAS/simulator.py b/DAS/simulator.py index 676b891..cc02a6b 100644 --- a/DAS/simulator.py +++ b/DAS/simulator.py @@ -10,19 +10,16 @@ from DAS.validator import * class Simulator: - proposerID = 0 - logLevel = logging.INFO - validators = [] - glob = [] - result = [] - shape = [] - logger = [] - format = {} def __init__(self, shape): self.shape = shape self.format = {"entity": "Simulator"} self.result = Result(self.shape) + self.validators = [] + self.logger = [] + self.logLevel = logging.INFO + self.proposerID = 0 + self.glob = [] def initValidators(self): self.glob = Observer(self.logger, self.shape) @@ -87,6 +84,7 @@ class Simulator: def resetShape(self, shape): self.shape = shape + self.result = Result(self.shape) for val in self.validators: val.shape.failureRate = shape.failureRate val.shape.chi = shape.chi @@ -120,19 +118,16 @@ class Simulator: missingRate = missingSamples*100/expected self.logger.debug("step %d, missing %d of %d (%0.02f %%)" % (steps, missingSamples, expected, missingRate), extra=self.format) if missingSamples == oldMissingSamples: + #self.logger.info("The block cannot be recovered, failure rate %d!" % self.shape.failureRate, extra=self.format) + missingVector.append(missingSamples) break elif missingSamples == 0: + #self.logger.info("The entire block is available at step %d, with failure rate %d !" % (steps, self.shape.failureRate), extra=self.format) + missingVector.append(missingSamples) break else: steps += 1 - self.result.addMissing(missingVector) - if missingSamples == 0: - self.result.blockAvailable = 1 - self.logger.debug("The entire block is available at step %d, with failure rate %d !" % (steps, self.shape.failureRate), extra=self.format) - return self.result - else: - self.result.blockAvailable = 0 - self.logger.debug("The block cannot be recovered, failure rate %d!" % self.shape.failureRate, extra=self.format) - return self.result + self.result.populate(self.shape, missingVector) + return self.result diff --git a/DAS/validator.py b/DAS/validator.py index 950fdea..491f3da 100644 --- a/DAS/validator.py +++ b/DAS/validator.py @@ -20,11 +20,6 @@ class Neighbor: class Validator: - ID = 0 - amIproposer = 0 - shape = [] - format = {} - logger = [] def __repr__(self): return str(self.ID) diff --git a/config.das b/config.ini similarity index 96% rename from config.das rename to config.ini index f5d608e..052f754 100644 --- a/config.das +++ b/config.ini @@ -25,3 +25,4 @@ chiStep = 2 deterministic = 0 numberRuns = 2 +dumpXML = 1 diff --git a/study.py b/study.py index ae27e5c..68663b8 100644 --- a/study.py +++ b/study.py @@ -1,6 +1,6 @@ #! /bin/python3 -import time, sys +import time, sys, random, copy from DAS import * @@ -10,11 +10,15 @@ def study(): exit(1) config = Configuration(sys.argv[1]) - sim = Simulator(config) + shape = Shape(0, 0, 0, 0, 0, 0) + sim = Simulator(shape) sim.initLogger() results = [] simCnt = 0 + now = datetime.now() + execID = now.strftime("%Y-%m-%d_%H-%M-%S_")+str(random.randint(100,999)) + sim.logger.info("Starting simulations:", extra=sim.format) start = time.time() @@ -28,18 +32,23 @@ def study(): if not config.deterministic: random.seed(datetime.now()) - shape = Shape(blockSize, nv, fr, chi, netDegree) + shape = Shape(blockSize, nv, fr, chi, netDegree, run) sim.resetShape(shape) sim.initValidators() sim.initNetwork() result = sim.run() - sim.logger.info("Run %d, FR: %d %%, Chi: %d, BlockSize: %d, Nb.Val: %d, netDegree: %d ... Block Available: %d" % (run, fr, chi, blockSize, nv, netDegree, result.blockAvailable), extra=sim.format) - results.append(result) + sim.logger.info("Shape: %s ... Block Available: %d" % (str(sim.shape.__dict__), result.blockAvailable), extra=sim.format) + results.append(copy.deepcopy(result)) simCnt += 1 end = time.time() sim.logger.info("A total of %d simulations ran in %d seconds" % (simCnt, end-start), extra=sim.format) + if config.dumpXML: + for res in results: + res.dump(execID) + sim.logger.info("Results dumped into results/%s/" % (execID), extra=sim.format) + study()