//该方法将不同行细分为:修改、删除、新增类型; private bool AddChanges( ArrayList report, int curDest, int nextDest, int curSource, int nextSource) { bool retval = false; int diffDest = nextDest - curDest;//下一个区域的索引减去当前区域索引(区域总共多少行?) int diffSource = nextSource - curSource; int minDiff = 0; if (diffDest > 0) { if (diffSource > 0) { minDiff = Math.Min(diffDest, diffSource); //curDest---新版本文件中区域块第一行的索引 //curSource --- 老版本文件中区域块第一行索引 //minDiff ---区域块中行数目 report.Add(DiffResultSpan.CreateReplace(curDest, curSource, minDiff)); //比如老版本10行,新版本5行;合并后10行不同,前5行是修改状态,后5行是新增状态 //minDiff = 5; if (diffDest > diffSource) { curDest += minDiff; report.Add(DiffResultSpan.CreateAddDestination(curDest, diffDest - diffSource)); } else//比如老版本3行,新版本5行;合并后5行不同,前3行是修改状态,后2行是删除状态 //minDiff = 3; { if (diffSource > diffDest) { curSource += minDiff; report.Add(DiffResultSpan.CreateDeleteSource(curSource, diffSource - diffDest)); } } } else //diffSource == 0表示老版本没有行,新版本有,表示新增行 { report.Add(DiffResultSpan.CreateAddDestination(curDest, diffDest)); } retval = true; } else { if (diffSource > 0) { report.Add(DiffResultSpan.CreateDeleteSource(curSource, diffSource)); retval = true; } } return(retval); }
public ArrayList DiffReport() { ArrayList retval = new ArrayList(); int dcount = _destination.Count(); int scount = _source.Count(); //Deal with the special case of empty files if (dcount == 0) { if (scount > 0) { retval.Add(DiffResultSpan.CreateDeleteSource(0, scount)); } return(retval); } else { if (scount == 0) { retval.Add(DiffResultSpan.CreateAddDestination(0, dcount)); return(retval); } } _matchList.Sort(); int curDest = 0; int curSource = 0; DiffResultSpan last = null; //Process each match record foreach (DiffResultSpan drs in _matchList) { if ((!AddChanges(retval, curDest, drs.DestIndex, curSource, drs.SourceIndex)) && (last != null)) { last.AddLength(drs.Length); } else { retval.Add(drs); } curDest = drs.DestIndex + drs.Length; curSource = drs.SourceIndex + drs.Length; last = drs; } //Process any tail end data AddChanges(retval, curDest, dcount, curSource, scount); return(retval); }
public DiffResultSpanCollection DiffReport() { DiffResultSpanCollection returnResultSpanCollection = new DiffResultSpanCollection(); int dcount = _dest.Count(); int scount = _source.Count(); //Deal with the special case of empty files if (dcount == 0) { if (scount > 0) { returnResultSpanCollection.Add(DiffResultSpan.CreateDeleteSource(0, scount)); } return(returnResultSpanCollection); } else { if (scount == 0) { returnResultSpanCollection.Add(DiffResultSpan.CreateAddDestination(0, dcount)); return(returnResultSpanCollection); } } _matchList.Sort(); int curDest = 0; int curSource = 0; DiffResultSpan lastResultSpan = null; //Process each match record foreach (DiffResultSpan resultSpan in _matchList) { if ((!AddChanges(returnResultSpanCollection, curDest, resultSpan.DestIndex, curSource, resultSpan.SourceIndex)) && (lastResultSpan != null)) { lastResultSpan.AddLength(resultSpan.Length); } else { returnResultSpanCollection.Add(resultSpan); } curDest = resultSpan.DestIndex + resultSpan.Length; curSource = resultSpan.SourceIndex + resultSpan.Length; lastResultSpan = resultSpan; } //Process any tail end data AddChanges(returnResultSpanCollection, curDest, dcount, curSource, scount); return(returnResultSpanCollection); }
//添加不同行的区域块,从第一行到最后一行,相邻的行状态相同为一个区域块 //DiffReport返回参数解释: //int DestIndex ---区域块第一行在新版本文件中的原来的索引 //SourceIndex ---区域块第一行在老版本文件中的原来的索引 //int Length ---当前区域块中的行的个数 //Status ---改区域块中所有行共同的状态(Add/Delete/Modify) public ArrayList DiffReport() { ArrayList resultList = new ArrayList();//返回值 int dcount = _dest.Count(); int scount = _source.Count(); //处理空文件 if (dcount == 0) { if (scount > 0) { resultList.Add(DiffResultSpan.CreateDeleteSource(0, scount)); } return(resultList); } else { if (scount == 0) { resultList.Add(DiffResultSpan.CreateAddDestination(0, dcount)); return(resultList); } } //_matchList添加了相同行和不同行区域块,但是不同行又分为:新增、删除、修改三个状态没有区分 _matchList.Sort(); int curNewIndex = 0; int curOldIndex = 0; DiffResultSpan last = null; //Process each match record foreach (DiffResultSpan drs in _matchList) { if ((!AddChanges(resultList, curNewIndex, drs.DestIndex, curOldIndex, drs.SourceIndex)) && (last != null)) { last.AddLength(drs.Length); } else { resultList.Add(drs); } curNewIndex = drs.DestIndex + drs.Length;//新版本当前区域块第一行的索引。 curOldIndex = drs.SourceIndex + drs.Length; last = drs; } //Process any tail end data AddChanges(resultList, curNewIndex, dcount, curOldIndex, scount); return(resultList); }
private bool AddChanges( List <DiffResultSpan> report, int curDest, int nextDest, int curSource, int nextSource) { bool retval = false; int diffDest = nextDest - curDest; int diffSource = nextSource - curSource; int minDiff = 0; if (diffDest > 0) { if (diffSource > 0) { minDiff = Math.Min(diffDest, diffSource); report.Add(DiffResultSpan.CreateReplace(curDest, curSource, minDiff)); if (diffDest > diffSource) { curDest += minDiff; report.Add(DiffResultSpan.CreateAddDestination(curDest, diffDest - diffSource)); } else { if (diffSource > diffDest) { curSource += minDiff; report.Add(DiffResultSpan.CreateDeleteSource(curSource, diffSource - diffDest)); } } } else { report.Add(DiffResultSpan.CreateAddDestination(curDest, diffDest)); } retval = true; } else { if (diffSource > 0) { report.Add(DiffResultSpan.CreateDeleteSource(curSource, diffSource)); retval = true; } } return(retval); }
private void ProcessRange(int destStart, int destEnd, int sourceStart, int sourceEnd) { int curBestIndex = -1; int curBestLength = -1; int maxPossibleDestLength = 0; DiffState curItem = null; DiffState bestItem = null; for (int destIndex = destStart; destIndex <= destEnd; destIndex++) { maxPossibleDestLength = (destEnd - destIndex) + 1; if (maxPossibleDestLength <= curBestLength) { //we won't find a longer one even if we looked break; } curItem = _diffStateList.GetByIndex(destIndex); if (!curItem.HasValidLength(sourceStart, sourceEnd, maxPossibleDestLength)) { //recalc new best length since it isn't valid or has never been done. GetLongestSourceMatch(curItem, destIndex, destEnd, sourceStart, sourceEnd); } if (curItem.Status == DiffStatus.Matched) { switch (_level) { case DiffEngineLevel.Fast: if (curItem.Length > curBestLength) { //this is longest match so far curBestIndex = destIndex; curBestLength = curItem.Length; bestItem = curItem; } //Jump over the match destIndex += curItem.Length - 1; break; case DiffEngineLevel.Medium: if (curItem.Length > curBestLength) { //this is longest match so far curBestIndex = destIndex; curBestLength = curItem.Length; bestItem = curItem; //Jump over the match destIndex += curItem.Length - 1; } break; default: if (curItem.Length > curBestLength) { //this is longest match so far curBestIndex = destIndex; curBestLength = curItem.Length; bestItem = curItem; } break; } } } if (curBestIndex < 0) { // there are no matches in this span } else { int sourceIndex = bestItem.StartIndex; _matchList.Add(DiffResultSpan.CreateNoChange(curBestIndex, sourceIndex, curBestLength)); if (destStart < curBestIndex && sourceStart < sourceIndex) { // Recursive call to process lower indexes ProcessRange(destStart, curBestIndex - 1, sourceStart, sourceIndex - 1); } int upperDestStart = curBestIndex + curBestLength; int upperSourceStart = sourceIndex + curBestLength; if (destEnd > upperDestStart && sourceEnd > upperSourceStart) { // Recursive call to process upper indexes ProcessRange(upperDestStart, destEnd, upperSourceStart, sourceEnd); } } }
private void ProcessRange(int destStart, int destEnd, int sourceStart, int sourceEnd) { int curBestIndex = -1; //当前匹配项 int curBestLength = -1; //当前匹配状态(匹配、不匹配) int maxPossibleDestLength = 0; //最大行数 DiffState curItem = null; DiffState bestItem = null; //循环新版本所有行 for (int destIndex = destStart; destIndex <= destEnd; destIndex++) { maxPossibleDestLength = (destEnd - destIndex) + 1; if (maxPossibleDestLength <= curBestLength) { break; } //循环新文件的当前行状态对象: curItem = _stateList.GetByIndex(destIndex); if (!curItem.HasValidLength(sourceStart, sourceEnd, maxPossibleDestLength)) { //如果装填不知道,返回true //设置当前行的状态 //recalc new best length since it isn't valid or has never been done. GetLongestSourceMatch(curItem, destIndex, destEnd, sourceStart, sourceEnd); } //如果新文件当前行和老文件匹配(相同) if (curItem.Status == DiffStatus.Matched) { switch (_level) { case DiffEngineLevel.FastImperfect: if (curItem.Length > curBestLength) { //this is longest match so far curBestIndex = destIndex; curBestLength = curItem.Length; bestItem = curItem; } //Jump over the match destIndex += curItem.Length - 1; //当前第9行不相同,从第9行开始往下比较下一个不匹配项 break; } } } if (curBestIndex < 0) { //we are done - there are no matches in this span } else //如果新文件当前行和老文件匹配(相同) { int sourceIndex = bestItem.StartIndex; _matchList.Add(DiffResultSpan.CreateNoChange(curBestIndex, sourceIndex, curBestLength)); if (destStart < curBestIndex) { //Still have more lower destination data if (sourceStart < sourceIndex) { //Still have more lower source data // Recursive call to process lower indexes ProcessRange(destStart, curBestIndex - 1, sourceStart, sourceIndex - 1); } } int upperDestStart = curBestIndex + curBestLength; int upperSourceStart = sourceIndex + curBestLength; if (destEnd > upperDestStart) { //we still have more upper dest data if (sourceEnd > upperSourceStart) { //set still have more upper source data // Recursive call to process upper indexes ProcessRange(upperDestStart, destEnd, upperSourceStart, sourceEnd); } } } }