/// <summary> /// Map + single-input Reduce /// </summary> internal static StreamProperties <TKey, TOutput> MapReduce <TKey, TMapInputLeft, TMapInputRight, TReduceInput, TReduceKey, TBind, TOutput>( this StreamProperties <TKey, TMapInputLeft> leftStream, StreamProperties <TKey, TMapInputRight> rightStream, Func <IStreamable <TKey, TMapInputLeft>, IStreamable <TKey, TMapInputRight>, IStreamable <TKey, TReduceInput> > mapper, Expression <Func <TReduceInput, TReduceKey> > keySelector, Func <IStreamable <CompoundGroupKey <TKey, TReduceKey>, TReduceInput>, IStreamable <CompoundGroupKey <TKey, TReduceKey>, TBind> > reducer, Expression <Func <TReduceKey, TBind, TOutput> > resultSelector) { bool mc = leftStream.IsMulticore; var map = leftStream.ToMulticore(true).Derive(a => mapper(a, null)); if (reducer != null) { // We need to test the reducer function to see what it does to properties. var group = map.GroupNested(keySelector); if (group.CanSpray(keySelector)) { var reduce = group.Derive(reducer).Ungroup(resultSelector); if (Config.MapArity > 1) { reduce = reduce.Union(reduce); } var returnValue = reduce.ToMulticore(mc); return(returnValue); } else { if (Config.MapArity > 1) { group = group.Union(group); } var reduce = group.Derive(reducer).Ungroup(resultSelector); if (Config.ReduceArity > 1) { reduce = reduce.Union(reduce); } var returnValue = reduce.ToMulticore(mc); return(returnValue); } } else { var result = leftStream.Derive(a => mapper(a, null)) as StreamProperties <TKey, TOutput>; if (Config.MapArity > 1) { result = result.Union(result); } return(result.ToMulticore(mc)); } }
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); } }