Example #1
0
// Constructor
        internal DiffgramChangeNode(XmlDiffNode sourceNode, XmlDiffNode targetNode, XmlDiffOperation op, ulong operationID)
            : base(operationID)
        {
            Debug.Assert(sourceNode != null);
            Debug.Assert(targetNode != null);
            Debug.Assert(XmlDiff.IsChangeOperation(op) || op == XmlDiffOperation.ChangeAttr);

            _sourceNode = sourceNode;
            _targetNode = targetNode;
            _op         = op;
        }
Example #2
0
// Constructor
        internal EditScriptChange(int sourceIndex, int targetIndex, XmlDiffOperation changeOp, EditScript next)
            : base(next)
        {
            Debug.Assert(sourceIndex > 0);
            Debug.Assert(targetIndex > 0);
            Debug.Assert(XmlDiff.IsChangeOperation(changeOp));

            _sourceIndex = sourceIndex;
            _targetIndex = targetIndex;
            _changeOp    = changeOp;
        }
Example #3
0
        private void ComputeTreeDistance(int sourcePos, int targetPos)
        {
            int sourcePosLeft = _sourceNodes[sourcePos].Left;
            int targetPosLeft = _targetNodes[targetPos].Left;
            int i, j;

            // init borders of _forestDist array
            EditScriptAddOpened    esAdd    = new EditScriptAddOpened(targetPosLeft, EmptyEditScript);
            EditScriptRemoveOpened esRemove = new EditScriptRemoveOpened(sourcePosLeft, EmptyEditScript);

            _forestDist[sourcePosLeft - 1, targetPosLeft - 1]._cost       = 0;
            _forestDist[sourcePosLeft - 1, targetPosLeft - 1]._editScript = EmptyEditScript;

            for (i = sourcePosLeft; i <= sourcePos; i++)
            {
                _forestDist[i, targetPosLeft - 1]._cost       = (i - sourcePosLeft + 1) * OperationCost[(int)XmlDiffOperation.Remove];
                _forestDist[i, targetPosLeft - 1]._editScript = esRemove;
            }
            for (j = targetPosLeft; j <= targetPos; j++)
            {
                _forestDist[sourcePosLeft - 1, j]._cost       = (j - targetPosLeft + 1) * OperationCost[(int)XmlDiffOperation.Add];
                _forestDist[sourcePosLeft - 1, j]._editScript = esAdd;
            }

#if DEBUG
            Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "\nForest distance (" + sourcePos + "," + targetPos + "):\n");
            Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "       0    ");
            for (j = targetPosLeft; j <= targetPos; j++)
            {
                Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, j + "    ");
            }
            Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "\n   ");
            for (j = targetPosLeft - 1; j <= targetPos; j++)
            {
                Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "*****");
            }
            Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "\n0  *   0   ");
            for (j = targetPosLeft; j <= targetPos; j++)
            {
                Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "-" + _forestDist[sourcePosLeft - 1, j]._cost + "   ");
            }
            Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "\n");
#endif

            // compute the inside of _forestDist array
            for (i = sourcePosLeft; i <= sourcePos; i++)
            {
#if DEBUG
                Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, i + "  *  |" + _forestDist[i, targetPosLeft - 1]._cost + "   ");
#endif

                for (j = targetPosLeft; j <= targetPos; j++)
                {
                    int sourceCurLeft = _sourceNodes[i].Left;
                    int targetCurLeft = _targetNodes[j].Left;

                    int removeCost = _forestDist[i - 1, j]._cost + OperationCost[(int)XmlDiffOperation.Remove];
                    int addCost    = _forestDist[i, j - 1]._cost + OperationCost[(int)XmlDiffOperation.Add];

                    if (sourceCurLeft == sourcePosLeft && targetCurLeft == targetPosLeft)
                    {
                        XmlDiffOperation changeOp = _sourceNodes[i].GetDiffOperation(_targetNodes[j], _xmlDiff);

                        Debug.Assert(XmlDiff.IsChangeOperation(changeOp) ||
                                     changeOp == XmlDiffOperation.Match ||
                                     changeOp == XmlDiffOperation.Undefined);

                        if (changeOp == XmlDiffOperation.Match)
                        {
                            // identical nodes matched
                            OpNodesMatch(i, j);
                        }
                        else
                        {
                            int changeCost = _forestDist[i - 1, j - 1]._cost + OperationCost[(int)changeOp];

                            if (changeCost < addCost)
                            {
                                // operation 'change'
                                if (changeCost < removeCost)
                                {
                                    OpChange(i, j, changeOp, changeCost);
                                }
                                // operation 'remove'
                                else
                                {
                                    OpRemove(i, j, removeCost);
                                }
                            }
                            else
                            {
                                // operation 'add'
                                if (addCost < removeCost)
                                {
                                    OpAdd(i, j, addCost);
                                }
                                // operation 'remove'
                                else
                                {
                                    OpRemove(i, j, removeCost);
                                }
                            }
                        }

                        _treeDist[i, j]._cost       = _forestDist[i, j]._cost;
                        _treeDist[i, j]._editScript = _forestDist[i, j]._editScript.GetClosedScript(i, j);;
                    }
                    else
                    {
                        int m = sourceCurLeft - 1;
                        int n = targetCurLeft - 1;

                        if (m < sourcePosLeft - 1)
                        {
                            m = sourcePosLeft - 1;
                        }
                        if (n < targetPosLeft - 1)
                        {
                            n = targetPosLeft - 1;
                        }

                        // cost of concatenating of the two edit scripts
                        int compoundEditCost = _forestDist[m, n]._cost + _treeDist[i, j]._cost;

                        if (compoundEditCost < addCost)
                        {
                            if (compoundEditCost < removeCost)
                            {
                                // copy script
                                if (_treeDist[i, j]._editScript == EmptyEditScript)
                                {
                                    Debug.Assert(_treeDist[i, j]._cost == 0);
                                    OpCopyScript(i, j, m, n);
                                }
                                // concatenate scripts
                                else
                                {
                                    OpConcatScripts(i, j, m, n);
                                }
                            }
                            // operation 'remove'
                            else
                            {
                                OpRemove(i, j, removeCost);
                            }
                        }
                        else
                        {
                            // operation 'add'
                            if (addCost < removeCost)
                            {
                                OpAdd(i, j, addCost);
                            }
                            // operation 'remove'
                            else
                            {
                                OpRemove(i, j, removeCost);
                            }
                        }
                    }
#if DEBUG
                    Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, _forestDist[i, j]._cost + "   ");
#endif
                }
#if DEBUG
                Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "\n");
#endif
            }
        }