public static RecoveryCheck CheckMissingRCS(SDSStack.Entry sds) { RecoveryCheck rs = new RecoveryCheck(); rs.predecessorIsConsistent = stack.FindGeneration(sds.Generation - 1).IsFullyConsistent; //sds.IntermediateSDS.inputConsistent; rs.thisIsConsistent = sds.IsFullyConsistent; foreach (var other in Simulation.Neighbors) { var inbound = sds.InboundRCS[other.LinearIndex]; if (inbound != null && inbound.IsFullyConsistent) { continue; } //try get from database: SerialRCS rcs = DB.TryGetInbound(other.InboundRCSStackID.Generation(sds.Generation)); //SerialRCSStack rcsStack = BaseDB.TryGet(other.InboundRCSStackID); if (rcs != null) { sds.InboundRCS[other.LinearIndex] = rcs.Deserialize(); rs.rcsRestoredFromDB++; continue; } rs.missingRCS++; //try to get from neighbor: if (other.IsResponsive) { rs.rcsAvailableFromNeighbor++; //optimisitic guess } } return(rs); }
public static void FetchNeighborUpdate(SDSStack.Entry target, Link neighbor, RCS candidate) { var existing = target.InboundRCS[neighbor.LinearIndex]; bool significant = existing != null && candidate.IC.OneCount < existing.IC.OneCount; if (existing != null && candidate.IC.OneCount > existing.IC.OneCount) { Log.Error("Unable to incorportate RCS from " + neighbor + ": RCS at generation " + target.Generation + " is worse than known"); return; } target.InboundRCS[neighbor.LinearIndex] = candidate; if (significant) { target.SignificantInboundChange = true; } Log.Message(neighbor.Name + ": RCS[" + neighbor.LinearIndex + "] @g" + target.Generation + " IC ones: " + candidate.IC.OneCount); }
public SDSComputation(DateTime applicationBeginDeadline, ExtMessagePack clientMessages, TimeSpan entityLogicTimeout, EntityChange.ExecutionContext ctx) { this.ctx = ctx; generation = ctx.GenerationNumber; Deadline = applicationBeginDeadline; SDSStack stack = Simulation.Stack; SDSStack.Entry input = stack.FindGeneration(generation - 1); if (input == null) { throw new IntegrityViolation("Unable to locate previous SDS at generation " + (generation - 1)); } if (!input.IsFinished) { throw new IntegrityViolation("Previous SDS at generation " + (generation - 1) + " exists but is not finished"); } //if (input.Generation != generation-1) // throw new IntegrityViolation("Generation mismatch"); old = stack.FindGeneration(generation); if (old == null) { throw new IntegrityViolation("Unable to locate original SDS at generation " + generation); } data = new IntermediateSDS(); data.inputConsistent = input.IsFullyConsistent; { using (var ms = new MemoryStream()) { input.SDS.AddToStream(ms); clientMessages.AddToStream(ms); ms.Seek(0, SeekOrigin.Begin); data.inputHash = new Digest(SHA256.Create().ComputeHash(ms), true); } } //old bad or dont exist, new maybe good if (clientMessages.HasBeenDiscarded) { throw new IntegrityViolation("Available client messages are incomplete but recorded messages have been discarded"); } this.clientMessages = clientMessages.MessagePack; if (old.IntermediateSDS != null && old.IntermediateSDS.inputHash == data.inputHash) { data = old.IntermediateSDS; return; } data.entities = new EntityPool(input.SDS.FinalEntities, ctx); data.localChangeSet = new EntityChangeSet(); data.ic = input.SDS.IC.Clone(); if (!this.clientMessages.Completed) { Log.Message("Client messages are not complete for generation " + generation + ", setting everything inconsistent"); data.ic.SetAllOne(); } //bool doSendClientMessages = freshClientMessages != null && freshClientMessages.ArchivedGeneration == generation; errors = data.localChangeSet.Evolve(input.SDS.FinalEntities, this.clientMessages.Messages, data.ic, entityLogicTimeout, ctx); if (errors == null && input.IsFullyConsistent && data.ic.OneCount != 0 && clientMessages.MessagePack.Completed) { throw new IntegrityViolation("Input is fully consistent, and there are no errors. IC should have remaining empty"); } InconsistencyCoverage untrimmed = data.ic.Grow(false); if (untrimmed.Size != InconsistencyCoverage.CommonResolution + 2) { throw new IntegrityViolation("IC of unsupported size: " + untrimmed.Size); } data.ic = untrimmed.Sub(new Int3(1), new Int3(InconsistencyCoverage.CommonResolution)); foreach (var n in Simulation.Neighbors) { IntBox remoteBox = n.ICExportRegion; var ic = untrimmed.Sub(remoteBox); RCS rcs = new RCS(new EntityChangeSet(data.localChangeSet, n.WorldSpace, ctx), ic); var oID = n.GetOutboundRCSID(Generation); if (generation >= n.OldestGeneration) { Log.Message("Dispatched " + oID + ", IC ones=" + ic.OneCount); n.Set(oID.ToString(), new RCS.Serial(rcs, generation)); if (rcs.IsFullyConsistent) { n.UploadToDB(generation, rcs); } } else { Log.Error("Recomputed generation, but remote shard will not want generated RCS"); } } data.localChangeSet.FilterByTargetLocation(Simulation.MySpace, ctx); }
private static void RunStupidModel() { int gridRes = 100; //2d resolution //each grid cell can 'see' +- 4 cells in all direction. All 'motion' is done via communication //hence R = 4 / gridRes float r = 4.5f / gridRes; BaseDB.ConfigContainer config = new BaseDB.ConfigContainer() { extent = Int3.One, r = r, m = r * 0.5f }; Simulation.Configure(new ShardID(Int3.Zero, 0), config, true); Vec3 outlierCoords = Simulation.MySpace.Min; var ctx = new SimulationContext(true); var intermediate0 = new IntermediateSDS(); intermediate0.entities = new EntityPool(MakeGrid2D(gridRes), ctx); //EntityTest.RandomDefaultPool(100); intermediate0.ic = InconsistencyCoverage.NewCommon(); intermediate0.inputConsistent = true; intermediate0.localChangeSet = new EntityChangeSet(); SDSStack.Entry root = new SDSStack.Entry( new SDS(0, intermediate0.entities.ToArray(), intermediate0.ic), intermediate0); //Assert.IsTrue(root.IsFullyConsistent); SDSStack stack = Simulation.Stack; stack.ResetToRoot(root); for (int i = 0; i < 13; i++) { //Assert.IsNotNull(stack.NewestSDS.FinalEntities, i.ToString()); var temp = stack.AllocateGeneration(i + 1); ctx.SetGeneration(i + 1); var comp = new SDSComputation(new DateTime(), ExtMessagePack.CompleteBlank, TimeSpan.FromMilliseconds(10), ctx); //ComputationTests.AssertNoErrors(comp, "comp"); //Assert.IsTrue(comp.Intermediate.inputConsistent); var sds = comp.Complete(); stack.Insert(sds); //Assert.IsTrue(sds.IsFullyConsistent); //Assert.AreEqual(sds.FinalEntities.Length, gridRes * gridRes); int numBugs = 0; int numPredators = 0; int numConflicts = 0; float totalFood = 0; foreach (var e in sds.Item1.FinalEntities) { Habitat h = (Habitat)Helper.Deserialize(e.SerialLogicState); if (h.bug.HasAnimal) { numBugs++; } if (h.predator.HasAnimal) { numPredators++; if (h.bug.HasAnimal) { numConflicts++; } } totalFood += h.food; } Console.WriteLine("Population: b=" + numBugs + ", p=" + numPredators + ", c=" + numConflicts + "; Food=" + totalFood); } }
public static void FetchNeighborUpdate(SDSStack.Entry target, Link neighbor, RCS.SerialData data) { FetchNeighborUpdate(target, neighbor, new RCS(data)); }