Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        /// <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);
            }
        }
Пример #4
0
        /// <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 --&gt; (c, d')
        /// 1.3 (c', d') in this diff: impossible
        /// 1.4 (0, 0)   in this diff: put in c-list --&gt; (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 --&gt; (0, 0)
        /// 2.2 (0, d')  in this diff: impossible
        /// 2.3 (c', d') in this diff: remove from c-list --&gt; (0, d')
        /// 2.4 (0, 0)   in this diff: put in d-list --&gt; (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 --&gt; (c, 0)
        /// 3.2 (0, d')  in this diff: impossible
        /// 3.3 (c', d') in this diff: replace the element in c-list --&gt; (c, d')
        /// 3.4 (0, 0)   in this diff: put in c-list and d-list --&gt; (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;
                    }
                }
            }
        }
Пример #5
0
        /// <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);
                }
            }
        }