diff options
Diffstat (limited to 'src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs')
-rw-r--r-- | src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs | 104 |
1 files changed, 43 insertions, 61 deletions
diff --git a/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs b/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs index 2169c6dee7..9b36c053ad 100644 --- a/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs +++ b/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Security.Permissions; using System.Threading; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; @@ -26,9 +27,6 @@ namespace System.Collections.Concurrent /// non-blocking. These behaviors can be overridden via this enumeration. /// </summary> [Flags] -#if !FEATURE_CORECLR - [Serializable] -#endif public enum EnumerablePartitionerOptions { /// <summary> @@ -71,7 +69,6 @@ namespace System.Collections.Concurrent /// thread. /// </para> /// </remarks> - [HostProtection(Synchronization = true, ExternalThreading = true)] public static class Partitioner { /// <summary> @@ -91,7 +88,7 @@ namespace System.Collections.Concurrent { if (list == null) { - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); } if (loadBalance) { @@ -122,7 +119,7 @@ namespace System.Collections.Concurrent if (array == null) { - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } if (loadBalance) { @@ -172,11 +169,11 @@ namespace System.Collections.Concurrent { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if ((partitionerOptions & (~EnumerablePartitionerOptions.NoBuffering)) != 0) - throw new ArgumentOutOfRangeException("partitionerOptions"); + throw new ArgumentOutOfRangeException(nameof(partitionerOptions)); return (new DynamicPartitionerForIEnumerable<TSource>(source, partitionerOptions)); } @@ -194,7 +191,7 @@ namespace System.Collections.Concurrent // load balancing on a busy system if you make it higher than 1. int coreOversubscriptionRate = 3; - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); long rangeSize = (toExclusive - fromInclusive) / (PlatformHelper.ProcessorCount * coreOversubscriptionRate); if (rangeSize == 0) rangeSize = 1; @@ -212,8 +209,8 @@ namespace System.Collections.Concurrent /// less than or equal to 0.</exception> public static OrderablePartitioner<Tuple<long, long>> Create(long fromInclusive, long toExclusive, long rangeSize) { - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); - if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); + if (rangeSize <= 0) throw new ArgumentOutOfRangeException(nameof(rangeSize)); return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize), EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time } @@ -251,7 +248,7 @@ namespace System.Collections.Concurrent // load balancing on a busy system if you make it higher than 1. int coreOversubscriptionRate = 3; - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); int rangeSize = (toExclusive - fromInclusive) / (PlatformHelper.ProcessorCount * coreOversubscriptionRate); if (rangeSize == 0) rangeSize = 1; @@ -269,8 +266,8 @@ namespace System.Collections.Concurrent /// less than or equal to 0.</exception> public static OrderablePartitioner<Tuple<int, int>> Create(int fromInclusive, int toExclusive, int rangeSize) { - if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); - if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize"); + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive)); + if (rangeSize <= 0) throw new ArgumentOutOfRangeException(nameof(rangeSize)); return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize), EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time } @@ -431,7 +428,7 @@ namespace System.Collections.Concurrent //perform deferred allocating of the local variables. if (m_localOffset == null) { - Contract.Assert(m_currentChunkSize == null); + Debug.Assert(m_currentChunkSize == null); m_localOffset = new SharedInt(-1); m_currentChunkSize = new SharedInt(0); m_doublingCountdown = CHUNK_DOUBLING_RATE; @@ -449,7 +446,7 @@ namespace System.Collections.Concurrent { // The second part of the || condition is necessary to handle the case when MoveNext() is called // after a previous MoveNext call returned false. - Contract.Assert(m_localOffset.Value == m_currentChunkSize.Value - 1 || m_currentChunkSize.Value == 0); + Debug.Assert(m_localOffset.Value == m_currentChunkSize.Value - 1 || m_currentChunkSize.Value == 0); //set the requested chunk size to a proper value int requestedChunkSize; @@ -470,11 +467,11 @@ namespace System.Collections.Concurrent // Decrement your doubling countdown m_doublingCountdown--; - Contract.Assert(requestedChunkSize > 0 && requestedChunkSize <= m_maxChunkSize); + Debug.Assert(requestedChunkSize > 0 && requestedChunkSize <= m_maxChunkSize); //GrabNextChunk will update the value of m_currentChunkSize if (GrabNextChunk(requestedChunkSize)) { - Contract.Assert(m_currentChunkSize.Value <= requestedChunkSize && m_currentChunkSize.Value > 0); + Debug.Assert(m_currentChunkSize.Value <= requestedChunkSize && m_currentChunkSize.Value > 0); m_localOffset.Value = 0; return true; } @@ -517,7 +514,7 @@ namespace System.Collections.Concurrent { if (partitionCount <= 0) { - throw new ArgumentOutOfRangeException("partitionCount"); + throw new ArgumentOutOfRangeException(nameof(partitionCount)); } IEnumerator<KeyValuePair<long, TSource>>[] partitions = new IEnumerator<KeyValuePair<long, TSource>>[partitionCount]; @@ -715,10 +712,10 @@ namespace System.Collections.Concurrent /// </returns> internal bool GrabChunk_Single(KeyValuePair<long,TSource>[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed) { - Contract.Assert(m_useSingleChunking, "Expected m_useSingleChecking to be true"); - Contract.Assert(requestedChunkSize == 1, "Got requested chunk size of " + requestedChunkSize + " when single-chunking was on"); - Contract.Assert(actualNumElementsGrabbed == 0, "Expected actualNumElementsGrabbed == 0, instead it is " + actualNumElementsGrabbed); - Contract.Assert(destArray.Length == 1, "Expected destArray to be of length 1, instead its length is " + destArray.Length); + Debug.Assert(m_useSingleChunking, "Expected m_useSingleChecking to be true"); + Debug.Assert(requestedChunkSize == 1, "Got requested chunk size of " + requestedChunkSize + " when single-chunking was on"); + Debug.Assert(actualNumElementsGrabbed == 0, "Expected actualNumElementsGrabbed == 0, instead it is " + actualNumElementsGrabbed); + Debug.Assert(destArray.Length == 1, "Expected destArray to be of length 1, instead its length is " + destArray.Length); lock (m_sharedLock) { @@ -764,8 +761,8 @@ namespace System.Collections.Concurrent /// </returns> internal bool GrabChunk_Buffered(KeyValuePair<long,TSource>[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed) { - Contract.Assert(requestedChunkSize > 0); - Contract.Assert(!m_useSingleChunking, "Did not expect to be in single-chunking mode"); + Debug.Assert(requestedChunkSize > 0); + Debug.Assert(!m_useSingleChunking, "Did not expect to be in single-chunking mode"); TryCopyFromFillBuffer(destArray, requestedChunkSize, ref actualNumElementsGrabbed); @@ -803,7 +800,7 @@ namespace System.Collections.Concurrent while( m_activeCopiers > 0) sw.SpinOnce(); } - Contract.Assert(m_sharedIndex != null); //already been allocated in MoveNext() before calling GrabNextChunk + Debug.Assert(m_sharedIndex != null); //already been allocated in MoveNext() before calling GrabNextChunk // Now's the time to actually enumerate the source @@ -940,7 +937,7 @@ namespace System.Collections.Concurrent /// </returns> override protected bool GrabNextChunk(int requestedChunkSize) { - Contract.Assert(requestedChunkSize > 0); + Debug.Assert(requestedChunkSize > 0); if (HasNoElementsLeft) { @@ -973,8 +970,8 @@ namespace System.Collections.Concurrent { //we only set it from false to true once //we should never set it back in any circumstances - Contract.Assert(value); - Contract.Assert(!m_hasNoElementsLeft.Value); + Debug.Assert(value); + Debug.Assert(!m_hasNoElementsLeft.Value); m_hasNoElementsLeft.Value = true; } } @@ -988,8 +985,8 @@ namespace System.Collections.Concurrent { throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_localList != null); - Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); + Debug.Assert(m_localList != null); + Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); return (m_localList[m_localOffset.Value]); } } @@ -1053,7 +1050,7 @@ namespace System.Collections.Concurrent { if (partitionCount <= 0) { - throw new ArgumentOutOfRangeException("partitionCount"); + throw new ArgumentOutOfRangeException(nameof(partitionCount)); } IEnumerator<KeyValuePair<long, TSource>>[] partitions = new IEnumerator<KeyValuePair<long, TSource>>[partitionCount]; @@ -1127,11 +1124,11 @@ namespace System.Collections.Concurrent /// </returns> override protected bool GrabNextChunk(int requestedChunkSize) { - Contract.Assert(requestedChunkSize > 0); + Debug.Assert(requestedChunkSize > 0); while (!HasNoElementsLeft) { - Contract.Assert(m_sharedIndex != null); + Debug.Assert(m_sharedIndex != null); // use the new Volatile.Read method because it is cheaper than Interlocked.Read on AMD64 architecture long oldSharedIndex = Volatile.Read(ref m_sharedIndex.Value); @@ -1173,13 +1170,13 @@ namespace System.Collections.Concurrent { get { - Contract.Assert(m_sharedIndex != null); + Debug.Assert(m_sharedIndex != null); // use the new Volatile.Read method because it is cheaper than Interlocked.Read on AMD64 architecture return Volatile.Read(ref m_sharedIndex.Value) >= SourceCount - 1; } set { - Contract.Assert(false); + Debug.Assert(false); } } @@ -1268,7 +1265,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); + Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); return new KeyValuePair<long, TSource>(m_startIndex + m_localOffset.Value, m_sharedReader[m_startIndex + m_localOffset.Value]); } @@ -1352,7 +1349,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); + Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value); return new KeyValuePair<long, TSource>(m_startIndex + m_localOffset.Value, m_sharedReader[m_startIndex + m_localOffset.Value]); } @@ -1417,7 +1414,7 @@ namespace System.Collections.Concurrent { if (partitionCount <= 0) { - throw new ArgumentOutOfRangeException("partitionCount"); + throw new ArgumentOutOfRangeException(nameof(partitionCount)); } int quotient, remainder; @@ -1539,7 +1536,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionerForIList(IList<TSource> list) : base() { - Contract.Assert(list != null); + Debug.Assert(list != null); m_list = list; } override protected int SourceCount @@ -1565,7 +1562,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionForIList(IList<TSource> list, int startIndex, int endIndex) : base(startIndex, endIndex) { - Contract.Assert(startIndex >= 0 && endIndex <= list.Count - 1); + Debug.Assert(startIndex >= 0 && endIndex <= list.Count - 1); m_list = list; } @@ -1579,7 +1576,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); + Debug.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); return (new KeyValuePair<long, TSource>(m_offset, m_list[m_offset])); } } @@ -1597,7 +1594,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionerForArray(TSource[] array) : base() { - Contract.Assert(array != null); + Debug.Assert(array != null); m_array = array; } override protected int SourceCount @@ -1622,7 +1619,7 @@ namespace System.Collections.Concurrent internal StaticIndexRangePartitionForArray(TSource[] array, int startIndex, int endIndex) : base(startIndex, endIndex) { - Contract.Assert(startIndex >= 0 && endIndex <= array.Length - 1); + Debug.Assert(startIndex >= 0 && endIndex <= array.Length - 1); m_array = array; } @@ -1636,7 +1633,7 @@ namespace System.Collections.Concurrent throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext")); } - Contract.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); + Debug.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex); return (new KeyValuePair<long, TSource>(m_offset, m_array[m_offset])); } } @@ -1704,30 +1701,15 @@ namespace System.Collections.Concurrent if (typeof(TSource).IsValueType) { -#if !FEATURE_CORECLR // Marshal.SizeOf is not supported in CoreCLR - - if (typeof(TSource).StructLayoutAttribute.Value == LayoutKind.Explicit) - { - chunkSize = Math.Max(1, DEFAULT_BYTES_PER_CHUNK / Marshal.SizeOf(typeof(TSource))); - } - else - { - // We choose '128' because this ensures, no matter the actual size of the value type, - // the total bytes used will be a multiple of 128. This ensures it's cache aligned. - chunkSize = 128; - } -#else chunkSize = 128; -#endif } else { - Contract.Assert((DEFAULT_BYTES_PER_CHUNK % IntPtr.Size) == 0, "bytes per chunk should be a multiple of pointer size"); + Debug.Assert((DEFAULT_BYTES_PER_CHUNK % IntPtr.Size) == 0, "bytes per chunk should be a multiple of pointer size"); chunkSize = (DEFAULT_BYTES_PER_CHUNK / IntPtr.Size); } return chunkSize; } #endregion - } } |