public bool TryMergeWith(MapReduceJob next, out MapReduceJob combined) { // we can merge any two jobs with the first having phases i .. j and the second having phases j .. k if (this.Phases.Max() <= next.Phases.Min()) { combined = this.Merge( next, mapExpression: Merge(this.MapExpression, next.MapExpression), combineExpression: Merge(this.CombineExpression, next.CombineExpression), reduceExpression: Merge(this.ReduceExpression, next.ReduceExpression) ); return true; } // we can also push map-only jobs back onto the output of reduce jobs if (this.Phases.Contains(Phase.Reduce) && next.Phases.SequenceEqual(new[] { Phase.Map })) { combined = this.Merge( next, mapExpression: this.MapExpression, combineExpression: this.CombineExpression, reduceExpression: Merge(this.ReduceExpression, next.MapExpression) ); return true; } combined = null; return false; }
private MapReduceJob Merge(MapReduceJob next, LambdaExpression mapExpression, LambdaExpression combineExpression, LambdaExpression reduceExpression) { var mergedJob = new MapReduceJob( this.OutputParameterExpression.Name + "=>" + next.OutputParameterExpression.Name, mapExpression: mapExpression, combineExpression: combineExpression, reduceExpression: reduceExpression ); return mergedJob; }