internal override Expression Visit(Expression expr) { if (expr == null) { return(expr); } if (HpcLinqExpression.IsConstant(expr)) { object val = ExpressionSimplifier.Evaluate(expr); if (val is IQueryable) { QueryNodeInfo nodeInfo; if (this.m_referencedQueryMap.TryGetValue(((IQueryable)val).Expression, out nodeInfo)) { string name = "side__" + this.m_idx; this.m_idx++; this.m_referencedQueries.Add(new Pair <string, DryadQueryNode>(name, nodeInfo.queryNode)); return(Expression.Parameter(expr.Type, name)); } throw new DryadLinqException(HpcLinqErrorCode.UnhandledQuery, String.Format(SR.UnhandledQuery, HpcLinqExpression.Summarize(expr))); } return(expr); } return(base.Visit(expr)); }
internal static Exception Create(int errorCode, string msg, Expression expr) { StringBuilder sb = new StringBuilder(); sb.Append(msg); sb.Append(" Expression : "); sb.AppendLine(HpcLinqExpression.Summarize(expr, 1)); return(new DryadLinqException(errorCode, sb.ToString())); }
internal override PartitionInfo Rewrite(LambdaExpression resultSel, ParameterExpression param) { ParameterExpression a = this.m_keySelector.Parameters[0]; Substitution pSubst = Substitution.Empty.Cons(a, param); LambdaExpression newKeySel = HpcLinqExpression.Rewrite(this.m_keySelector, resultSel, pSubst); if (newKeySel == null) { return(new RandomPartition(this.m_count)); } return(this.Create(newKeySel)); }
internal override Expression Visit(Expression expr) { if (expr == null) { return(expr); } if (HpcLinqExpression.IsConstant(expr)) { object val = ExpressionSimplifier.Evaluate(expr); if (val is IQueryable) { this.m_querySet.Add(((IQueryable)val).Expression); } return(expr); } return(base.Visit(expr)); }
//This is the IQueryProvider.Execute() method used for execution when a single value is produced (rather than an enumerable) public override TResult Execute <TResult>(Expression expression) { MethodCallExpression callExpr = expression as MethodCallExpression; if (callExpr == null) { throw new ArgumentException(String.Format(SR.ExpressionMustBeMethodCall, HpcLinqExpression.Summarize(expression)), "expression"); } string methodName = callExpr.Method.Name; if (methodName == "FirstOrDefault" || methodName == "SingleOrDefault" || methodName == "LastOrDefault") { Type qType = typeof(DryadLinqQuery <>).MakeGenericType(typeof(AggregateValue <>).MakeGenericType(expression.Type)); AggregateValue <TResult> res = ((IEnumerable <AggregateValue <TResult> >) Activator.CreateInstance( qType, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this, expression }, CultureInfo.CurrentCulture )).Single(); if (res.Count == 0) { return(default(TResult)); } return(res.Value); } else { Type qType = typeof(DryadLinqQuery <>).MakeGenericType(expression.Type); return(((IEnumerable <TResult>)Activator.CreateInstance( qType, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this, expression }, CultureInfo.CurrentCulture )).Single()); } }
private static DecompositionInfo GetDecompositionInfo(ParameterExpression groupParam, MethodCallExpression mcExpr, HpcLinqCodeGen codeGen) { if (mcExpr.Arguments.Count == 0 || mcExpr.Arguments[0] != groupParam) { return(null); } for (int i = 1; i < mcExpr.Arguments.Count; i++) { if (HpcLinqExpression.Contains(groupParam, mcExpr.Arguments[i])) { return(null); } } ExpressionSimplifier <object> evaluator = new ExpressionSimplifier <object>(); Type[] paramTypeArgs = groupParam.Type.GetGenericArguments(); Type sourceElemType = paramTypeArgs[paramTypeArgs.Length - 1]; Type resultType = mcExpr.Type; Type decomposerType = null; DecomposableAttribute decomposableAttrib = AttributeSystem.GetDecomposableAttrib(mcExpr); if (decomposableAttrib != null) { decomposerType = decomposableAttrib.DecompositionType; } else { MethodInfo mInfo = mcExpr.Method; if (mInfo.DeclaringType == typeof(System.Linq.Enumerable) || mInfo.DeclaringType == typeof(System.Linq.Queryable)) { // For built-in decomposable operators. switch (mInfo.Name) { case "Count": case "LongCount": { Type outputType; Expression body; if (mInfo.Name == "Count") { outputType = typeof(Int32); body = Expression.Constant(1, outputType); } else { outputType = typeof(Int64); body = Expression.Constant((long)1, outputType); } ParameterExpression param1 = Expression.Parameter(outputType, "a"); ParameterExpression param2 = Expression.Parameter(sourceElemType, "e"); LambdaExpression seedExpr = Expression.Lambda(body, param2); body = Expression.AddChecked(param1, body); LambdaExpression accumulateExpr = Expression.Lambda(body, param1, param2); param2 = Expression.Parameter(outputType, "b"); body = Expression.AddChecked(param1, param2); LambdaExpression recursiveAccumulateExpr = Expression.Lambda(body, param1, param2); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "Any": { ParameterExpression param1 = Expression.Parameter(typeof(bool), "a"); ParameterExpression param2; Expression body; if (mcExpr.Arguments.Count == 1) { param2 = Expression.Parameter(sourceElemType, "e"); body = Expression.Constant(true, typeof(bool)); } else { LambdaExpression predExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[1]); param2 = predExpr.Parameters[0]; body = predExpr.Body; } LambdaExpression seedExpr = Expression.Lambda(body, param2); LambdaExpression accumulateExpr = Expression.Lambda(Expression.Or(param1, body), param1, param2); param2 = Expression.Parameter(typeof(bool), "b"); body = Expression.Or(param1, param2); LambdaExpression recursiveAccumulateExpr = Expression.Lambda(body, param1, param2); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "All": { ParameterExpression param1 = Expression.Parameter(typeof(bool), "a"); LambdaExpression predExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[1]); ParameterExpression param2 = predExpr.Parameters[0]; Expression body = predExpr.Body; LambdaExpression seedExpr = Expression.Lambda(body, param2); LambdaExpression accumulateExpr = Expression.Lambda(Expression.And(param1, body), param1, param2); param2 = Expression.Parameter(typeof(bool), "b"); body = Expression.And(param1, param2); LambdaExpression recursiveAccumulateExpr = Expression.Lambda(body, param1, param2); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "First": { ParameterExpression param1 = Expression.Parameter(sourceElemType, "a"); ParameterExpression param2 = Expression.Parameter(sourceElemType, "e"); LambdaExpression seedExpr = Expression.Lambda(param2, param2); LambdaExpression accumulateExpr = Expression.Lambda(param1, param1, param2); LambdaExpression recursiveAccumulateExpr = accumulateExpr; return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "Last": { ParameterExpression param1 = Expression.Parameter(sourceElemType, "a"); ParameterExpression param2 = Expression.Parameter(sourceElemType, "e"); LambdaExpression seedExpr = Expression.Lambda(param2, param2); LambdaExpression accumulateExpr = Expression.Lambda(param2, param1, param2); LambdaExpression recursiveAccumulateExpr = accumulateExpr; return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "Sum": { ParameterExpression param1; ParameterExpression param2; Expression arg2; if (mInfo.GetParameters().Length == 1) { param2 = Expression.Parameter(sourceElemType, "e"); arg2 = param2; } else { LambdaExpression selectExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[1]); param2 = selectExpr.Parameters[0]; arg2 = selectExpr.Body; } Expression abody, sbody; if (arg2.Type.IsGenericType) { param1 = Expression.Parameter(arg2.Type.GetGenericArguments()[0], "a"); MethodInfo accumulateInfo = typeof(HpcLinqVertex).GetMethod( "SumAccumulate", new Type[] { param1.Type, arg2.Type }); sbody = Expression.Constant(0, param1.Type); sbody = Expression.Call(accumulateInfo, sbody, arg2); abody = Expression.Call(accumulateInfo, param1, arg2); } else { param1 = Expression.Parameter(arg2.Type, "a"); sbody = arg2; abody = Expression.AddChecked(param1, arg2); } LambdaExpression seedExpr = Expression.Lambda(sbody, param2); LambdaExpression accumulateExpr = Expression.Lambda(abody, param1, param2); param2 = Expression.Parameter(param1.Type, "b"); Expression rbody = Expression.AddChecked(param1, param2); LambdaExpression recursiveAccumulateExpr = Expression.Lambda(rbody, param1, param2); Expression fbody = Expression.Convert(param1, arg2.Type); LambdaExpression finalReduceExpr = Expression.Lambda(fbody, param1); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, finalReduceExpr)); } case "Max": case "Min": { ParameterExpression param2; Expression abody; if (mInfo.GetParameters().Length == 1) { param2 = Expression.Parameter(sourceElemType, "e"); abody = param2; } else { LambdaExpression selectExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[1]); param2 = selectExpr.Parameters[0]; abody = selectExpr.Body; } ParameterExpression param1 = Expression.Parameter(abody.Type, "a"); Expression sbody = abody; MethodInfo accumulateInfo; string methodName = (mInfo.Name == "Max") ? "MaxAccumulate" : "MinAccumulate"; if (mInfo.IsGenericMethod && (mInfo.GetParameters().Length == 1)) { accumulateInfo = typeof(HpcLinqVertex).GetMethod(methodName + "Generic"); accumulateInfo = accumulateInfo.MakeGenericMethod(sourceElemType); } else { accumulateInfo = typeof(HpcLinqVertex).GetMethod( methodName, new Type[] { param1.Type, abody.Type }); } abody = Expression.Call(accumulateInfo, param1, abody); LambdaExpression seedExpr = Expression.Lambda(sbody, param2); LambdaExpression accumulateExpr = Expression.Lambda(abody, param1, param2); param2 = Expression.Parameter(param1.Type, "b"); Expression rbody = Expression.Call(accumulateInfo, param1, param2); LambdaExpression recursiveAccumulateExpr = Expression.Lambda(rbody, param1, param2); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "Aggregate": { ParameterExpression elemParam = Expression.Parameter(sourceElemType, "e"); LambdaExpression accumulateExpr; LambdaExpression seedExpr; if (mcExpr.Arguments.Count == 2) { accumulateExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[1]); seedExpr = Expression.Lambda(elemParam, elemParam); } else { accumulateExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[2]); object seedVal = evaluator.Eval(mcExpr.Arguments[1]); Expression body = Expression.Constant(seedVal, seedVal.GetType()); ParameterSubst subst = new ParameterSubst(accumulateExpr.Parameters[0], body); body = subst.Visit(accumulateExpr.Body); seedExpr = Expression.Lambda(body, accumulateExpr.Parameters[1]); } if (!HpcLinqExpression.IsAssociative(accumulateExpr)) { return(null); } LambdaExpression recursiveAccumulateExpr = HpcLinqExpression.GetAssociativeCombiner(accumulateExpr); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, null)); } case "Average": { ParameterExpression param2; Expression abody; if (mInfo.GetParameters().Length == 1) { param2 = Expression.Parameter(sourceElemType, "e"); abody = param2; } else { LambdaExpression selectExpr = HpcLinqExpression.GetLambda(mcExpr.Arguments[1]); param2 = selectExpr.Parameters[0]; abody = selectExpr.Body; } Type aggValueType = abody.Type; if (aggValueType == typeof(int) || aggValueType == typeof(int?)) { aggValueType = typeof(long); } else if (aggValueType == typeof(long?)) { aggValueType = typeof(long); } else if (aggValueType == typeof(float) || aggValueType == typeof(float?)) { aggValueType = typeof(double); } else if (aggValueType == typeof(double?)) { aggValueType = typeof(double); } else if (aggValueType == typeof(decimal?)) { aggValueType = typeof(decimal); } Type sumAndCountType = typeof(AggregateValue <>).MakeGenericType(aggValueType); ParameterExpression param1 = Expression.Parameter(sumAndCountType, "a"); MethodInfo accumulateInfo = typeof(HpcLinqVertex).GetMethod( "AverageAccumulate", new Type[] { sumAndCountType, abody.Type }); // Seed: Expression sbody = Expression.New(sumAndCountType); sbody = Expression.Call(accumulateInfo, sbody, abody); LambdaExpression seedExpr = Expression.Lambda(sbody, param2); // Accumulate: abody = Expression.Call(accumulateInfo, param1, abody); LambdaExpression accumulateExpr = Expression.Lambda(abody, param1, param2); // RecursiveAccumulate: param2 = Expression.Parameter(param1.Type, "b"); PropertyInfo valueInfo = sumAndCountType.GetProperty("Value"); PropertyInfo countInfo = sumAndCountType.GetProperty("Count"); Expression sumExpr1 = Expression.Property(param1, valueInfo); Expression countExpr1 = Expression.Property(param1, countInfo); Expression sumExpr2 = Expression.Property(param2, valueInfo); Expression countExpr2 = Expression.Property(param2, countInfo); Expression sumExpr = Expression.AddChecked(sumExpr1, sumExpr2); Expression countExpr = Expression.AddChecked(countExpr1, countExpr2); ConstructorInfo cinfo = sumAndCountType.GetConstructor(new Type[] { sumExpr.Type, countExpr.Type }); Expression rbody = Expression.New(cinfo, sumExpr, countExpr); LambdaExpression recursiveAccumulateExpr = Expression.Lambda(rbody, param1, param2); // FinalReduce: if (sumExpr1.Type == typeof(long)) { sumExpr1 = Expression.Convert(sumExpr1, typeof(double)); } Expression fbody = Expression.Divide(sumExpr1, countExpr1); fbody = Expression.Convert(fbody, resultType); if (resultType.IsGenericType) { Expression zeroExpr = Expression.Constant(0, typeof(long)); Expression condExpr = Expression.GreaterThan(countExpr1, zeroExpr); Expression nullExpr = Expression.Constant(null, resultType); fbody = Expression.Condition(condExpr, fbody, nullExpr); } LambdaExpression finalReduceExpr = Expression.Lambda(fbody, param1); return(new DecompositionInfo(mcExpr, seedExpr, accumulateExpr, recursiveAccumulateExpr, finalReduceExpr)); } case "Contains": { decomposerType = typeof(ContainsDecomposition <>).MakeGenericType(sourceElemType); break; } case "Distinct": { decomposerType = typeof(DistinctDecomposition <>).MakeGenericType(sourceElemType); break; } default: { return(null); } } } } if (decomposerType == null) { return(null); } Type implementedInterface = null; Type[] interfaces = decomposerType.GetInterfaces(); foreach (Type intf in interfaces) { if (intf.GetGenericTypeDefinition() == typeof(IDecomposable <, ,>)) { if (implementedInterface != null) { throw new DryadLinqException("Decomposition class can implement only one decomposable interface."); } implementedInterface = intf; } } if (implementedInterface == null || implementedInterface.GetGenericArguments().Length != 3) { throw new DryadLinqException("Decomposition class " + decomposerType.FullName + "must implement IDecomposable<,,>"); } // The second type of the implemented interface definition is the accumulatorType. Type accumulatorType = implementedInterface.GetGenericArguments()[1]; // Now check that all the types match up. Type decomposerInterface = typeof(IDecomposable <, ,>).MakeGenericType( sourceElemType, accumulatorType, resultType); if (!decomposerInterface.IsAssignableFrom(decomposerType)) { throw new DryadLinqException("Decomposition class must match the function that it decorates."); } if (decomposerType.ContainsGenericParameters) { if (decomposerType.GetGenericArguments().Length != 1 || !decomposerType.GetGenericArguments()[0].IsGenericParameter) { throw new DryadLinqException(decomposerType.Name + " must match the function it annotates."); } decomposerType = decomposerType.MakeGenericType(sourceElemType); } if (decomposerType.GetConstructor(Type.EmptyTypes) == null) { throw new DryadLinqException("Decomposition class must have a default constructor."); } // Add to the codegen a call of the static Initializer of decomposerType Expression[] args = new Expression[mcExpr.Arguments.Count - 1]; for (int i = 0; i < args.Length; i++) { args[i] = Expression.Convert(mcExpr.Arguments[i + 1], typeof(object)); } Expression stateExpr = Expression.NewArrayInit(typeof(object), args); string decomposerName = codeGen.AddDecompositionInitializer(decomposerType, stateExpr); ParameterExpression decomposer = Expression.Parameter(decomposerType, decomposerName); // Seed: TSource => TAccumulate MethodInfo seedInfo1 = decomposerType.GetMethod("Seed"); ParameterExpression p2 = Expression.Parameter(sourceElemType, "e"); Expression sbody1 = Expression.Call(decomposer, seedInfo1, p2); LambdaExpression seedExpr1 = Expression.Lambda(sbody1, p2); // Accumulate: (TAccumulate, TSource) => TAccumulate MethodInfo accumulateInfo1 = decomposerType.GetMethod("Accumulate"); ParameterExpression p1 = Expression.Parameter(accumulatorType, "a"); Expression abody1 = Expression.Call(decomposer, accumulateInfo1, p1, p2); LambdaExpression accumulateExpr1 = Expression.Lambda(abody1, p1, p2); // RecursiveAccumulate: (TAccumulate, TAccumulate) => TAccumulate MethodInfo recursiveAccumulateInfo1 = decomposerType.GetMethod("RecursiveAccumulate"); p2 = Expression.Parameter(accumulatorType, "e"); Expression rbody1 = Expression.Call(decomposer, recursiveAccumulateInfo1, p1, p2); LambdaExpression recursiveAccumulateExpr1 = Expression.Lambda(rbody1, p1, p2); // FinalReduce: TAccumulate => TResult MethodInfo finalReduceInfo1 = decomposerType.GetMethod("FinalReduce"); Expression fbody1 = Expression.Call(decomposer, finalReduceInfo1, p1); LambdaExpression finalReduceExpr1 = Expression.Lambda(fbody1, p1); return(new DecompositionInfo(mcExpr, seedExpr1, accumulateExpr1, recursiveAccumulateExpr1, finalReduceExpr1)); }
private static bool GetDecompositionInfoList(ParameterExpression keyParam, ParameterExpression groupParam, Expression expr, List <DecompositionInfo> infoList, HpcLinqCodeGen codeGen) { IEnumerable <Expression> argList = null; if (HpcLinqExpression.IsConstant(expr)) { return(true); } else if (expr is BinaryExpression) { BinaryExpression be = (BinaryExpression)expr; argList = new Expression[] { be.Left, be.Right }; } else if (expr is UnaryExpression) { UnaryExpression ue = (UnaryExpression)expr; return(GetDecompositionInfoList(keyParam, groupParam, ue.Operand, infoList, codeGen)); } else if (expr is ConditionalExpression) { ConditionalExpression ce = (ConditionalExpression)expr; argList = new Expression[] { ce.Test, ce.IfTrue, ce.IfFalse }; } else if (expr is MethodCallExpression) { MethodCallExpression mcExpr = (MethodCallExpression)expr; DecompositionInfo dinfo = GetDecompositionInfo(groupParam, mcExpr, codeGen); if (dinfo != null) { infoList.Add(dinfo); return(true); } if (mcExpr.Object != null) { bool isDecomposed = GetDecompositionInfoList(keyParam, groupParam, mcExpr.Object, infoList, codeGen); if (!isDecomposed) { return(false); } } argList = mcExpr.Arguments; } else if (expr is NewExpression) { argList = ((NewExpression)expr).Arguments; } else if (expr is NewArrayExpression) { argList = ((NewArrayExpression)expr).Expressions; } else if (expr is ListInitExpression) { ListInitExpression li = (ListInitExpression)expr; bool isDecomposed = GetDecompositionInfoList(keyParam, groupParam, li.NewExpression, infoList, codeGen); for (int i = 0, n = li.Initializers.Count; i < n; i++) { ElementInit ei = li.Initializers[i]; foreach (Expression arg in ei.Arguments) { isDecomposed = GetDecompositionInfoList(keyParam, groupParam, arg, infoList, codeGen); if (!isDecomposed) { return(false); } } } return(true); } else if (expr is MemberInitExpression) { MemberInitExpression mi = (MemberInitExpression)expr; bool isDecomposed = GetDecompositionInfoList(keyParam, groupParam, mi.NewExpression, infoList, codeGen); if (!isDecomposed) { return(false); } foreach (MemberBinding mb in mi.Bindings) { isDecomposed = GetDecompositionInfoList(keyParam, groupParam, mb, infoList, codeGen); if (!isDecomposed) { return(false); } } return(true); } else if (keyParam == null) { while (expr is MemberExpression) { MemberExpression me = (MemberExpression)expr; if (me.Expression == groupParam && me.Member.Name == "Key") { return(true); } expr = me.Expression; } return(false); } else { while (expr is MemberExpression) { expr = ((MemberExpression)expr).Expression; } return(expr == keyParam); } foreach (var argExpr in argList) { bool isDecomposed = GetDecompositionInfoList(keyParam, groupParam, argExpr, infoList, codeGen); if (!isDecomposed) { return(false); } } return(true); }
/// <summary> /// Explain one query node. /// </summary> /// <param name="plan">Return plan here.</param> /// <param name="n">Node to explain.</param> internal static void ExplainNode(StringBuilder plan, DryadQueryNode n) { if (n is DryadTeeNode || n is DryadOutputNode) { return; } else if (n is DryadInputNode) { plan.AppendLine("Input:"); plan.Append("\t"); n.BuildString(plan); plan.AppendLine(); return; } plan.Append(n.m_vertexEntryMethod); plan.AppendLine(":"); HashSet <DryadQueryNode> allchildren = new HashSet <DryadQueryNode>(); if (n is DryadSuperNode) { DryadSuperNode sn = n as DryadSuperNode; List <DryadQueryNode> tovisit = new List <DryadQueryNode>(); tovisit.Add(sn.RootNode); while (tovisit.Count > 0) { DryadQueryNode t = tovisit[0]; tovisit.RemoveAt(0); if (!(t is DryadSuperNode)) { allchildren.Add(t); } foreach (DryadQueryNode tc in t.Children) { if (!allchildren.Contains(tc) && sn.Contains(tc)) { tovisit.Add(tc); } } } } else { allchildren.Add(n); } foreach (DryadQueryNode nc in allchildren.Reverse()) { Expression expression = null; // expression to print List <string> additional = new List <string>(); // additional arguments to print int argsToSkip = 0; string methodname = nc.OpName; plan.Append("\t"); if (nc is DryadMergeNode) { expression = ((DryadMergeNode)nc).ComparerExpression; } else if (nc is DryadHashPartitionNode) { DryadHashPartitionNode hp = (DryadHashPartitionNode)nc; expression = hp.KeySelectExpression; additional.Add(hp.NumberOfPartitions.ToString()); } else if (nc is DryadGroupByNode) { DryadGroupByNode gb = (DryadGroupByNode)nc; expression = gb.KeySelectExpression; if (gb.ElemSelectExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.ElemSelectExpression)); } if (gb.ResSelectExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.ResSelectExpression)); } if (gb.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.ComparerExpression)); } if (gb.SeedExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.SeedExpression)); } if (gb.AccumulatorExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.AccumulatorExpression)); } } else if (nc is DryadOrderByNode) { DryadOrderByNode ob = (DryadOrderByNode)nc; expression = ob.KeySelectExpression; if (ob.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(ob.ComparerExpression)); } } else if (nc is DryadWhereNode) { expression = ((DryadWhereNode)nc).WhereExpression; } else if (nc is DryadSelectNode) { DryadSelectNode s = (DryadSelectNode)nc; expression = s.SelectExpression; if (s.ResultSelectExpression != null) { additional.Add(HpcLinqExpression.Summarize(s.ResultSelectExpression)); } } else if (nc is DryadAggregateNode) { DryadAggregateNode a = (DryadAggregateNode)nc; expression = a.FuncLambda; if (a.SeedExpression != null) { additional.Add(HpcLinqExpression.Summarize(a.SeedExpression)); } if (a.ResultLambda != null) { additional.Add(HpcLinqExpression.Summarize(a.ResultLambda)); } } else if (nc is DryadPartitionOpNode) { expression = ((DryadPartitionOpNode)nc).ControlExpression; } else if (nc is DryadJoinNode) { DryadJoinNode j = (DryadJoinNode)nc; expression = j.OuterKeySelectorExpression; additional.Add(HpcLinqExpression.Summarize(j.InnerKeySelectorExpression)); additional.Add(HpcLinqExpression.Summarize(j.ResultSelectorExpression)); if (j.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(j.ComparerExpression)); } } else if (nc is DryadDistinctNode) { expression = ((DryadDistinctNode)nc).ComparerExpression; } else if (nc is DryadContainsNode) { DryadContainsNode c = (DryadContainsNode)nc; expression = c.ValueExpression; if (c.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(c.ComparerExpression)); } } else if (nc is DryadBasicAggregateNode) { expression = ((DryadBasicAggregateNode)nc).SelectExpression; } else if (nc is DryadConcatNode) // nothing to do { } else if (nc is DryadSetOperationNode) { expression = ((DryadSetOperationNode)nc).ComparerExpression; } else if (nc is DryadRangePartitionNode) { DryadRangePartitionNode r = (DryadRangePartitionNode)nc; expression = r.CountExpression; // TODO: there's some other possible interesting info } else if (nc is DryadApplyNode) { expression = ((DryadApplyNode)nc).LambdaExpression; } else if (nc is DryadForkNode) { expression = ((DryadForkNode)nc).ForkLambda; } else if (nc is DryadTeeNode) { // nothing } else if (nc is DryadDynamicNode) { // nothing } else { expression = nc.QueryExpression; } if (expression is MethodCallExpression) { MethodCallExpression mc = (MethodCallExpression)expression; methodname = mc.Method.Name; // overwrite methodname // determine which arguments to skip #region LINQMETHODS switch (mc.Method.Name) { case "Aggregate": case "AggregateAsQuery": case "Select": case "LongSelect": case "SelectMany": case "LongSelectMany": case "OfType": case "Where": case "LongWhere": case "First": case "FirstOrDefault": case "FirstAsQuery": case "Single": case "SingleOrDefault": case "SingleAsQuery": case "Last": case "LastOrDefault": case "LastAsQuery": case "Distinct": case "Any": case "AnyAsQuery": case "All": case "AllAsQuery": case "Count": case "CountAsQuery": case "LongCount": case "LongCountAsQuery": case "Sum": case "SumAsQuery": case "Min": case "MinAsQuery": case "Max": case "MaxAsQuery": case "Average": case "AverageAsQuery": case "GroupBy": case "OrderBy": case "OrderByDescending": case "ThenBy": case "ThenByDescending": case "Take": case "TakeWhile": case "LongTakeWhile": case "Skip": case "SkipWhile": case "LongSkipWhile": case "Contains": case "ContainsAsQuery": case "Reverse": case "Merge": case "HashPartition": case "RangePartition": case "Fork": case "ForkChoose": case "AssumeHashPartition": case "AssumeRangePartition": case "AssumeOrderBy": case "ToPartitionedTableLazy": case "AddCacheEntry": case "SlidingWindow": case "SelectWithPartitionIndex": case "ApplyWithPartitionIndex": argsToSkip = 1; break; case "Join": case "GroupJoin": case "Concat": case "MultiConcat": case "Union": case "Intersect": case "Except": case "SequenceEqual": case "SequenceEqualAsQuery": case "Zip": argsToSkip = 2; break; case "Apply": case "ApplyPerPartition": if (mc.Arguments.Count < 3) { argsToSkip = 1; } else { argsToSkip = 2; } break; default: throw DryadLinqException.Create(HpcLinqErrorCode.OperatorNotSupported, String.Format(SR.OperatorNotSupported, mc.Method.Name), expression); } #endregion plan.Append(methodname); plan.Append("("); int argno = 0; foreach (var arg in mc.Arguments) { argno++; if (argno <= argsToSkip) { continue; } if (argno > argsToSkip + 1) { plan.Append(","); } plan.Append(HpcLinqExpression.Summarize(arg)); } plan.AppendLine(")"); } else { // expression is not methodcall plan.Append(methodname); plan.Append("("); if (expression != null) { plan.Append(HpcLinqExpression.Summarize(expression)); } foreach (string e in additional) { plan.Append(","); plan.Append(e); } plan.AppendLine(")"); } } }
// Return true iff EPG is modified by this method. public bool RewriteOne(int idx) { QueryNodeInfo curNode = this.m_nodeInfos[idx]; if (curNode.OperatorName == "Where" && !curNode.children[0].child.IsForked) { LambdaExpression lambda = HpcLinqExpression.GetLambda(((MethodCallExpression)curNode.queryExpression).Arguments[1]); if (lambda.Type.GetGenericArguments().Length == 2) { QueryNodeInfo child = curNode.children[0].child; string[] names = new string[] { "OrderBy", "Distinct", "RangePartition", "HashPartition" }; if (names.Contains(child.OperatorName)) { curNode.Swap(child); return(true); } if (child.OperatorName == "Concat") { curNode.Delete(); for (int i = 0; i < child.children.Count; i++) { NodeInfoEdge edge = child.children[i]; QueryNodeInfo node = curNode.Clone(); this.m_nodeInfos.Add(node); edge.Insert(node); } return(true); } } } else if ((curNode.OperatorName == "Select" || curNode.OperatorName == "SelectMany") && !curNode.children[0].child.IsForked) { LambdaExpression lambda = HpcLinqExpression.GetLambda(((MethodCallExpression)curNode.queryExpression).Arguments[1]); if (lambda.Type.GetGenericArguments().Length == 2) { QueryNodeInfo child = curNode.children[0].child; if (child.OperatorName == "Concat") { curNode.Delete(); for (int i = 0; i < child.children.Count; i++) { NodeInfoEdge edge = child.children[i]; QueryNodeInfo node = curNode.Clone(); this.m_nodeInfos.Add(node); edge.Insert(node); } return(true); } } } else if (curNode.OperatorName == "Take" && !curNode.children[0].child.IsForked) { QueryNodeInfo child = curNode.children[0].child; if (child.OperatorName == "Select") { QueryNodeInfo cchild = child.children[0].child; if (cchild.OperatorName != "GroupBy") { curNode.Swap(child); return(true); } } } else if ((curNode.OperatorName == "Contains" || curNode.OperatorName == "ContainsAsQuery" || curNode.OperatorName == "All" || curNode.OperatorName == "AllAsQuery" || curNode.OperatorName == "Any" || curNode.OperatorName == "AnyAsQuery") && !curNode.children[0].child.IsForked) { QueryNodeInfo child = curNode.children[0].child; string[] names = new string[] { "OrderBy", "Distinct", "RangePartition", "HashPartition" }; if (names.Contains(child.OperatorName)) { child.Delete(); return(true); } } return(false); }