095777506e4fddd5e2ce936ded549968405338d8
[mono.git] / mcs / class / referencesource / mscorlib / system / collections / Concurrent / Partitioner.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
7 //
8 // Partitioner.cs
9 //
10 // <OWNER>Microsoft</OWNER>
11 //
12 // Represents a particular way of splitting a collection into multiple partitions.
13 //
14 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
15
16 using System;
17 using System.Collections.Generic;
18 using System.Security.Permissions;
19 using System.Threading;
20
21 namespace System.Collections.Concurrent
22 {
23     /// <summary>
24     /// Represents a particular manner of splitting a data source into multiple partitions.
25     /// </summary>
26     /// <typeparam name="TSource">Type of the elements in the collection.</typeparam>
27     /// <remarks>
28     /// <para>
29     /// Inheritors of <see cref="Partitioner{TSource}"/> must adhere to the following rules:
30     /// <ol>
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>
47     /// </ol>
48     /// </para>
49     /// </remarks>
50     [HostProtection(Synchronization = true, ExternalThreading = true)]
51     public abstract class Partitioner<TSource>
52     {
53         /// <summary>
54         /// Partitions the underlying collection into the given number of partitions.
55         /// </summary>
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);
59
60         /// <summary>
61         /// Gets whether additional partitions can be created dynamically.
62         /// </summary>
63         /// <returns>
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.
67         /// </returns>
68         /// <remarks>
69         /// <para>
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.
73         /// </para>
74         /// </remarks>
75         public virtual bool SupportsDynamicPartitions
76         {
77             get { return false; }
78         }
79
80         /// <summary>
81         /// Creates an object that can partition the underlying collection into a variable number of
82         /// partitions.
83         /// </summary>
84         /// <remarks>
85         /// <para>
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.
90         /// </para>
91         /// <para>
92         /// The <see cref="GetDynamicPartitions"/> method is only supported if the <see
93         /// cref="SupportsDynamicPartitions"/>
94         /// property returns true.
95         /// </para>
96         /// </remarks>
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()
101         {
102             throw new NotSupportedException(Environment.GetResourceString("Partitioner_DynamicPartitionsNotSupported"));
103         }
104     }
105 }