public void ClassArray() { FieldCloneClassArrayModel model = new FieldCloneClassArrayModel { Models = new FieldCloneNormalModel[10] }; for (int i = 0; i < 10; i++) { model.Models[i] = new FieldCloneNormalModel() { Age = i, Name = i.ToString() }; } SnapshotOperator.MakeSnapshot(model); for (int i = 5; i < 10; i++) { model.Models[i] = new FieldCloneNormalModel() { Age = i + 100, Name = (i + 100).ToString() }; } var reuslt = SnapshotOperator.Compare(model); var value = (HashSet <FieldCloneNormalModel>)reuslt["Models"].Value; int temp = 5; foreach (var item in value) { Assert.Equal(temp.ToString(), item.Name); Assert.Equal(temp, item.Age); temp++; } }
public void PropSubClassArray() { PropCloneSubNodeModel model = new PropCloneSubNodeModel { Node = new PropCloneNormalModel() { Age = 1, Name = "111" } }; SnapshotOperator.MakeSnapshot(model); model.Node = new PropCloneNormalModel() { Age = 2, Name = "222" }; var result = SnapshotOperator.Compare(model); var value = (Dictionary <string, DiffModel>)(result["Node"].Value); Assert.NotEqual(model.Node.Name, (string)(value["Name"].Value)); Assert.NotEqual(model.Node.Age, (int)(value["Age"].Value)); Assert.Equal("111", (string)(value["Name"].Value)); Assert.Equal(1, (int)(value["Age"].Value)); }
public void NotClassArray() { FieldCloneArrayModel model = new FieldCloneArrayModel { Name = new string[10] }; for (int i = 0; i < 10; i++) { model.Name[i] = i.ToString(); } SnapshotOperator.MakeSnapshot(model); for (int i = 5; i < 10; i++) { model.Name[i] = (i + 100).ToString(); } var reuslt = SnapshotOperator.Compare(model); var value = (HashSet <string>)reuslt["Name"].Value; int temp = 5; foreach (var item in value) { Assert.Equal(temp.ToString(), item); temp++; } }
public void Normal() { FieldCloneNormalModel model = new FieldCloneNormalModel { Age = 1000, Name = "ababab", Timer = DateTime.Now, money = 100000, Flag = CloneEnum.A, Title = false, Id = 100000 }; SnapshotOperator.MakeSnapshot(model); model.Age = 1001; model.Name = "hahaha"; model.Flag = CloneEnum.B; model.Title = true; var reuslt = SnapshotOperator.Compare(model); Assert.NotEqual(model.Age, (int)(reuslt["Age"].Value)); Assert.NotEqual(model.Title, (bool)(reuslt["Title"].Value)); Assert.NotEqual(model.Name, (string)(reuslt["Name"].Value)); Assert.NotEqual(model.Flag, (CloneEnum)(reuslt["Flag"].Value)); Assert.Equal(1000, (int)(reuslt["Age"].Value)); Assert.False((bool)(reuslt["Title"].Value)); Assert.Equal("ababab", (string)(reuslt["Name"].Value)); Assert.Equal(CloneEnum.A, (CloneEnum)(reuslt["Flag"].Value)); }
public void PropClassCollectionTest() { PropCloneClassCollectionModel model = new PropCloneClassCollectionModel(); model.Nodes = new List <PropCloneNormalModel>(); for (int i = 0; i < 10; i++) { model.Nodes.Add(new PropCloneNormalModel() { Age = i, Name = i.ToString() }); } SnapshotOperator.MakeSnapshot(model); for (int i = 5; i < 10; i++) { model.Nodes.Add(new PropCloneNormalModel() { Age = i + 100, Name = (i + 100).ToString() }); } var reuslt = SnapshotOperator.Compare(model); var value = (HashSet <PropCloneNormalModel>)reuslt["Nodes"].Value; int temp = 5; foreach (var item in value) { Assert.Equal(temp.ToString(), item.Name); Assert.Equal(temp, item.Age); temp++; } }
public void PropNormal() { var tempDate = DateTime.Now; PropCloneNormalModel model = new PropCloneNormalModel(); model.Age = 1000; model.Name = "ababab"; model.Timer = tempDate; model.money = 100000; model.Title = false; model.Id = 100000; //生成快照 SnapshotOperator.MakeSnapshot(model); //更改model model.Age = 1001; model.Name = "hahaha"; model.Timer = DateTime.Now; model.Title = true; //对比快照 var reuslt = SnapshotOperator.Compare(model); Assert.NotEqual(model.Age, (int)(reuslt["Age"].Value)); Assert.NotEqual(model.Title, (bool)(reuslt["Title"].Value)); Assert.NotEqual(model.Name, (string)(reuslt["Name"].Value)); Assert.NotEqual(model.Timer, (DateTime)(reuslt["Timer"].Value)); Assert.Equal(1000, (int)(reuslt["Age"].Value)); Assert.False((bool)(reuslt["Title"].Value)); Assert.Equal("ababab", (string)(reuslt["Name"].Value)); Assert.Equal(tempDate, (DateTime)(reuslt["Timer"].Value)); }
public static void MakeSnapshot <T>(T needSnapshot) { SnapshotOperator <T> .MakeSnapshot(needSnapshot); }
public static Dictionary <string, DiffModel> Compare <T>(T instance) { return(SnapshotOperator <T> .Compare(instance)); }
public static bool IsDiffernt <T>(T instance) { return(SnapshotOperator <T> .Compare(instance).Count != 0); }
public static Dictionary <string, DiffModel> Diff <T>(T newInstance, T oldInstance) { return(SnapshotOperator <T> .Diff(newInstance, oldInstance)); }
private async Task SendSnapshot( IRaftServer proxy, AsyncPolicy policy, Peer peer, long nextIndex, long matchIndex) { var logOffset = LogPersister.LogOffset; var term = State.CurrentTerm; Snapshot ss; if (!SnapshotOperator.TryGetLastSnapshot(out ss)) { throw new InvalidProgramException($"WE DO NOT HAVE A SNAPSHOT for client {peer.Address} whose nextIndex is {nextIndex} yet our LogOffset is {logOffset}"); } if (ss.LastIncludedIndex + 1 < nextIndex) { throw new InvalidProgramException($"WE DO NOT HAVE A <<PROPER>> SNAPSHOT for client {peer.Address} whose nextIndex is {nextIndex} yet our LogOffset is {logOffset}. Snapshot was have ({ss.FullName}) is short {ss.LastIncludedIndex}"); } // make a copy since it might be cleaned up or opened by another thread for another client var fileName = Path.GetTempFileName(); File.Copy(ss.FullName, fileName, true); TheTrace.TraceInformation($"[{_meAsAPeer.ShortName}] About to send Snapshot copy file {fileName} to [{peer.ShortName}] and copy of {ss.FullName}."); using (var fs = new FileStream(fileName, FileMode.Open)) { var start = 0; var total = 0; var length = fs.Length; var buffer = new byte[_settings.MaxSnapshotChunkSentInBytes]; TheTrace.TraceInformation($"[{_meAsAPeer.ShortName}] Snapshot copy file size is {length}. Location is {fileName} and copy of {ss.FullName}."); while (total < length) { var count = fs.Read(buffer, 0, buffer.Length); total += count; var result = await proxy.InstallSnapshotAsync(new InstallSnapshotRequest() { CurrentTerm = term, Data = count == buffer.Length ? buffer : buffer.Take(count).ToArray(), LastIncludedIndex = ss.LastIncludedIndex, LastIncludedTerm = term, IsDone = total == length, LeaderId = State.Id, Offset = start }); TheTrace.TraceInformation($"[{_meAsAPeer.ShortName}] Sent snapshot for peer {peer.Address} with {count} bytes totalling {total}."); start += count; if (result.CurrentTerm != term) { TheTrace.TraceWarning($"[{_meAsAPeer.ShortName}] I am sending snapshot but this peer {peer.Address} has term {result.CurrentTerm} vs my started term {term} and current term {State.CurrentTerm}."); } } } _volatileLeaderState.SetMatchIndex(peer.Id, ss.LastIncludedIndex); _volatileLeaderState.SetNextIndex(peer.Id, ss.LastIncludedIndex + 1); // the rest will be done by sending logs File.Delete(fileName); }
public static void MakeSnapshot <T>(this T instance) { SnapshotOperator.MakeSnapshot(instance); }