예제 #1
0
        private void InitializePartitions(IEnumerable <T> source, int partitionCount, bool useStriping)
        {
            ParallelEnumerableWrapper <T> wrapper = source as ParallelEnumerableWrapper <T>;

            if (wrapper != null)
            {
                source = wrapper.WrappedEnumerable;
            }
            IList <T> data = source as IList <T>;

            if (data != null)
            {
                QueryOperatorEnumerator <T, int>[] enumeratorArray = new QueryOperatorEnumerator <T, int> [partitionCount];
                int count        = data.Count;
                T[] localArray   = source as T[];
                int maxChunkSize = -1;
                if (useStriping)
                {
                    maxChunkSize = Scheduling.GetDefaultChunkSize <T>();
                    if (maxChunkSize < 1)
                    {
                        maxChunkSize = 1;
                    }
                }
                for (int i = 0; i < partitionCount; i++)
                {
                    if (localArray != null)
                    {
                        if (useStriping)
                        {
                            enumeratorArray[i] = new ArrayIndexRangeEnumerator <T>(localArray, partitionCount, i, maxChunkSize);
                        }
                        else
                        {
                            enumeratorArray[i] = new ArrayContiguousIndexRangeEnumerator <T>(localArray, partitionCount, i);
                        }
                    }
                    else if (useStriping)
                    {
                        enumeratorArray[i] = new ListIndexRangeEnumerator <T>(data, partitionCount, i, maxChunkSize);
                    }
                    else
                    {
                        enumeratorArray[i] = new ListContiguousIndexRangeEnumerator <T>(data, partitionCount, i);
                    }
                }
                base.m_partitions = enumeratorArray;
            }
            else
            {
                base.m_partitions = PartitionedDataSource <T> .MakePartitions(source.GetEnumerator(), partitionCount);
            }
        }
예제 #2
0
        //-----------------------------------------------------------------------------------
        // A factory method to construct a partitioned stream over a data source.
        //
        // Arguments:
        //    source                      - the data source to be partitioned
        //    partitionCount              - the number of partitions desired
        //    useOrdinalOrderPreservation - whether ordinal position must be tracked
        //    useStriping                 - whether striped partitioning should be used instead of range partitioning
        //

        internal static PartitionedStream <T, int> PartitionDataSource <T>(IEnumerable <T> source, int partitionCount, bool useStriping)
        {
            // The partitioned stream to return.
            PartitionedStream <T, int> returnValue;

            IParallelPartitionable <T> sourceAsPartitionable = source as IParallelPartitionable <T>;

            if (sourceAsPartitionable != null)
            {
                // The type overrides the partitioning algorithm, so we will use it instead of the default.
                // The returned enumerator must be the same size that we requested, otherwise we throw.
                QueryOperatorEnumerator <T, int>[] enumerators = sourceAsPartitionable.GetPartitions(partitionCount);
                if (enumerators == null)
                {
                    throw new InvalidOperationException(SR.GetString(SR.ParallelPartitionable_NullReturn));
                }
                else if (enumerators.Length != partitionCount)
                {
                    throw new InvalidOperationException(SR.GetString(SR.ParallelPartitionable_IncorretElementCount));
                }

                // Now just copy the enumerators into the stream, validating that the result is non-null.
                PartitionedStream <T, int> stream =
                    new PartitionedStream <T, int>(partitionCount, Util.GetDefaultComparer <int>(), OrdinalIndexState.Correct);
                for (int i = 0; i < partitionCount; i++)
                {
                    QueryOperatorEnumerator <T, int> currentEnumerator = enumerators[i];
                    if (currentEnumerator == null)
                    {
                        throw new InvalidOperationException(SR.GetString(SR.ParallelPartitionable_NullElement));
                    }
                    stream[i] = currentEnumerator;
                }

                returnValue = stream;
            }
            else
            {
                returnValue = new PartitionedDataSource <T>(source, partitionCount, useStriping);
            }

            Contract.Assert(returnValue.PartitionCount == partitionCount);

            return(returnValue);
        }