3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
8 // PartitionedStream.cs
10 // <OWNER>[....]</OWNER>
12 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
14 using System.Collections.Generic;
15 using System.Diagnostics.Contracts;
17 namespace System.Linq.Parallel
20 /// A partitioned stream just partitions some data source using an extensible
21 /// partitioning algorithm and exposes a set of N enumerators that are consumed by
22 /// their ordinal index [0..N). It is used to build up a set of streaming computations.
23 /// At instantiation time, the actual data source to be partitioned is supplied; and
24 /// then the caller will layer on top additional enumerators to represent phases in the
25 /// computation. Eventually, a merge can then schedule enumeration of all of the
26 /// individual partitions in parallel by obtaining references to the individual
27 /// partition streams.
29 /// This type has a set of subclasses which implement different partitioning algorithms,
30 /// allowing us to easily plug in different partitioning techniques as needed. The type
31 /// supports wrapping IEnumerables and IEnumerators alike, with some preference for the
32 /// former as many partitioning algorithms are more intelligent for certain data types.
34 /// <typeparam name="TElement"></typeparam>
35 /// <typeparam name="TKey"></typeparam>
36 internal class PartitionedStream<TElement, TKey>
38 protected QueryOperatorEnumerator<TElement, TKey>[] m_partitions; // Partitions exposed by this object.
39 private readonly IComparer<TKey> m_keyComparer; // Comparer for order keys.
40 private readonly OrdinalIndexState m_indexState; // State of the order keys.
42 internal PartitionedStream(int partitionCount, IComparer<TKey> keyComparer, OrdinalIndexState indexState)
44 Contract.Assert(partitionCount > 0);
45 m_partitions = new QueryOperatorEnumerator<TElement, TKey>[partitionCount];
46 m_keyComparer = keyComparer;
47 m_indexState = indexState;
50 //---------------------------------------------------------------------------------------
51 // Retrieves or sets a partition for the given index.
54 // The index falls within the legal range of the enumerator, i.e. 0 <= value < count.
57 internal QueryOperatorEnumerator<TElement, TKey> this[int index]
61 Contract.Assert(m_partitions != null);
62 Contract.Assert(0 <= index && index < m_partitions.Length, "index out of bounds");
63 return m_partitions[index];
67 Contract.Assert(m_partitions != null);
68 Contract.Assert(value != null);
69 Contract.Assert(0 <= index && index < m_partitions.Length, "index out of bounds");
70 m_partitions[index] = value;
74 //---------------------------------------------------------------------------------------
75 // Retrives the number of partitions.
78 public int PartitionCount
82 Contract.Assert(m_partitions != null);
83 return m_partitions.Length;
87 //---------------------------------------------------------------------------------------
88 // The comparer for the order keys.
91 internal IComparer<TKey> KeyComparer
93 get { return m_keyComparer; }
96 //---------------------------------------------------------------------------------------
97 // State of the order keys.
100 internal OrdinalIndexState OrdinalIndexState
102 get { return m_indexState; }