Пример #1
0
        private List <Task <CorrelaterResult <T> > > Map(ICollectionWrapper <T> collection1, ICollectionWrapper <T> collection2, CancellationToken cancellationToken)
        {
            var resultTasks = new List <Task <CorrelaterResult <T> > >();

            for (int i = 0; i < Math.Max(collection1.Length, collection2.Length); i = i + chunkSize)
            {
                var wrappedCollection1 = new OffsetCollectionWrapper <T>(collection1, Math.Min(collection1.Length, i), Math.Min(collection1.Length, i + chunkSize));
                var wrappedCollection2 = new OffsetCollectionWrapper <T>(collection2, Math.Min(collection2.Length, i), Math.Min(collection2.Length, i + chunkSize));
                resultTasks.Add(Task.Run(() => innerCorrelater.Correlate(wrappedCollection1, wrappedCollection2, cancellationToken)));
            }

            return(resultTasks);
        }
        public CorrelaterResult <T> Correlate(IEnumerable <T> collection1, IEnumerable <T> collection2, CancellationToken cancellationToken = default)
        {
            var collection1Wrapper = collection1.ToCollectionWrapper();
            var collection2Wrapper = collection2.ToCollectionWrapper();

            var(elementsUniqueInBothCollections, indexOfElementsInCollection1) = GetElementsUniqueInBothCollections(collection1Wrapper, collection2Wrapper);
            var longestSubsequence = patienceSortingAlgorithm.GetRisingIndexes(elementsUniqueInBothCollections.Select(v => v.LocationInCollection2).ToArray());
            var allResults         = new List <Task <CorrelaterResult <T> > >();

            if (!longestSubsequence.Any())
            {
                return(innerCorrelater.Correlate(collection1Wrapper, collection2Wrapper, cancellationToken));
            }
            else
            {
                int previousLocationInCollection1 = -1, previousLocationInCollection2 = -1;
                for (var i = 0; i < longestSubsequence.Count(); i++)
                {
                    var locationInCollection2 = longestSubsequence[i];
                    var matchingElement       = collection2Wrapper[locationInCollection2];
                    var locationInCollection1 = indexOfElementsInCollection1[matchingElement].Location;
                    var relevantCollection1   = new OffsetCollectionWrapper <T>(collection1Wrapper, previousLocationInCollection1 + 1, locationInCollection1);
                    var relevantCollection2   = new OffsetCollectionWrapper <T>(collection2Wrapper, previousLocationInCollection2 + 1, locationInCollection2);
                    allResults.Add(Task.Run(() => innerCorrelater.Correlate(relevantCollection1, relevantCollection2, cancellationToken)));
                    if (!multiThread)
                    {
                        allResults.Last().Wait();
                    }
                    allResults.Add(Task.FromResult(new CorrelaterResult <T>(0, new[] { matchingElement }, new[] { matchingElement })));
                    previousLocationInCollection1 = locationInCollection1;
                    previousLocationInCollection2 = locationInCollection2;
                }
                allResults.Add(Task.Run(() =>
                                        innerCorrelater.Correlate(
                                            new OffsetCollectionWrapper <T>(collection1Wrapper, previousLocationInCollection1 + 1, collection1Wrapper.Length),
                                            new OffsetCollectionWrapper <T>(collection2Wrapper, previousLocationInCollection2 + 1, collection2Wrapper.Length),
                                            cancellationToken)));
            }

            return(Merge(allResults));
        }