Ejemplo n.º 1
0
        public static NPatch Diff(NElement oldE, ref NElement newE)
        {
            var oldSet = oldE != null;
            var newSet = newE != null;

            if (oldSet == newSet)
            {
                if (!oldSet)
                {
                    return(null);
                }

                if (NPatch.ElementEquals(oldE, newE))
                {
                    var oldC = oldE as NClass;
                    if (oldC != null)
                    {
                        var newC = (NClass)newE;
                        newE = oldE;
                        return(oldC.Upgrade(newC));
                    }

                    return(new NPropDiffer(oldE, newE).Diff());
                }
            }

            return(NPatch.AssignNewValue);
        }
Ejemplo n.º 2
0
        NPatch Diff()
        {
            var cOld = _source.Length;
            var cNew = _target.Length;

            if (cOld == 0 || cNew == 0)
            {
                return(NPatch.AssignNewValue);
            }

            var iOld = 0;
            var iNew = 0;
            var iFix = 0;

            for (;;)
            {
                var oldH = iOld < cOld;
                var oldE = oldH ? _source[iOld] : null;

                var newH = iNew < cNew;
                var newE = newH ? _target[iNew] : null;

                if (oldH)
                {
                    if (newH && NPatch.ElementEquals(oldE, newE))
                    {
                        Update(iOld + iFix, newE, oldE);
                        iNew++;
                    }
                    else
                    {
                        Remove(iOld + iFix, oldE);
                        iFix--;
                    }
                    iOld++;
                }
                else
                {
                    if (newH)
                    {
                        Insert(iOld + iFix, newE);
                        iOld++;
                        iNew++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            Optimize();

            TransferClasses();

            return(_head != null ? new NListPatch(_head) : null);
        }
Ejemplo n.º 3
0
        void OptimizeRemove(NListPatchEntry e)
        {
            var delta = 0;
            var oldE  = e.Finalizer;
            var last  = e;

            for (var i = e.Next; i != null; i = i.Next)
            {
                switch (i.Op)
                {
                case NListPatchOp.Insert:
                {
                    var newE = i.Value;

                    if (NPatch.ElementEquals(newE, oldE))
                    {
                        e.Op        = NListPatchOp.Move;                // transform to move
                        e.Finalizer = null;                             // remove finalizer
                        e.iInsert   = i.iInsert + delta;                // correct insert index at the time of move
                        e.iFinal    = i.iFinal;                         // preserve final index
                        e.Patch     = NPropDiffer.Diff(oldE, ref newE); // make patch
                        e.Value     = oldE;                             // preserve moved value

                        last.Next = i.Next;                             // delete insertion
                        return;
                    }
                    delta--;
                }
                break;

                case NListPatchOp.Remove:
                    delta++;
                    break;
                }
                last = i;
            }
        }