/* Create a streamable for a 2-input reducer, with two 2-input mappers */ public IStreamable <TMapKey, TOutput> CreateStreamable <TMapInputLeft2, TMapInputRight2, TReduceInput2, TBind, TOutput>( IMapDefinition <TMapKey, TMapInputLeft2, TMapInputRight2, TReduceKey, TReduceInput2> imapDefinitionRight, Func <IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TReduceInput>, IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TReduceInput2>, IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TBind> > reducer, Expression <Func <GroupSelectorInput <TReduceKey>, TBind, TOutput> > resultSelector, OperationalHint reduceOptions) { Contract.Assume(sourceLeft != null); var mapDefinitionRight = (MapDefinition <TMapKey, TMapInputLeft2, TMapInputRight2, TReduceKey, TReduceInput2>)imapDefinitionRight; var sourceL1 = sourceLeft; var sourceR1 = sourceRight; var sourceL2 = mapDefinitionRight.sourceLeft; var sourceR2 = mapDefinitionRight.sourceRight; Expression <Func <TReduceKey, TBind, TOutput> > resultSelector2 = (k, b) => CallInliner.Call(resultSelector, new GroupSelectorInput <TReduceKey>(k), b); var inlinedResultSelector = resultSelector2.InlineCalls(); return(new Map2ReduceStreamable <TMapKey, TMapInputLeft, TMapInputRight, TMapInputLeft2, TMapInputRight2, TReduceKey, TReduceInput, TReduceInput2, TBind, TOutput>( sourceL1, sourceR1, mapper, keySelector, sourceL2, sourceR2, mapDefinitionRight.mapper, mapDefinitionRight.keySelector, reducer, inlinedResultSelector, leftAsymmetric, mapDefinitionRight.leftAsymmetric, reduceOptions)); }
internal Map2ReduceStreamable( IStreamable <TMapKey, TMapInputLeft1> sourceLeft1, IStreamable <TMapKey, TMapInputRight1> sourceRight1, Func <IStreamable <TMapKey, TMapInputLeft1>, IStreamable <TMapKey, TMapInputRight1>, IStreamable <TMapKey, TReduceInput1> > mapper1, Expression <Func <TReduceInput1, TReduceKey> > keySelector1, IStreamable <TMapKey, TMapInputLeft2> sourceLeft2, IStreamable <TMapKey, TMapInputRight2> sourceRight2, Func <IStreamable <TMapKey, TMapInputLeft2>, IStreamable <TMapKey, TMapInputRight2>, IStreamable <TMapKey, TReduceInput2> > mapper2, Expression <Func <TReduceInput2, TReduceKey> > keySelector2, Func <IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TReduceInput1>, IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TReduceInput2>, IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TBind> > reducer, Expression <Func <TReduceKey, TBind, TOutput> > resultSelector, bool leftAsymmetric1, bool leftAsymmetric2, OperationalHint reduceOptions) : base( sourceLeft1.Properties.Map2Reduce( sourceRight1?.Properties, sourceLeft2?.Properties, sourceRight2?.Properties, mapper1, mapper2, reducer, keySelector1, keySelector2, resultSelector, reduceOptions)) { Contract.Requires(sourceLeft1 != null); Contract.Requires(sourceLeft2 != null); Contract.Requires(reducer != null); this.sourceLeft1 = sourceLeft1; this.sourceLeft2 = sourceLeft2; this.sourceRight1 = sourceRight1; this.sourceRight2 = sourceRight2; this.mapper1 = mapper1; this.mapper2 = mapper2; this.keySelector1 = keySelector1; this.keySelector2 = keySelector2; this.reducer = reducer; this.resultSelector = resultSelector; this.leftAsymmetric1 = leftAsymmetric1; this.leftAsymmetric2 = leftAsymmetric2; this.reduceOptions = reduceOptions; if (this.sourceLeft1.Properties.CanSpray(this.sourceLeft2.Properties, this.keySelector1, this.keySelector2) && this.sourceLeft1.Properties.Derive(a => this.mapper1(a, null)).CanSpray( this.sourceLeft2.Properties.Derive(a => this.mapper2(a, null)), this.keySelector1, this.keySelector2)) { this.reduceInMap = true; this.sprayComparer1 = this.sourceLeft1.Properties.GetSprayComparerExpression(this.keySelector1); } }
internal Map2ReduceStreamable( IStreamable <TMapKey, TMapInputLeft1> sourceLeft1, IStreamable <TMapKey, TMapInputRight1> sourceRight1, Func <IStreamable <TMapKey, TMapInputLeft1>, IStreamable <TMapKey, TMapInputRight1>, IStreamable <TMapKey, TReduceInput1> > mapper1, Expression <Func <TReduceInput1, TReduceKey> > keySelector1, IStreamable <TMapKey, TMapInputLeft2> sourceLeft2, IStreamable <TMapKey, TMapInputRight2> sourceRight2, Func <IStreamable <TMapKey, TMapInputLeft2>, IStreamable <TMapKey, TMapInputRight2>, IStreamable <TMapKey, TReduceInput2> > mapper2, Expression <Func <TReduceInput2, TReduceKey> > keySelector2, IEqualityComparerExpression <TReduceKey> keyComparer, Func <IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TReduceInput1>, IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TReduceInput2>, IStreamable <CompoundGroupKey <TMapKey, TReduceKey>, TBind> > reducer, Expression <Func <TReduceKey, TBind, TOutput> > resultSelector, bool leftAsymmetric1, bool leftAsymmetric2, OperationalHint reduceOptions) : base( sourceLeft1.Properties.Map2Reduce( sourceRight1?.Properties, sourceLeft2?.Properties, sourceRight2?.Properties, mapper1, mapper2, reducer, keySelector1, keySelector2, resultSelector, reduceOptions)) { Contract.Requires(sourceLeft1 != null); Contract.Requires(sourceLeft2 != null); Contract.Requires(reducer != null); this.sourceLeft1 = sourceLeft1; this.sourceLeft2 = sourceLeft2; this.sourceRight1 = sourceRight1; this.sourceRight2 = sourceRight2; this.mapper1 = mapper1; this.mapper2 = mapper2; this.keySelector1 = keySelector1; this.keySelector2 = keySelector2; this.keyComparer = keyComparer; this.reducer = reducer; this.resultSelector = resultSelector; this.leftAsymmetric1 = leftAsymmetric1; this.leftAsymmetric2 = leftAsymmetric2; this.reduceOptions = reduceOptions; ProcessProperties(); }
Map2Reduce <TMapInputLeft1, TMapInputRight1, TMapInputLeft2, TMapInputRight2, TReduceKey, TReduceInput1, TReduceInput2, TBind, TOutput>( this StreamProperties <Empty, TMapInputLeft1> leftStream1, StreamProperties <Empty, TMapInputRight1> rightStream1, StreamProperties <Empty, TMapInputLeft2> leftStream2, StreamProperties <Empty, TMapInputRight2> rightStream2, Func <IStreamable <Empty, TMapInputLeft1>, IStreamable <Empty, TMapInputRight1>, IStreamable <Empty, TReduceInput1> > mapper1, Func <IStreamable <Empty, TMapInputLeft2>, IStreamable <Empty, TMapInputRight2>, IStreamable <Empty, TReduceInput2> > mapper2, Func <IStreamable <TReduceKey, TReduceInput1>, IStreamable <TReduceKey, TReduceInput2>, IStreamable <TReduceKey, TBind> > reducer, Expression <Func <TReduceInput1, TReduceKey> > keySelector1, Expression <Func <TReduceInput2, TReduceKey> > keySelector2, Expression <Func <TReduceKey, TBind, TOutput> > resultSelector, OperationalHint reduceOptions) { var map1 = leftStream1.Derive(a => mapper1(a, null)); var map2 = leftStream2.Derive(a => mapper2(a, null)); var group1 = map1.Group(keySelector1); var group2 = map2.Group(keySelector2); if (leftStream1.CanSpray(leftStream2, keySelector1, keySelector2) && group1.CanSpray(group2, keySelector1, keySelector2)) { var reduce = group1.Derive(group2, reducer).Ungroup(resultSelector); if (Config.MapArity > 1) { reduce = reduce.Union(reduce); } return(reduce); } else { if (Config.MapArity > 1) { group1 = group1.Union(group1); group2 = group2.Union(group2); } var reduce = group1.Derive(group2, reducer).Ungroup(resultSelector); if (Config.ReduceArity > 1) { reduce = reduce.Union(reduce); } return(reduce); } }