public override void WrapPartitionedStream <TLeftKey, TRightKey>( PartitionedStream <TInputOutput, TLeftKey> leftPartitionedStream, PartitionedStream <TInputOutput, TRightKey> rightPartitionedStream, IPartitionedStreamRecipient <TInputOutput> outputRecipient, bool preferStriping, QuerySettings settings) { Debug.Assert(leftPartitionedStream.PartitionCount == rightPartitionedStream.PartitionCount); if (OutputOrdered) { WrapPartitionedStreamHelper <TLeftKey, TRightKey>( ExchangeUtilities.HashRepartitionOrdered <TInputOutput, NoKeyMemoizationRequired, TLeftKey>( leftPartitionedStream, null, null, _comparer, settings.CancellationState.MergedCancellationToken), rightPartitionedStream, outputRecipient, settings.CancellationState.MergedCancellationToken); } else { WrapPartitionedStreamHelper <int, TRightKey>( ExchangeUtilities.HashRepartition <TInputOutput, NoKeyMemoizationRequired, TLeftKey>( leftPartitionedStream, null, null, _comparer, settings.CancellationState.MergedCancellationToken), rightPartitionedStream, outputRecipient, settings.CancellationState.MergedCancellationToken); } }
//--------------------------------------------------------------------------------------- // A helper method that allows WrapPartitionedStream to fix the TLeftKey type parameter. // private void WrapPartitionedStreamFixedLeftType <TLeftKey, TRightKey>( PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, TLeftKey> leftHashStream, PartitionedStream <TInputOutput, TRightKey> rightStream, IPartitionedStreamRecipient <TInputOutput> outputRecipient, int partitionCount, CancellationToken cancellationToken) { if (RightChild.OutputOrdered) { PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, TRightKey> rightHashStream = ExchangeUtilities.HashRepartitionOrdered <TInputOutput, NoKeyMemoizationRequired, TRightKey>( rightStream, null, null, _comparer, cancellationToken); WrapPartitionedStreamFixedBothTypes <TLeftKey, TRightKey>( leftHashStream, rightHashStream, outputRecipient, partitionCount, cancellationToken); } else { PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, int> rightHashStream = ExchangeUtilities.HashRepartition <TInputOutput, NoKeyMemoizationRequired, TRightKey>( rightStream, null, null, _comparer, cancellationToken); WrapPartitionedStreamFixedBothTypes <TLeftKey, int>( leftHashStream, rightHashStream, outputRecipient, partitionCount, cancellationToken); } }
//--------------------------------------------------------------------------------------- // This is a helper method. WrapPartitionedStream decides what type TLeftKey is going // to be, and then call this method with that key as a generic parameter. // private void WrapPartitionedStreamHelper <TLeftKey, TRightKey>( PartitionedStream <Pair <TLeftInput, TKey>, TLeftKey> leftHashStream, PartitionedStream <TRightInput, TRightKey> rightPartitionedStream, IPartitionedStreamRecipient <TOutput> outputRecipient, CancellationToken cancellationToken) { if (RightChild.OutputOrdered && LeftChild.OutputOrdered) { PairOutputKeyBuilder <TLeftKey, TRightKey> outputKeyBuilder = new PairOutputKeyBuilder <TLeftKey, TRightKey>(); IComparer <Pair <TLeftKey, TRightKey> > outputKeyComparer = new PairComparer <TLeftKey, TRightKey>(leftHashStream.KeyComparer, rightPartitionedStream.KeyComparer); WrapPartitionedStreamHelper <TLeftKey, TRightKey, Pair <TLeftKey, TRightKey> >(leftHashStream, ExchangeUtilities.HashRepartitionOrdered(rightPartitionedStream, _rightKeySelector, _keyComparer, null, cancellationToken), outputKeyBuilder, outputKeyComparer, outputRecipient, cancellationToken); } else { LeftKeyOutputKeyBuilder <TLeftKey, int> outputKeyBuilder = new LeftKeyOutputKeyBuilder <TLeftKey, int>(); WrapPartitionedStreamHelper <TLeftKey, int, TLeftKey>(leftHashStream, ExchangeUtilities.HashRepartition(rightPartitionedStream, _rightKeySelector, _keyComparer, null, cancellationToken), outputKeyBuilder, leftHashStream.KeyComparer, outputRecipient, cancellationToken); } }
internal override void WrapPartitionedStream <TKey>( PartitionedStream <TSource, TKey> inputStream, IPartitionedStreamRecipient <IGrouping <TGroupKey, TElement> > recipient, bool preferStriping, QuerySettings settings) { // Hash-repartition the source stream if (Child.OutputOrdered) { WrapPartitionedStreamHelperOrdered <TKey>( ExchangeUtilities.HashRepartitionOrdered <TSource, TGroupKey, TKey>( inputStream, _keySelector, _keyComparer, null, settings.CancellationState.MergedCancellationToken), recipient, settings.CancellationState.MergedCancellationToken ); } else { WrapPartitionedStreamHelper <TKey, int>( ExchangeUtilities.HashRepartition <TSource, TGroupKey, TKey>( inputStream, _keySelector, _keyComparer, null, settings.CancellationState.MergedCancellationToken), recipient, settings.CancellationState.MergedCancellationToken ); } }
//--------------------------------------------------------------------------------------- // This is a helper method. WrapPartitionedStream decides what type TLeftKey is going // to be, and then call this method with that key as a generic parameter. // private void WrapPartitionedStreamHelper <TLeftKey, TRightKey>( PartitionedStream <Pair <TLeftInput, TKey>, TLeftKey> leftHashStream, PartitionedStream <TRightInput, TRightKey> rightPartitionedStream, IPartitionedStreamRecipient <TOutput> outputRecipient, int partitionCount, CancellationToken cancellationToken) { if (RightChild.OutputOrdered) { PartitionedStream <Pair <TRightInput, TKey>, TRightKey> rePartitionedRightStream = ExchangeUtilities.HashRepartitionOrdered( rightPartitionedStream, _rightKeySelector, _keyComparer, null, cancellationToken); HashLookupBuilder <IEnumerable <TRightInput>, Pair <bool, TRightKey>, TKey>[] rightLookupBuilders = new HashLookupBuilder <IEnumerable <TRightInput>, Pair <bool, TRightKey>, TKey> [partitionCount]; for (int i = 0; i < partitionCount; i++) { rightLookupBuilders[i] = new OrderedGroupJoinHashLookupBuilder <TRightInput, TRightKey, TKey>( rePartitionedRightStream[i], _keyComparer, rePartitionedRightStream.KeyComparer); } WrapPartitionedStreamHelper <TLeftKey, Pair <bool, TRightKey> >(leftHashStream, rightLookupBuilders, CreateComparer(rightPartitionedStream.KeyComparer), outputRecipient, partitionCount, cancellationToken); } else { PartitionedStream <Pair <TRightInput, TKey>, int> rePartitionedRightStream = ExchangeUtilities.HashRepartition( rightPartitionedStream, _rightKeySelector, _keyComparer, null, cancellationToken); HashLookupBuilder <IEnumerable <TRightInput>, int, TKey>[] rightLookupBuilders = new HashLookupBuilder <IEnumerable <TRightInput>, int, TKey> [partitionCount]; for (int i = 0; i < partitionCount; i++) { rightLookupBuilders[i] = new GroupJoinHashLookupBuilder <TRightInput, int, TKey>( rePartitionedRightStream[i], _keyComparer); } WrapPartitionedStreamHelper <TLeftKey, int>(leftHashStream, rightLookupBuilders, null, outputRecipient, partitionCount, cancellationToken); } }
public override void WrapPartitionedStream <TLeftKey, TRightKey>(PartitionedStream <TInputOutput, TLeftKey> leftStream, PartitionedStream <TInputOutput, TRightKey> rightStream, IPartitionedStreamRecipient <TInputOutput> outputRecipient, bool preferStriping, QuerySettings settings) { int partitionCount = leftStream.PartitionCount; if (base.LeftChild.OutputOrdered) { PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, TLeftKey> leftHashStream = ExchangeUtilities.HashRepartitionOrdered <TInputOutput, NoKeyMemoizationRequired, TLeftKey>(leftStream, null, null, this.m_comparer, settings.CancellationState.MergedCancellationToken); this.WrapPartitionedStreamFixedLeftType <TLeftKey, TRightKey>(leftHashStream, rightStream, outputRecipient, partitionCount, settings.CancellationState.MergedCancellationToken); } else { PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, int> stream2 = ExchangeUtilities.HashRepartition <TInputOutput, NoKeyMemoizationRequired, TLeftKey>(leftStream, null, null, this.m_comparer, settings.CancellationState.MergedCancellationToken); this.WrapPartitionedStreamFixedLeftType <int, TRightKey>(stream2, rightStream, outputRecipient, partitionCount, settings.CancellationState.MergedCancellationToken); } }
private void WrapPartitionedStreamHelper <TLeftKey, TRightKey>(PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, TLeftKey> leftHashStream, PartitionedStream <TInputOutput, TRightKey> rightPartitionedStream, IPartitionedStreamRecipient <TInputOutput> outputRecipient, CancellationToken cancellationToken) { int partitionCount = leftHashStream.PartitionCount; PartitionedStream <Pair <TInputOutput, NoKeyMemoizationRequired>, int> stream = ExchangeUtilities.HashRepartition <TInputOutput, NoKeyMemoizationRequired, TRightKey>(rightPartitionedStream, null, null, this.m_comparer, cancellationToken); PartitionedStream <TInputOutput, TLeftKey> partitionedStream = new PartitionedStream <TInputOutput, TLeftKey>(partitionCount, leftHashStream.KeyComparer, OrdinalIndexState.Shuffled); for (int i = 0; i < partitionCount; i++) { if (base.OutputOrdered) { partitionedStream[i] = new OrderedExceptQueryOperatorEnumerator <TInputOutput, TLeftKey>(leftHashStream[i], stream[i], this.m_comparer, leftHashStream.KeyComparer, cancellationToken); } else { partitionedStream[i] = (QueryOperatorEnumerator <TInputOutput, TLeftKey>) new ExceptQueryOperatorEnumerator <TInputOutput, TLeftKey>(leftHashStream[i], stream[i], this.m_comparer, cancellationToken); } } outputRecipient.Receive <TLeftKey>(partitionedStream); }