private void WrapPartitionedStreamIndexed(PartitionedStream <TLeftInput, int> inputStream, IPartitionedStreamRecipient <TOutput> recipient, QuerySettings settings) { PairComparer <int, int> keyComparer = new PairComparer <int, int>(inputStream.KeyComparer, Util.GetDefaultComparer <int>()); PartitionedStream <TOutput, Pair <int, int> > partitionedStream = new PartitionedStream <TOutput, Pair <int, int> >(inputStream.PartitionCount, keyComparer, this.OrdinalIndexState); for (int i = 0; i < inputStream.PartitionCount; i++) { partitionedStream[i] = new IndexedSelectManyQueryOperatorEnumerator <TLeftInput, TRightInput, TOutput>(inputStream[i], (SelectManyQueryOperator <TLeftInput, TRightInput, TOutput>) this, settings.CancellationState.MergedCancellationToken); } recipient.Receive <Pair <int, int> >(partitionedStream); }
/// <summary> /// A helper method for WrapPartitionedStream. We use the helper to reuse a block of code twice, but with /// a different order key type. (If premature merge occurred, the order key type will be "int". Otherwise, /// it will be the same type as "TLeftKey" in WrapPartitionedStream.) /// </summary> private void WrapPartitionedStreamNotIndexed <TLeftKey>( PartitionedStream <TLeftInput, TLeftKey> inputStream, IPartitionedStreamRecipient <TOutput> recipient, QuerySettings settings) { int partitionCount = inputStream.PartitionCount; var keyComparer = new PairComparer <TLeftKey, int>(inputStream.KeyComparer, Util.GetDefaultComparer <int>()); var outputStream = new PartitionedStream <TOutput, Pair <TLeftKey, int> >(partitionCount, keyComparer, OrdinalIndexState); for (int i = 0; i < partitionCount; i++) { outputStream[i] = new SelectManyQueryOperatorEnumerator <TLeftKey>(inputStream[i], this, settings.CancellationState.MergedCancellationToken); } recipient.Receive(outputStream); }
//--------------------------------------------------------------------------------------- // IOrderedEnumerable method for nesting an order by operator inside another. // IOrderedEnumerable <TInputOutput> IOrderedEnumerable <TInputOutput> .CreateOrderedEnumerable <TKey2>( Func <TInputOutput, TKey2> key2Selector, IComparer <TKey2> key2Comparer, bool descending) { key2Comparer = key2Comparer ?? Util.GetDefaultComparer <TKey2>(); if (descending) { key2Comparer = new ReverseComparer <TKey2>(key2Comparer); } IComparer <Pair <TSortKey, TKey2> > pairComparer = new PairComparer <TSortKey, TKey2>(_comparer, key2Comparer); Func <TInputOutput, Pair <TSortKey, TKey2> > pairKeySelector = (TInputOutput elem) => new Pair <TSortKey, TKey2>(_keySelector(elem), key2Selector(elem)); return(new SortQueryOperator <TInputOutput, Pair <TSortKey, TKey2> >(Child, pairKeySelector, pairComparer, false)); }
private void WrapPartitionedStreamHelper <TLeftKey, TRightKey>( PartitionedStream <Pair <TLeftInput, TKey>, TLeftKey> leftHashStream, HashLookupBuilder <IEnumerable <TRightInput>, TRightKey, TKey>[] rightLookupBuilders, IComparer <TRightKey>?rightKeyComparer, IPartitionedStreamRecipient <TOutput> outputRecipient, int partitionCount, 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, rightKeyComparer); WrapPartitionedStreamHelper <TLeftKey, TRightKey, Pair <TLeftKey, TRightKey> >(leftHashStream, rightLookupBuilders, outputKeyBuilder, outputKeyComparer, outputRecipient, partitionCount, cancellationToken); } else { LeftKeyOutputKeyBuilder <TLeftKey, TRightKey> outputKeyBuilder = new LeftKeyOutputKeyBuilder <TLeftKey, TRightKey>(); WrapPartitionedStreamHelper <TLeftKey, TRightKey, TLeftKey>(leftHashStream, rightLookupBuilders, outputKeyBuilder, leftHashStream.KeyComparer, 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); } }