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; }
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 } }