Example #1
0
        private void OpRemove(int i, int j, int cost)
        {
#if DEBUG
            Trace.WriteIf(XmlDiff.T_ForestDistance.Enabled, "|");
#endif
            EditScriptRemoveOpened openedRemove = _forestDist[i - 1, j]._editScript as EditScriptRemoveOpened;

            if (openedRemove == null)
            {
                openedRemove = new EditScriptRemoveOpened(i, _forestDist[i - 1, j]._editScript.GetClosedScript(i - 1, j));
            }

            _forestDist[i, j]._editScript = openedRemove;
            _forestDist[i, j]._cost       = cost;
        }
        private void OpRemove( int i, int j, int cost )
        {
            #if DEBUG
            Trace.WriteIf( XmlDiff.T_ForestDistance.Enabled, "|" );
            #endif
            EditScriptRemoveOpened openedRemove = _forestDist[ i-1, j ]._editScript as EditScriptRemoveOpened;

            if ( openedRemove == null )
            openedRemove  = new EditScriptRemoveOpened( i, _forestDist[ i-1, j ]._editScript.GetClosedScript( i-1, j ) );

            _forestDist[ i, j ]._editScript = openedRemove;
            _forestDist[ i, j ]._cost = cost;
        }
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
            }
        }
        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
            }
        }