Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,128 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// CDSCollectionETWBCLProvider.cs
//
// <OWNER>[....]</OWNER>
//
// A helper class for firing ETW events related to the Coordination Data Structure
// collection types. This provider is used by CDS collections in both mscorlib.dll
// and System.dll. The purpose of sharing the provider class is to be able to enable
// ETW tracing on all CDS collection with a single ETW provider GUID, and to minimize
// the number of providers in use.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
using System.Collections.Generic;
using System.Text;
namespace System.Collections.Concurrent
{
#if !FEATURE_PAL // PAL doesn't support eventing
using System.Diagnostics.Tracing;
/// <summary>Provides an event source for tracing CDS collection information.</summary>
[System.Runtime.CompilerServices.FriendAccessAllowed]
[EventSource(
Name = "System.Collections.Concurrent.ConcurrentCollectionsEventSource",
Guid = "35167F8E-49B2-4b96-AB86-435B59336B5E",
LocalizationResources = "mscorlib")]
internal sealed class CDSCollectionETWBCLProvider : EventSource
{
/// <summary>
/// Defines the singleton instance for the collection ETW provider.
/// The collection provider GUID is {35167F8E-49B2-4b96-AB86-435B59336B5E}.
/// </summary>
public static CDSCollectionETWBCLProvider Log = new CDSCollectionETWBCLProvider();
/// <summary>Prevent external instantiation. All logging should go through the Log instance.</summary>
private CDSCollectionETWBCLProvider() { }
/// <summary>Enabled for all keywords.</summary>
private const EventKeywords ALL_KEYWORDS = (EventKeywords)(-1);
//-----------------------------------------------------------------------------------
//
// CDS Collection Event IDs (must be unique)
//
private const int CONCURRENTSTACK_FASTPUSHFAILED_ID = 1;
private const int CONCURRENTSTACK_FASTPOPFAILED_ID = 2;
private const int CONCURRENTDICTIONARY_ACQUIRINGALLLOCKS_ID = 3;
private const int CONCURRENTBAG_TRYTAKESTEALS_ID = 4;
private const int CONCURRENTBAG_TRYPEEKSTEALS_ID = 5;
/////////////////////////////////////////////////////////////////////////////////////
//
// ConcurrentStack Events
//
[Event(CONCURRENTSTACK_FASTPUSHFAILED_ID, Level = EventLevel.Warning)]
public void ConcurrentStack_FastPushFailed(int spinCount)
{
if (IsEnabled(EventLevel.Warning, ALL_KEYWORDS))
{
WriteEvent(CONCURRENTSTACK_FASTPUSHFAILED_ID, spinCount);
}
}
[Event(CONCURRENTSTACK_FASTPOPFAILED_ID, Level = EventLevel.Warning)]
public void ConcurrentStack_FastPopFailed(int spinCount)
{
if (IsEnabled(EventLevel.Warning, ALL_KEYWORDS))
{
WriteEvent(CONCURRENTSTACK_FASTPOPFAILED_ID, spinCount);
}
}
/////////////////////////////////////////////////////////////////////////////////////
//
// ConcurrentDictionary Events
//
[Event(CONCURRENTDICTIONARY_ACQUIRINGALLLOCKS_ID, Level = EventLevel.Warning)]
public void ConcurrentDictionary_AcquiringAllLocks(int numOfBuckets)
{
if (IsEnabled(EventLevel.Warning, ALL_KEYWORDS))
{
WriteEvent(CONCURRENTDICTIONARY_ACQUIRINGALLLOCKS_ID, numOfBuckets);
}
}
//
// Events below this point are used by the CDS types in System.DLL
//
/////////////////////////////////////////////////////////////////////////////////////
//
// ConcurrentBag Events
//
[Event(CONCURRENTBAG_TRYTAKESTEALS_ID, Level = EventLevel.Verbose)]
public void ConcurrentBag_TryTakeSteals()
{
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
{
WriteEvent(CONCURRENTBAG_TRYTAKESTEALS_ID);
}
}
[Event(CONCURRENTBAG_TRYPEEKSTEALS_ID, Level = EventLevel.Verbose)]
public void ConcurrentBag_TryPeekSteals()
{
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
{
WriteEvent(CONCURRENTBAG_TRYPEEKSTEALS_ID);
}
}
}
#endif // !FEATURE_PAL
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// IProducerConsumerCollection.cs
//
// <OWNER>[....]</OWNER>
//
// A common interface for all concurrent collections.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Collections.Concurrent
{
/// <summary>
/// Defines methods to manipulate thread-safe collections intended for producer/consumer usage.
/// </summary>
/// <typeparam name="T">Specifies the type of elements in the collection.</typeparam>
/// <remarks>
/// All implementations of this interface must enable all members of this interface
/// to be used concurrently from multiple threads.
/// </remarks>
public interface IProducerConsumerCollection<T> : IEnumerable<T>, ICollection
{
/// <summary>
/// Copies the elements of the <see cref="IProducerConsumerCollection{T}"/> to
/// an
/// <see cref="T:System.Array"/>, starting at a specified index.
/// </summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of
/// the elements copied from the <see cref="IProducerConsumerCollection{T}"/>.
/// The array must have zero-based indexing.</param>
/// <param name="index">The zero-based index in <paramref name="array"/> at which copying
/// begins.</param>
/// <exception cref="ArgumentNullException"><paramref name="array"/> is a null reference (Nothing in
/// Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than
/// zero.</exception>
/// <exception cref="ArgumentException"><paramref name="index"/> is equal to or greater than the
/// length of the <paramref name="array"/>
/// -or- The number of elements in the source <see cref="ConcurrentQueue{T}"/> is greater than the
/// available space from <paramref name="index"/> to the end of the destination <paramref
/// name="array"/>.
/// </exception>
void CopyTo(T[] array, int index);
/// <summary>
/// Attempts to add an object to the <see
/// cref="IProducerConsumerCollection{T}"/>.
/// </summary>
/// <param name="item">The object to add to the <see
/// cref="IProducerConsumerCollection{T}"/>.</param>
/// <returns>true if the object was added successfully; otherwise, false.</returns>
/// <exception cref="T:System.ArgumentException">The <paramref name="item"/> was invalid for this collection.</exception>
bool TryAdd(T item);
/// <summary>
/// Attempts to remove and return an object from the <see cref="IProducerConsumerCollection{T}"/>.
/// </summary>
/// <param name="item">
/// When this method returns, if the object was removed and returned successfully, <paramref
/// name="item"/> contains the removed object. If no object was available to be removed, the value is
/// unspecified.
/// </param>
/// <returns>true if an object was removed and returned successfully; otherwise, false.</returns>
bool TryTake(out T item);
/// <summary>
/// Copies the elements contained in the <see cref="IProducerConsumerCollection{T}"/> to a new array.
/// </summary>
/// <returns>A new array containing the elements copied from the <see cref="IProducerConsumerCollection{T}"/>.</returns>
T[] ToArray();
}
/// <summary>
/// A debugger view of the IProducerConsumerCollection that makes it simple to browse the
/// collection's contents at a point in time.
/// </summary>
/// <typeparam name="T">The type of elements stored within.</typeparam>
internal sealed class SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<T>
{
private IProducerConsumerCollection<T> m_collection; // The collection being viewed.
/// <summary>
/// Constructs a new debugger view object for the provided collection object.
/// </summary>
/// <param name="collection">A collection to browse in the debugger.</param>
public SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView(IProducerConsumerCollection<T> collection)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
m_collection = collection;
}
/// <summary>
/// Returns a snapshot of the underlying collection's elements.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public T[] Items
{
get { return m_collection.ToArray(); }
}
}
}

