34 namespace System.Collections.Concurrent.Partitioners
39 IEnumerable<T> source;
41 const int InitialPartitionSize = 1;
42 const int PartitionMultiplier = 2;
44 int initialPartitionSize;
45 int partitionMultiplier;
47 public EnumerablePartitioner (IEnumerable<T> source)
48 :
this (source, InitialPartitionSize, PartitionMultiplier)
54 public EnumerablePartitioner (IEnumerable<T> source,
int initialPartitionSize,
int partitionMultiplier)
55 : base (
true,
false,
true)
58 this.initialPartitionSize = initialPartitionSize;
59 this.partitionMultiplier = partitionMultiplier;
62 public override IList<IEnumerator<KeyValuePair<long, T>>> GetOrderablePartitions (
int partitionCount)
64 if (partitionCount <= 0)
65 throw new ArgumentOutOfRangeException (
"partitionCount");
67 IEnumerator<KeyValuePair<long, T>>[] enumerators
68 =
new IEnumerator<KeyValuePair<long, T>>[partitionCount];
70 PartitionerState state =
new PartitionerState ();
71 IEnumerator<T> src = source.GetEnumerator ();
72 bool isSimple = initialPartitionSize == 1 && partitionMultiplier == 1;
74 for (
int i = 0; i < enumerators.Length; i++) {
75 enumerators[i] = isSimple ? GetPartitionEnumeratorSimple (src, state, i == enumerators.Length - 1) : GetPartitionEnumerator (src, state);
83 IEnumerator<KeyValuePair<long, T>> GetPartitionEnumeratorSimple (IEnumerator<T> src,
84 PartitionerState state,
88 var value =
default (T);
92 lock (state.SyncLock) {
95 if (state.Finished = !src.MoveNext ())
98 index = state.Index++;
102 yield
return new KeyValuePair<long, T> (index, value);
103 }
while (!state.Finished);
110 IEnumerator<KeyValuePair<long, T>> GetPartitionEnumerator (IEnumerator<T> src, PartitionerState state)
112 int count = initialPartitionSize;
113 List<T> list =
new List<T> ();
115 while (!state.Finished) {
119 lock (state.SyncLock) {
125 for (
int i = 0; i < count; i++) {
126 if (state.Finished = !src.MoveNext ()) {
133 list.Add (src.Current);
138 for (
int i = 0; i < list.Count; i++)
139 yield
return new KeyValuePair<long, T> (ind + i, list[i]);
141 count *= partitionMultiplier;
145 class PartitionerState
147 public bool Finished;
148 public long Index = 0;
149 public readonly
object SyncLock =
new object ();