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