View File

@@ -0,0 +1,284 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// OrderablePartitioner.cs
//
// <OWNER>[....]</OWNER>
//
//
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Threading;
namespace System.Collections.Concurrent
{
/// <summary>
/// Represents a particular manner of splitting an orderable data source into multiple partitions.
/// </summary>
/// <typeparam name="TSource">Type of the elements in the collection.</typeparam>
/// <remarks>
/// <para>
/// Each element in each partition has an integer index associated with it, which determines the relative
/// order of that element against elements in other partitions.
/// </para>
/// <para>
/// Inheritors of <see cref="OrderablePartitioner{TSource}"/> must adhere to the following rules:
/// <ol>
/// <li>All indices must be unique, such that there may not be duplicate indices. If all indices are not
/// unique, the output ordering may be scrambled.</li>
/// <li>All indices must be non-negative. If any indices are negative, consumers of the implementation
/// may throw exceptions.</li>
/// <li><see cref="GetPartitions"/> and <see cref="GetOrderablePartitions"/> should throw a
/// <see cref="T:System.ArgumentOutOfRangeException"/> if the requested partition count is less than or
/// equal to zero.</li>
/// <li><see cref="GetPartitions"/> and <see cref="GetOrderablePartitions"/> should always return a number
/// of enumerables equal to the requested partition count. If the partitioner runs out of data and cannot
/// create as many partitions as requested, an empty enumerator should be returned for each of the
/// remaining partitions. If this rule is not followed, consumers of the implementation may throw a <see
/// cref="T:System.InvalidOperationException"/>.</li>
/// <li><see cref="GetPartitions"/>, <see cref="GetOrderablePartitions"/>,
/// <see cref="GetDynamicPartitions"/>, and <see cref="GetOrderableDynamicPartitions"/>
/// should never return null. If null is returned, a consumer of the implementation may throw a
/// <see cref="T:System.InvalidOperationException"/>.</li>
/// <li><see cref="GetPartitions"/>, <see cref="GetOrderablePartitions"/>,
/// <see cref="GetDynamicPartitions"/>, and <see cref="GetOrderableDynamicPartitions"/>
/// should always return partitions that can fully and uniquely enumerate the input data source. All of
/// the data and only the data contained in the input source should be enumerated, with no duplication
/// that was not already in the input, unless specifically required by the particular partitioner's
/// design. If this is not followed, the output ordering may be scrambled.</li>
/// <li>If <see cref="KeysOrderedInEachPartition"/> returns true, each partition must return elements
/// with increasing key indices.</li>
/// <li>If <see cref="KeysOrderedAcrossPartitions"/> returns true, all the keys in partition numbered N
/// must be larger than all the keys in partition numbered N-1.</li>
/// <li>If <see cref="KeysNormalized"/> returns true, all indices must be monotonically increasing from
/// 0, though not necessarily within a single partition.</li>
/// </ol>
/// </para>
/// </remarks>
[HostProtection(Synchronization = true, ExternalThreading = true)]
public abstract class OrderablePartitioner<TSource> : Partitioner<TSource>
{
/// <summary>
/// Initializes a new instance of the <see cref="OrderablePartitioner{TSource}"/> class with the
/// specified constraints on the index keys.
/// </summary>
/// <param name="keysOrderedInEachPartition">
/// Indicates whether the elements in each partition are yielded in the order of
/// increasing keys.
/// </param>
/// <param name="keysOrderedAcrossPartitions">
/// Indicates whether elements in an earlier partition always come before
/// elements in a later partition. If true, each element in partition 0 has a smaller order key than
/// any element in partition 1, each element in partition 1 has a smaller order key than any element
/// in partition 2, and so on.
/// </param>
/// <param name="keysNormalized">
/// Indicates whether keys are normalized. If true, all order keys are distinct
/// integers in the range [0 .. numberOfElements-1]. If false, order keys must still be dictinct, but
/// only their relative order is considered, not their absolute values.
/// </param>
protected OrderablePartitioner(bool keysOrderedInEachPartition, bool keysOrderedAcrossPartitions, bool keysNormalized)
{
KeysOrderedInEachPartition = keysOrderedInEachPartition;
KeysOrderedAcrossPartitions = keysOrderedAcrossPartitions;
KeysNormalized = keysNormalized;
}
/// <summary>
/// Partitions the underlying collection into the specified number of orderable partitions.
/// </summary>
/// <remarks>
/// Each partition is represented as an enumerator over key-value pairs.
/// The value of the pair is the element itself, and the key is an integer which determines
/// the relative ordering of this element against other elements in the data source.
/// </remarks>
/// <param name="partitionCount">The number of partitions to create.</param>
/// <returns>A list containing <paramref name="partitionCount"/> enumerators.</returns>
public abstract IList<IEnumerator<KeyValuePair<long, TSource>>> GetOrderablePartitions(int partitionCount);
/// <summary>
/// Creates an object that can partition the underlying collection into a variable number of
/// partitions.
/// </summary>
/// <remarks>
/// <para>
/// The returned object implements the <see
/// cref="T:System.Collections.Generic.IEnumerable{TSource}"/> interface. Calling <see
/// cref="System.Collections.Generic.IEnumerable{TSource}.GetEnumerator">GetEnumerator</see> on the
/// object creates another partition over the sequence.
/// </para>
/// <para>
/// Each partition is represented as an enumerator over key-value pairs. The value in the pair is the element
/// itself, and the key is an integer which determines the relative ordering of this element against
/// other elements.
/// </para>
/// <para>
/// The <see cref="GetOrderableDynamicPartitions"/> method is only supported if the <see
/// cref="System.Collections.Concurrent.Partitioner{TSource}.SupportsDynamicPartitions">SupportsDynamicPartitions</see>
/// property returns true.
/// </para>
/// </remarks>
/// <returns>An object that can create partitions over the underlying data source.</returns>
/// <exception cref="NotSupportedException">Dynamic partitioning is not supported by this
/// partitioner.</exception>
public virtual IEnumerable<KeyValuePair<long, TSource>> GetOrderableDynamicPartitions()
{
throw new NotSupportedException(Environment.GetResourceString("Partitioner_DynamicPartitionsNotSupported"));
}
/// <summary>
/// Gets whether elements in each partition are yielded in the order of increasing keys.
/// </summary>
public bool KeysOrderedInEachPartition { get; private set; }
/// <summary>
/// Gets whether elements in an earlier partition always come before elements in a later partition.
/// </summary>
/// <remarks>
/// If <see cref="KeysOrderedAcrossPartitions"/> returns true, each element in partition 0 has a
/// smaller order key than any element in partition 1, each element in partition 1 has a smaller
/// order key than any element in partition 2, and so on.
/// </remarks>
public bool KeysOrderedAcrossPartitions { get; private set; }
/// <summary>
/// Gets whether order keys are normalized.
/// </summary>
/// <remarks>
/// If <see cref="KeysNormalized"/> returns true, all order keys are distinct integers in the range
/// [0 .. numberOfElements-1]. If the property returns false, order keys must still be dictinct, but
/// only their relative order is considered, not their absolute values.
/// </remarks>
public bool KeysNormalized { get; private set; }
/// <summary>
/// Partitions the underlying collection into the given number of ordered partitions.
/// </summary>
/// <remarks>
/// The default implementation provides the same behavior as <see cref="GetOrderablePartitions"/> except
/// that the returned set of partitions does not provide the keys for the elements.
/// </remarks>
/// <param name="partitionCount">The number of partitions to create.</param>
/// <returns>A list containing <paramref name="partitionCount"/> enumerators.</returns>
public override IList<IEnumerator<TSource>> GetPartitions(int partitionCount)
{
IList<IEnumerator<KeyValuePair<long, TSource>>> orderablePartitions = GetOrderablePartitions(partitionCount);
if (orderablePartitions.Count != partitionCount)
{
throw new InvalidOperationException("OrderablePartitioner_GetPartitions_WrongNumberOfPartitions");
}
IEnumerator<TSource>[] partitions = new IEnumerator<TSource>[partitionCount];
for (int i = 0; i < partitionCount; i++)
{
partitions[i] = new EnumeratorDropIndices(orderablePartitions[i]);
}
return partitions;
}
/// <summary>
/// Creates an object that can partition the underlying collection into a variable number of
/// partitions.
/// </summary>
/// <remarks>
/// <para>
/// The returned object implements the <see
/// cref="T:System.Collections.Generic.IEnumerable{TSource}"/> interface. Calling <see
/// cref="System.Collections.Generic.IEnumerable{TSource}.GetEnumerator">GetEnumerator</see> on the
/// object creates another partition over the sequence.
/// </para>
/// <para>
/// The default implementation provides the same behavior as <see cref="GetOrderableDynamicPartitions"/> except
/// that the returned set of partitions does not provide the keys for the elements.
/// </para>
/// <para>
/// The <see cref="GetDynamicPartitions"/> method is only supported if the <see
/// cref="System.Collections.Concurrent.Partitioner{TSource}.SupportsDynamicPartitions"/>
/// property returns true.
/// </para>
/// </remarks>
/// <returns>An object that can create partitions over the underlying data source.</returns>
/// <exception cref="NotSupportedException">Dynamic partitioning is not supported by this
/// partitioner.</exception>
public override IEnumerable<TSource> GetDynamicPartitions()
{
IEnumerable<KeyValuePair<long, TSource>> orderablePartitions = GetOrderableDynamicPartitions();
return new EnumerableDropIndices(orderablePartitions);
}
/// <summary>
/// Converts an enumerable over key-value pairs to an enumerable over values.
/// </summary>
private class EnumerableDropIndices : IEnumerable<TSource>, IDisposable
{
private readonly IEnumerable<KeyValuePair<long, TSource>> m_source;
public EnumerableDropIndices(IEnumerable<KeyValuePair<long, TSource>> source)
{
m_source = source;
}
public IEnumerator<TSource> GetEnumerator()
{
return new EnumeratorDropIndices(m_source.GetEnumerator());
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((EnumerableDropIndices)this).GetEnumerator();
}
public void Dispose()
{
IDisposable d = m_source as IDisposable;
if (d != null)
{
d.Dispose();
}
}
}
private class EnumeratorDropIndices : IEnumerator<TSource>
{
private readonly IEnumerator<KeyValuePair<long, TSource>> m_source;
public EnumeratorDropIndices(IEnumerator<KeyValuePair<long, TSource>> source)
{
m_source = source;
}
public bool MoveNext()
{
return m_source.MoveNext();
}
public TSource Current
{
get
{
return m_source.Current.Value;
}
}
Object IEnumerator.Current
{
get
{
return ((EnumeratorDropIndices)this).Current;
}
}
public void Dispose()
{
m_source.Dispose();
}
public void Reset()
{
m_source.Reset();
}
}
}
}

