Пример #1
0
        // Add a new vertex method to the Dryad vertex class
        internal CodeMemberMethod AddVertexMethod(DryadQueryNode node)
        {
            CodeMemberMethod vertexMethod = new CodeMemberMethod();
            vertexMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
            vertexMethod.ReturnType = new CodeTypeReference(typeof(int));
            vertexMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "args"));
            vertexMethod.Name = MakeUniqueName(node.NodeType.ToString());

            CodeTryCatchFinallyStatement tryBlock = new CodeTryCatchFinallyStatement();

            string startedMsg = "DryadLinqLog.Add(\"Vertex " + vertexMethod.Name +
                " started at {0}\", DateTime.Now.ToString(\"MM/dd/yyyy HH:mm:ss.fff\"))";
            vertexMethod.Statements.Add(new CodeSnippetExpression(startedMsg));

            // We need to call AddCopyResourcesMethod()
            vertexMethod.Statements.Add(new CodeSnippetExpression("CopyResources()"));

            if (StaticConfig.LaunchDebugger)
            {
                // If static config requests it, we do an unconditional Debugger.Launch() at vertex entry.
                // Currently this isn't used because StaticConfig.LaunchDebugger is hardcoded to false
                System.Console.WriteLine("Launch debugger: may block application");

                CodeExpression launchExpr = new CodeSnippetExpression("System.Diagnostics.Debugger.Launch()");
                vertexMethod.Statements.Add(new CodeExpressionStatement(launchExpr));
            }
            else
            {
                // Otherwise (the default behavior), we first make sure we emit the debug check helper static method
                // and add a call to it at vertex entry. This helper checks an environment variable to decide whether
                // to launch the debugger, wait for a manual attach or simply skip straigt into vertex code.
                EnsureDebuggerHelperMethodEmitted();
                CodeMethodInvokeExpression debuggerCheckExpr = new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(VertexClassName),
                        DebugHelperMethodName));

                vertexMethod.Statements.Add(new CodeExpressionStatement(debuggerCheckExpr));
            }

            vertexMethod.Statements.Add(MakeDryadVertexParamsDecl(node));
            vertexMethod.Statements.Add(SetDryadVertexParamField("VertexStageName", vertexMethod.Name));
            vertexMethod.Statements.Add(SetDryadVertexParamField("UseLargeBuffer", node.UseLargeWriteBuffer));
            vertexMethod.Statements.Add(SetDryadVertexParamField("KeepInputPortOrder", node.KeepInputPortOrder()));

            // Push the parallel-code settings into HpcLinqVertex
            bool multiThreading = this.m_context.Configuration.AllowConcurrentUserDelegatesInSingleProcess;
            vertexMethod.Statements.Add(SetDryadVertexParamField("MultiThreading", multiThreading));
            vertexMethod.Statements.Add(
                  new CodeAssignStatement(
                     new CodeFieldReferenceExpression(DLVTypeExpr, "s_multiThreading"),
                     new CodePrimitiveExpression(multiThreading)));

            vertexMethod.Statements.Add(MakeDryadEnvDecl(node));

            Type[] outputTypes = node.OutputTypes;
            string[] writerNames = new string[outputTypes.Length];
            for (int i = 0; i < outputTypes.Length; i++)
            {
                CodeVariableDeclarationStatement
                    writerDecl = MakeDryadWriterDecl(outputTypes[i], this.GetStaticFactoryName(outputTypes[i]));
                vertexMethod.Statements.Add(writerDecl);
                writerNames[i] = writerDecl.Name;
            }

            // Add side readers:
            node.AddSideReaders(vertexMethod);

            // Generate code based on the node type:
            switch (node.NodeType)
            {
                case QueryNodeType.Where:
                case QueryNodeType.OrderBy:
                case QueryNodeType.Distinct:
                case QueryNodeType.Skip:
                case QueryNodeType.SkipWhile:
                case QueryNodeType.Take:
                case QueryNodeType.TakeWhile:
                case QueryNodeType.Merge:
                case QueryNodeType.Select:
                case QueryNodeType.SelectMany:
                case QueryNodeType.GroupBy:
                case QueryNodeType.BasicAggregate:
                case QueryNodeType.Aggregate:
                case QueryNodeType.Contains:
                case QueryNodeType.Join:
                case QueryNodeType.GroupJoin:
                case QueryNodeType.Union:
                case QueryNodeType.Intersect:
                case QueryNodeType.Except:
                case QueryNodeType.RangePartition:
                case QueryNodeType.HashPartition:
                case QueryNodeType.Apply:
                case QueryNodeType.Fork:
                case QueryNodeType.Dynamic:
                {
                    Type[] inputTypes = node.InputTypes;
                    string[] sourceNames = new string[inputTypes.Length];
                    for (int i = 0; i < inputTypes.Length; i++)
                    {
                        CodeVariableDeclarationStatement
                            readerDecl = MakeDryadReaderDecl(inputTypes[i], this.GetStaticFactoryName(inputTypes[i]));
                        vertexMethod.Statements.Add(readerDecl);
                        sourceNames[i] = readerDecl.Name;
                    }
                    string sourceToSink = this.m_vertexCodeGen.AddVertexCode(node, vertexMethod, sourceNames, writerNames);

                    if (sourceToSink != null && (node.NodeType == QueryNodeType.Dynamic || node.Parents.Count > 0))
                    {
                        CodeExpression sinkExpr = new CodeMethodInvokeExpression(
                                                           new CodeVariableReferenceExpression(writerNames[0]),
                                                           "WriteItemSequence",
                                                           new CodeVariableReferenceExpression(sourceToSink));
                        vertexMethod.Statements.Add(sinkExpr);
                    }
                    break;
                }
                case QueryNodeType.Super:
                {
                    string sourceToSink = this.m_vertexCodeGen.AddVertexCode(node, vertexMethod, null, writerNames);
                    if (sourceToSink != null && node.Parents.Count > 0)
                    {
                        CodeExpression sinkExpr = new CodeMethodInvokeExpression(
                                                           new CodeVariableReferenceExpression(writerNames[0]),
                                                           "WriteItemSequence",
                                                           new CodeVariableReferenceExpression(sourceToSink));
                        vertexMethod.Statements.Add(sinkExpr);
                    }
                    break;
                }
                default:
                {
                    //@@TODO: this should not be reachable. could change to Assert/InvalidOpEx
                    throw new DryadLinqException(HpcLinqErrorCode.Internal,
                                               String.Format(SR.AddVertexNotHandled, node.NodeType));
                }
            }

            string completedMsg = "DryadLinqLog.Add(\"Vertex " + vertexMethod.Name +
                " completed at {0}\", DateTime.Now.ToString(\"MM/dd/yyyy HH:mm:ss.fff\"))";
            vertexMethod.Statements.Add(new CodeSnippetExpression(completedMsg));

            // add a catch block
            CodeCatchClause catchBlock = new CodeCatchClause("e");
            CodeTypeReferenceExpression errorReportClass = new CodeTypeReferenceExpression("HpcLinqVertexEnv");
            CodeMethodReferenceExpression
                errorReportMethod = new CodeMethodReferenceExpression(errorReportClass, "ReportVertexError");
            CodeVariableReferenceExpression exRef = new CodeVariableReferenceExpression(catchBlock.LocalName);
            catchBlock.Statements.Add(new CodeMethodInvokeExpression(errorReportMethod, exRef));
            tryBlock.CatchClauses.Add(catchBlock);

            // wrap the entire vertex method in a try/catch block
            tryBlock.TryStatements.AddRange(vertexMethod.Statements);
            vertexMethod.Statements.Clear();
            vertexMethod.Statements.Add(tryBlock);

            // Always add "return 0", to make CLR hosting happy...
            vertexMethod.Statements.Add(new CodeMethodReturnStatement(ZeroExpr));

            this.m_dryadVertexClass.Members.Add(vertexMethod);
            return vertexMethod;
        }
Пример #2
0
 private bool KeepInputPortOrder(DryadQueryNode curNode)
 {
     if (curNode.SuperNode == this)
     {
         if (curNode.KeepInputPortOrder())
         {
             return true;
         }
         foreach (DryadQueryNode child in curNode.Children)
         {
             if (this.KeepInputPortOrder(child))
             {
                 return true;
             }
         }
     }
     return false;
 }