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