34 namespace System.Collections.Concurrent.Partitioners
37 internal class ListPartitioner<T> : OrderablePartitioner<T>
41 public ListPartitioner (IList<T> source) : base (true, true, true)
46 public override IList<IEnumerator<KeyValuePair<long, T>>> GetOrderablePartitions (
int partitionCount)
48 if (partitionCount <= 0)
49 throw new ArgumentOutOfRangeException (
"partitionCount");
51 IEnumerator<KeyValuePair<long, T>>[] enumerators
52 =
new IEnumerator<KeyValuePair<long, T>>[partitionCount];
54 int count = source.Count / partitionCount;
57 if (source.Count < partitionCount) {
60 extra = source.Count % partitionCount;
67 Range[] ranges =
new Range[enumerators.Length];
68 for (
int i = 0; i < ranges.Length; i++) {
69 ranges[i] =
new Range (currentIndex,
70 currentIndex + count);
71 currentIndex += count;
76 for (
int i = 0; i < enumerators.Length; i++) {
77 enumerators[i] = GetEnumeratorForRange (ranges, i);
86 public readonly
int LastIndex;
88 public Range (
int frm,
int lastIndex)
91 LastIndex = lastIndex;
95 IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRange (Range[] ranges,
int workerIndex)
97 if (ranges[workerIndex].Actual >= source.Count)
100 return GetEnumeratorForRangeInternal (ranges, workerIndex);
103 IEnumerator<KeyValuePair<long, T>> GetEmpty ()
108 IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRangeInternal (Range[] ranges,
int workerIndex)
110 Range range = ranges[workerIndex];
111 int lastIndex = range.LastIndex;
112 int index = range.Actual;
114 for (
int i = index; i < lastIndex; i = ++range.Actual) {
115 yield
return new KeyValuePair<long, T> (i, source[i]);