3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
10 // <OWNER>Microsoft</OWNER>
12 // Represents a particular way of splitting a collection into multiple partitions.
14 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
17 using System.Collections.Generic;
18 using System.Security.Permissions;
19 using System.Threading;
21 namespace System.Collections.Concurrent
24 /// Represents a particular manner of splitting a data source into multiple partitions.
26 /// <typeparam name="TSource">Type of the elements in the collection.</typeparam>
29 /// Inheritors of <see cref="Partitioner{TSource}"/> must adhere to the following rules:
31 /// <li><see cref="GetPartitions"/> should throw a
32 /// <see cref="T:System.ArgumentOutOfRangeException"/> if the requested partition count is less than or
33 /// equal to zero.</li>
34 /// <li><see cref="GetPartitions"/> should always return a number of enumerables equal to the requested
35 /// partition count. If the partitioner runs out of data and cannot create as many partitions as
36 /// requested, an empty enumerator should be returned for each of the remaining partitions. If this rule
37 /// is not followed, consumers of the implementation may throw a <see
38 /// cref="T:System.InvalidOperationException"/>.</li>
39 /// <li><see cref="GetPartitions"/> and <see cref="GetDynamicPartitions"/>
40 /// should never return null. If null is returned, a consumer of the implementation may throw a
41 /// <see cref="T:System.InvalidOperationException"/>.</li>
42 /// <li><see cref="GetPartitions"/> and <see cref="GetDynamicPartitions"/> should always return
43 /// partitions that can fully and uniquely enumerate the input data source. All of the data and only the
44 /// data contained in the input source should be enumerated, with no duplication that was not already in
45 /// the input, unless specifically required by the particular partitioner's design. If this is not
46 /// followed, the output ordering may be scrambled.</li>
50 [HostProtection(Synchronization = true, ExternalThreading = true)]
51 public abstract class Partitioner<TSource>
54 /// Partitions the underlying collection into the given number of partitions.
56 /// <param name="partitionCount">The number of partitions to create.</param>
57 /// <returns>A list containing <paramref name="partitionCount"/> enumerators.</returns>
58 public abstract IList<IEnumerator<TSource>> GetPartitions(int partitionCount);
61 /// Gets whether additional partitions can be created dynamically.
64 /// true if the <see cref="Partitioner{TSource}"/> can create partitions dynamically as they are
65 /// requested; false if the <see cref="Partitioner{TSource}"/> can only allocate
66 /// partitions statically.
70 /// If a derived class does not override and implement <see cref="GetDynamicPartitions"/>,
71 /// <see cref="SupportsDynamicPartitions"/> should return false. The value of <see
72 /// cref="SupportsDynamicPartitions"/> should not vary over the lifetime of this instance.
75 public virtual bool SupportsDynamicPartitions
81 /// Creates an object that can partition the underlying collection into a variable number of
86 /// The returned object implements the <see
87 /// cref="T:System.Collections.Generic.IEnumerable{TSource}"/> interface. Calling <see
88 /// cref="System.Collections.Generic.IEnumerable{TSource}.GetEnumerator">GetEnumerator</see> on the
89 /// object creates another partition over the sequence.
92 /// The <see cref="GetDynamicPartitions"/> method is only supported if the <see
93 /// cref="SupportsDynamicPartitions"/>
94 /// property returns true.
97 /// <returns>An object that can create partitions over the underlying data source.</returns>
98 /// <exception cref="NotSupportedException">Dynamic partitioning is not supported by this
99 /// partitioner.</exception>
100 public virtual IEnumerable<TSource> GetDynamicPartitions()
102 throw new NotSupportedException(Environment.GetResourceString("Partitioner_DynamicPartitionsNotSupported"));