예제 #1
0
 public IgnoreIdenticalBeginningAndEndCorrelaterWrapper(ICorrelater <T> innerCorrelater)
 {
     this.innerCorrelater              = innerCorrelater;
     innerCorrelater.OnProgressUpdate += (p, t) => OnProgressUpdate?.Invoke(p, t);
     if (innerCorrelater is IContinuousCorrelater <T> continuousCorrelater)
     {
         continuousCorrelater.OnResultUpdate += r => OnResultUpdate?.Invoke(r);
     }
 }
예제 #2
0
        public PatienceDiffCorrelater()
        {
            if (default(T) != null && typeof(T) != typeof(char))
            {
                throw new EnumerableCorrelaterException($"{nameof(T)} must be nullable or a char");
            }

            innerCorrelater.OnProgressUpdate += (p, t) => OnProgressUpdate?.Invoke(p, t);
            innerCorrelater.OnResultUpdate   += r => OnResultUpdate?.Invoke(r);
        }
예제 #3
0
        /// <summary>
        /// A certain stretch of the two chunks - which includes the end of the previous chunk, and the beginning of the current chunk, is considered the chunks "edge".
        /// We'll correlate this edge separately, to prevent loosing matches between chunks.
        /// </summary>
        private void AddEdge(int startFromIndexOnPreviousResult, int goUpToIndexOnCurrentResult, CorrelaterResult <T> currentResult, CorrelaterResult <T> previousResult, List <T> list1, List <T> list2, CancellationToken cancellationToken)
        {
            var collection1 = GetEdgeCollection(previousResult.BestMatch1, currentResult.BestMatch1,
                                                startFromIndexOnPreviousResult, goUpToIndexOnCurrentResult);
            var collection2 = GetEdgeCollection(previousResult.BestMatch2, currentResult.BestMatch2,
                                                startFromIndexOnPreviousResult, goUpToIndexOnCurrentResult);

            var result = innerCorrelater.Correlate(collection1, collection2, cancellationToken);

            AddRange(result.BestMatch1, list1, 0, result.BestMatch1.Length);
            AddRange(result.BestMatch2, list2, 0, result.BestMatch2.Length);
            OnResultUpdate?.Invoke(GetPartualResult(result, 0, result.BestMatch1.Length));
        }
        public CorrelaterResult <T> Merge(List <Task <CorrelaterResult <T> > > results)
        {
            var bestMatch1 = new List <T>();
            var bestMatch2 = new List <T>();
            var distance   = 0L;

            var i = 0;

            foreach (var result in results.Select(t => t.Result))
            {
                OnProgressUpdate?.Invoke(++i, results.Count);
                OnResultUpdate?.Invoke(result);
                bestMatch1.AddRange(result.BestMatch1);
                bestMatch2.AddRange(result.BestMatch2);
                distance += result.Distance;
            }

            return(new CorrelaterResult <T>(distance, bestMatch1.ToArray(), bestMatch2.ToArray()));
        }
예제 #5
0
        private void AddFinalEdge(int addedUpTo, CorrelaterResult <T> result, List <T> list1, List <T> list2)
        {
            var length = Math.Max(0, result.BestMatch1.Length - addedUpTo);
            var array1 = new T[length];
            var array2 = new T[length];

            for (int i = addedUpTo; i < result.BestMatch1.Length; i++)
            {
                array1[i - addedUpTo] = result.BestMatch1[i];
            }
            for (int i = addedUpTo; i < result.BestMatch2.Length; i++)
            {
                array2[i - addedUpTo] = result.BestMatch2[i];
            }

            list1.AddRange(array1);
            list2.AddRange(array2);

            OnResultUpdate?.Invoke(new CorrelaterResult <T>(0, array1, array2));
        }
예제 #6
0
        // When connecting section A with section B, the Reduce method tries to better connect the "edges" of A and B.
        private CorrelaterResult <T> Reduce(List <Task <CorrelaterResult <T> > > resultTasks, CancellationToken cancellationToken)
        {
            var list1        = new List <T>();
            var list2        = new List <T>();
            var distance     = 0L;
            var endEdgeIndex = -1;

            for (var i = 0; i < resultTasks.Count; i++)
            {
                var result         = resultTasks[i].Result;
                var startEdgeIndex = i > 0 ? GetStartEdgeIndex(resultTasks[i].Result) : 0;
                if (i > 0)
                {
                    AddEdge(endEdgeIndex, startEdgeIndex, result, resultTasks[i - 1].Result, list1, list2, cancellationToken);
                }
                endEdgeIndex = GetEndEdgeIndex(result);

                distance += result.Distance;
                if (maxDistance.HasValue && distance > maxDistance.Value)
                {
                    return(null);
                }

                AddRange(result.BestMatch1, list1, startEdgeIndex, endEdgeIndex);
                AddRange(result.BestMatch2, list2, startEdgeIndex, endEdgeIndex);

                OnResultUpdate?.Invoke(GetPartualResult(result, startEdgeIndex, endEdgeIndex));
                OnProgressUpdate?.Invoke(i + 1, resultTasks.Count);

                if (i == resultTasks.Count - 1)
                {
                    AddFinalEdge(Math.Max(endEdgeIndex, startEdgeIndex), result, list1, list2);
                }
            }

            return(new CorrelaterResult <T>(distance, list1.ToArray(), list2.ToArray()));
        }
예제 #7
0
        public CorrelaterResult <T> Correlate(IEnumerable <T> collection1, IEnumerable <T> collection2, CancellationToken cancellationToken = default)
        {
            var collection1Wrapper = collection1.ToCollectionWrapper();
            var collection2Wrapper = collection2.ToCollectionWrapper();

            var startIndex = GetFirstNotEqualIndex(collection1Wrapper, collection2Wrapper, cancellationToken);
            var endIndexes = GetLastNotEqualIndexes(collection1Wrapper, collection2Wrapper, startIndex, cancellationToken);

            if (startIndex > 0)
            {
                OnResultUpdate?.Invoke(new CorrelaterResult <T>(0, collection1Wrapper.Take(startIndex).ToArray(), collection2Wrapper.Take(startIndex).ToArray()));
            }

            var innerCorrelaterResult = innerCorrelater.Correlate(
                new OffsetCollectionWrapper <T>(collection1Wrapper, startIndex, endIndexes.Item1),
                new OffsetCollectionWrapper <T>(collection2Wrapper, startIndex, endIndexes.Item2),
                cancellationToken);

            var result = CreateResult(collection1Wrapper, collection2Wrapper, startIndex, endIndexes, innerCorrelaterResult);

            UpdateEndOfResult(startIndex, result, collection1Wrapper, endIndexes.Item1);

            return(result);
        }