Ejemplo n.º 1
0
        //该方法将不同行细分为:修改、删除、新增类型;
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        //添加不同行的区域块,从第一行到最后一行,相邻的行状态相同为一个区域块
        //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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
                }
            }
        }
Ejemplo n.º 7
0
        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);
                    }
                }
            }
        }