View File

@@ -0,0 +1,105 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// Partitioner.cs
//
// <OWNER>[....]</OWNER>
//
// Represents a particular way of splitting a collection into multiple partitions.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Threading;
namespace System.Collections.Concurrent
{
/// <summary>
/// Represents a particular manner of splitting a data source into multiple partitions.
/// </summary>
/// <typeparam name="TSource">Type of the elements in the collection.</typeparam>
/// <remarks>
/// <para>
/// Inheritors of <see cref="Partitioner{TSource}"/> must adhere to the following rules:
/// <ol>
/// <li><see cref="GetPartitions"/> should throw a
/// <see cref="T:System.ArgumentOutOfRangeException"/> if the requested partition count is less than or
/// equal to zero.</li>
/// <li><see cref="GetPartitions"/> should always return a number of enumerables equal to the requested
/// partition count. If the partitioner runs out of data and cannot create as many partitions as
/// requested, an empty enumerator should be returned for each of the remaining partitions. If this rule
/// is not followed, consumers of the implementation may throw a <see
/// cref="T:System.InvalidOperationException"/>.</li>
/// <li><see cref="GetPartitions"/> and <see cref="GetDynamicPartitions"/>
/// should never return null. If null is returned, a consumer of the implementation may throw a
/// <see cref="T:System.InvalidOperationException"/>.</li>
/// <li><see cref="GetPartitions"/> and <see cref="GetDynamicPartitions"/> should always return
/// partitions that can fully and uniquely enumerate the input data source. All of the data and only the
/// data contained in the input source should be enumerated, with no duplication that was not already in
/// the input, unless specifically required by the particular partitioner's design. If this is not
/// followed, the output ordering may be scrambled.</li>
/// </ol>
/// </para>
/// </remarks>
[HostProtection(Synchronization = true, ExternalThreading = true)]
public abstract class Partitioner<TSource>
{
/// <summary>
/// Partitions the underlying collection into the given number of partitions.
/// </summary>
/// <param name="partitionCount">The number of partitions to create.</param>
/// <returns>A list containing <paramref name="partitionCount"/> enumerators.</returns>
public abstract IList<IEnumerator<TSource>> GetPartitions(int partitionCount);
/// <summary>
/// Gets whether additional partitions can be created dynamically.
/// </summary>
/// <returns>
/// true if the <see cref="Partitioner{TSource}"/> can create partitions dynamically as they are
/// requested; false if the <see cref="Partitioner{TSource}"/> can only allocate
/// partitions statically.
/// </returns>
/// <remarks>
/// <para>
/// If a derived class does not override and implement <see cref="GetDynamicPartitions"/>,
/// <see cref="SupportsDynamicPartitions"/> should return false. The value of <see
/// cref="SupportsDynamicPartitions"/> should not vary over the lifetime of this instance.
/// </para>
/// </remarks>
public virtual bool SupportsDynamicPartitions
{
get { return false; }
}
/// <summary>
/// Creates an object that can partition the underlying collection into a variable number of
/// partitions.
/// </summary>
/// <remarks>
/// <para>
/// The returned object implements the <see
/// cref="T:System.Collections.Generic.IEnumerable{TSource}"/> interface. Calling <see
/// cref="System.Collections.Generic.IEnumerable{TSource}.GetEnumerator">GetEnumerator</see> on the
/// object creates another partition over the sequence.
/// </para>
/// <para>
/// The <see cref="GetDynamicPartitions"/> method is only supported if the <see
/// cref="SupportsDynamicPartitions"/>
/// property returns true.
/// </para>
/// </remarks>
/// <returns>An object that can create partitions over the underlying data source.</returns>
/// <exception cref="NotSupportedException">Dynamic partitioning is not supported by this
/// partitioner.</exception>
public virtual IEnumerable<TSource> GetDynamicPartitions()
{
throw new NotSupportedException(Environment.GetResourceString("Partitioner_DynamicPartitionsNotSupported"));
}
}
}

File diff suppressed because it is too large Load Diff