internal static void Modify(INode inode, IList <INode> current, Diff <byte[], INode > diff) { int i = Diff.Search(current, inode.GetKey()); NUnit.Framework.Assert.IsTrue(i >= 0); INodeDirectory oldinode = (INodeDirectory)current[i]; INodeDirectory newinode = new INodeDirectory(oldinode, false, oldinode.GetFeatures ()); newinode.SetModificationTime(oldinode.GetModificationTime() + 1); current.Set(i, newinode); if (diff != null) { //test undo with 1/UNDO_TEST_P probability bool testUndo = Random.Next(UndoTestP) == 0; string before = null; if (testUndo) { before = diff.ToString(); } Diff.UndoInfo <INode> undoInfo = diff.Modify(oldinode, newinode); if (testUndo) { string after = diff.ToString(); //undo diff.UndoModify(oldinode, newinode, undoInfo); AssertDiff(before, diff); //re-do diff.Modify(oldinode, newinode); AssertDiff(after, diff); } } }
internal static void Delete(INode inode, IList <INode> current, Diff <byte[], INode > diff) { int i = Diff.Search(current, inode.GetKey()); current.Remove(i); if (diff != null) { //test undo with 1/UNDO_TEST_P probability bool testUndo = Random.Next(UndoTestP) == 0; string before = null; if (testUndo) { before = diff.ToString(); } Diff.UndoInfo <INode> undoInfo = diff.Delete(inode); if (testUndo) { string after = diff.ToString(); //undo diff.UndoDelete(inode, undoInfo); AssertDiff(before, diff); //re-do diff.Delete(inode); AssertDiff(after, diff); } } }
/// <summary>Undo the previous delete(E) operation.</summary> /// <remarks> /// Undo the previous delete(E) operation. Note that the behavior is /// undefined if the previous operation is not delete(E). /// </remarks> public virtual void UndoDelete(E element, Diff.UndoInfo <E> undoInfo) { int c = undoInfo.createdInsertionPoint; if (c >= 0) { created.Add(c, undoInfo.trashed); } else { Remove(deleted, undoInfo.deletedInsertionPoint, element); } }
/// <summary>Combine this diff with a posterior diff.</summary> /// <remarks> /// Combine this diff with a posterior diff. We have the following cases: /// <pre> /// 1. For (c, 0) in the posterior diff, check the element in this diff: /// 1.1 (c', 0) in this diff: impossible /// 1.2 (0, d') in this diff: put in c-list --> (c, d') /// 1.3 (c', d') in this diff: impossible /// 1.4 (0, 0) in this diff: put in c-list --> (c, 0) /// This is the same logic as create(E). /// 2. For (0, d) in the posterior diff, /// 2.1 (c', 0) in this diff: remove from c-list --> (0, 0) /// 2.2 (0, d') in this diff: impossible /// 2.3 (c', d') in this diff: remove from c-list --> (0, d') /// 2.4 (0, 0) in this diff: put in d-list --> (0, d) /// This is the same logic as delete(E). /// 3. For (c, d) in the posterior diff, /// 3.1 (c', 0) in this diff: replace the element in c-list --> (c, 0) /// 3.2 (0, d') in this diff: impossible /// 3.3 (c', d') in this diff: replace the element in c-list --> (c, d') /// 3.4 (0, 0) in this diff: put in c-list and d-list --> (c, d) /// This is the same logic as modify(E, E). /// </pre> /// </remarks> /// <param name="posterior">The posterior diff to combine with.</param> /// <param name="deletedProcesser">process the deleted/overwritten elements in case 2.1, 2.3, 3.1 and 3.3. /// </param> public virtual void CombinePosterior(Diff <K, E> posterior, Diff.Processor <E> deletedProcesser ) { IEnumerator <E> createdIterator = posterior.GetList(Diff.ListType.Created).GetEnumerator (); IEnumerator <E> deletedIterator = posterior.GetList(Diff.ListType.Deleted).GetEnumerator (); E c = createdIterator.HasNext() ? createdIterator.Next() : null; E d = deletedIterator.HasNext() ? deletedIterator.Next() : null; for (; c != null || d != null;) { int cmp = c == null ? 1 : d == null ? -1 : c.CompareTo(d.GetKey()); if (cmp < 0) { // case 1: only in c-list Create(c); c = createdIterator.HasNext() ? createdIterator.Next() : null; } else { if (cmp > 0) { // case 2: only in d-list Diff.UndoInfo <E> ui = Delete(d); if (deletedProcesser != null) { deletedProcesser.Process(ui.trashed); } d = deletedIterator.HasNext() ? deletedIterator.Next() : null; } else { // case 3: in both c-list and d-list Diff.UndoInfo <E> ui = Modify(d, c); if (deletedProcesser != null) { deletedProcesser.Process(ui.trashed); } c = createdIterator.HasNext() ? createdIterator.Next() : null; d = deletedIterator.HasNext() ? deletedIterator.Next() : null; } } } }
/// <summary>Undo the previous modify(E, E) operation.</summary> /// <remarks> /// Undo the previous modify(E, E) operation. Note that the behavior /// is undefined if the previous operation is not modify(E, E). /// </remarks> public virtual void UndoModify(E oldElement, E newElement, Diff.UndoInfo <E> undoInfo ) { int c = undoInfo.createdInsertionPoint; if (c >= 0) { created.Set(c, undoInfo.trashed); } else { int d = undoInfo.deletedInsertionPoint; if (d < 0) { Remove(created, c, newElement); Remove(deleted, d, oldElement); } } }