Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Core / System / Linq / Parallel / Partitioning / PartitionedStream.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
7 //
8 // PartitionedStream.cs
9 //
10 // <OWNER>[....]</OWNER>
11 //
12 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
13
14 using System.Collections.Generic;
15 using System.Diagnostics.Contracts;
16
17 namespace System.Linq.Parallel
18 {
19     /// <summary>
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.
28     ///
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.
33     /// </summary>
34     /// <typeparam name="TElement"></typeparam>
35     /// <typeparam name="TKey"></typeparam>
36     internal class PartitionedStream<TElement, TKey>
37     {
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.
41
42         internal PartitionedStream(int partitionCount, IComparer<TKey> keyComparer, OrdinalIndexState indexState)
43         {
44             Contract.Assert(partitionCount > 0);
45             m_partitions = new QueryOperatorEnumerator<TElement, TKey>[partitionCount];
46             m_keyComparer = keyComparer;
47             m_indexState = indexState;
48         }
49
50         //---------------------------------------------------------------------------------------
51         // Retrieves or sets a partition for the given index.
52         //
53         // Assumptions:
54         //    The index falls within the legal range of the enumerator, i.e. 0 <= value < count.
55         //
56
57         internal QueryOperatorEnumerator<TElement, TKey> this[int index]
58         {
59             get
60             {
61                 Contract.Assert(m_partitions != null);
62                 Contract.Assert(0 <= index && index < m_partitions.Length, "index out of bounds");
63                 return m_partitions[index];
64             }
65             set
66             {
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;
71             }
72         }
73
74         //---------------------------------------------------------------------------------------
75         // Retrives the number of partitions.
76         //
77
78         public int PartitionCount
79         {
80             get
81             {
82                 Contract.Assert(m_partitions != null);
83                 return m_partitions.Length;
84             }
85         }
86
87         //---------------------------------------------------------------------------------------
88         // The comparer for the order keys.
89         //
90
91         internal IComparer<TKey> KeyComparer
92         {
93             get { return m_keyComparer; }
94         }
95
96         //---------------------------------------------------------------------------------------
97         // State of the order keys.
98         //
99
100         internal OrdinalIndexState OrdinalIndexState
101         {
102             get { return m_indexState; }
103         }
104     }
105 }