| File: System\Linq\Parallel\Merging\ArrayMergeHelper.cs | Web Access |
| Project: src\runtime\src\libraries\System.Linq.Parallel\src\System.Linq.Parallel.csproj (System.Linq.Parallel) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // ArrayMergeHelper.cs // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Parallel; using System.Text; using System.Threading.Tasks; namespace System.Linq.Parallel { /// <summary> /// A special merge helper for indexable queries. Given an indexable query, we know how many elements /// we'll have in the result set, so we can allocate the array ahead of time. Then, as each result element /// is produced, we can directly insert it into the appropriate position in the output array, paying /// no extra cost for ordering. /// </summary> /// <typeparam name="TInputOutput"></typeparam> internal sealed class ArrayMergeHelper<TInputOutput> : IMergeHelper<TInputOutput> { private readonly QueryResults<TInputOutput> _queryResults; // Indexable query results private readonly TInputOutput[] _outputArray; // The output array. private QuerySettings _settings; // Settings for the query. /// <summary> /// Instantiates the array merge helper. /// </summary> /// <param name="settings">The query settings</param> /// <param name="queryResults">The query results</param> public ArrayMergeHelper(QuerySettings settings, QueryResults<TInputOutput> queryResults) { _settings = settings; _queryResults = queryResults; int count = _queryResults.Count; _outputArray = new TInputOutput[count]; } /// <summary> /// A method used as a delegate passed into the ForAll operator /// </summary> private void ToArrayElement(int index) { _outputArray[index] = _queryResults[index]; } /// <summary> /// Schedules execution of the merge itself. /// </summary> public void Execute() { ParallelQuery<int> query = ParallelEnumerable.Range(0, _queryResults.Count); query = new QueryExecutionOption<int>(QueryOperator<int>.AsQueryOperator(query), _settings); query.ForAll(ToArrayElement); } /// <summary> /// Gets the enumerator over the results. /// /// We never expect this method to be called. ArrayMergeHelper is intended to be used when we want /// to consume the results using GetResultsAsArray(). /// </summary> [ExcludeFromCodeCoverage(Justification = "ArrayMergeHelper<>.GetEnumerator() is not intended to be used")] public IEnumerator<TInputOutput> GetEnumerator() { Debug.Fail("ArrayMergeHelper<>.GetEnumerator() is not intended to be used. Call GetResultsAsArray() instead."); return ((IEnumerable<TInputOutput>)GetResultsAsArray()).GetEnumerator(); } /// <summary> /// Returns the merged results as an array. /// </summary> /// <returns></returns> public TInputOutput[] GetResultsAsArray() { Debug.Assert(_outputArray != null); return _outputArray; } } }