Преглед изворни кода

HPCC-8316 Clean up the code to remove lots of workflow loops

Instead of applying each stage in turn to all the workflow items,
switch to walking through each workflow item and applying each stage
in turn.  It removes lots of loops.  It could also provide
scope for executing in parallel (although the benefits are likely to
be marginal for most queries).

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday пре 12 година
родитељ
комит
6550f10cba
4 измењених фајлова са 199 додато и 240 уклоњено
  1. 5 4
      ecl/hqlcpp/hqlcpp.ipp
  2. 6 13
      ecl/hqlcpp/hqlhtcpp.cpp
  3. 184 217
      ecl/hqlcpp/hqlttcpp.cpp
  4. 4 6
      ecl/hqlcpp/hqlttcpp.ipp

+ 5 - 4
ecl/hqlcpp/hqlcpp.ipp

@@ -1793,19 +1793,18 @@ protected:
     void doReportWarning(IHqlExpression * location, unsigned id, const char * msg);
 
     void optimizePersists(HqlExprArray & exprs);
-    void optimizePersists(WorkflowArray & workflow);
     void allocateSequenceNumbers(HqlExprArray & exprs);
-    void convertLogicalToActivities(WorkflowArray & array);
+    void convertLogicalToActivities(WorkflowItem & curWorkflow);
     void flattenDatasets(WorkflowArray & array);
 
-    void spotGlobalCSE(WorkflowArray & array);
+    void spotGlobalCSE(WorkflowItem & curWorkflow);
     IHqlExpression * spotGlobalCSE(IHqlExpression * _expr);
     void spotGlobalCSE(HqlExprArray & exprs);
     IHqlExpression * extractGlobalCSE(IHqlExpression * expr);
     void processCppBodyDirectives(IHqlExpression * expr);
 
 
-    void markThorBoundaries(WorkflowArray & array);
+    void markThorBoundaries(WorkflowItem & curWorkflow);
     bool transformGraphForGeneration(HqlQueryContext & query, WorkflowArray & exprs);
     void processEmbeddedLibraries(HqlExprArray & exprs, HqlExprArray & internalLibraries, bool isLibrary);
     void pickBestEngine(WorkflowArray & array);
@@ -1856,10 +1855,12 @@ public:
 public:
     void traceExpression(const char * title, IHqlExpression * expr, unsigned level=500);
     void traceExpressions(const char * title, HqlExprArray & exprs, unsigned level=500);
+    void traceExpressions(const char * title, WorkflowItem & workflow, unsigned level=500) { traceExpressions(title, workflow.queryExprs(), level); };
     void traceExpressions(const char * title, WorkflowArray & exprs);
 
     void checkNormalized(IHqlExpression * expr);
     void checkNormalized(WorkflowArray & array);
+    void checkNormalized(WorkflowItem & workflow) { checkNormalized(workflow.queryExprs()); }
     void checkNormalized(HqlExprArray & exprs);
     void checkNormalized(BuildCtx & ctx, IHqlExpression * expr);
 

+ 6 - 13
ecl/hqlcpp/hqlhtcpp.cpp

@@ -17180,13 +17180,13 @@ void HqlCppTranslator::buildWorkflow(WorkflowArray & workflow)
     BuildCtx switchctx(performctx);
     IHqlStmt * switchStmt = switchctx.addSwitch(function);
 
-    optimizePersists(workflow);
     ForEachItemIn(idx, workflow)
     {
         WorkflowItem & action = workflow.item(idx);
         HqlExprArray & exprs = action.queryExprs();
         unsigned wfid = action.queryWfid();
 
+        optimizePersists(exprs);
         bool isEmpty = exprs.ordinality() == 0;
         if (exprs.ordinality() == 1 && (exprs.item(0).getOperator() == no_workflow_action))
             isEmpty = true;
@@ -17921,12 +17921,6 @@ void HqlCppTranslator::optimizePersists(HqlExprArray & exprs)
     createCompoundEnsure(exprs, 0, max-1);
 }
 
-void HqlCppTranslator::optimizePersists(WorkflowArray & workflow)
-{
-    ForEachItemIn(idx, workflow)
-        optimizePersists(workflow.item(idx).queryExprs());
-}
-
 IHqlExpression * HqlCppTranslator::extractGlobalCSE(IHqlExpression * expr)
 {
     AutoScopeMigrateTransformer transformer(wu(), *this);
@@ -18014,13 +18008,12 @@ void HqlCppTranslator::spotGlobalCSE(HqlExprArray & exprs)
     }
 }
 
-void HqlCppTranslator::spotGlobalCSE(WorkflowArray & array)
+void HqlCppTranslator::spotGlobalCSE(WorkflowItem & curWorkflow)
 {
     if (!insideLibrary() && options.globalAutoHoist)
     {
         unsigned startTime = msTick();
-        ForEachItemIn(idx, array)
-            spotGlobalCSE(array.item(idx).queryExprs());
+        spotGlobalCSE(curWorkflow.queryExprs());
         DEBUG_TIMER("EclServer: tree transform: spot global cse", msTick()-startTime);
     }
 }
@@ -18300,14 +18293,14 @@ void HqlCppTranslator::pickBestEngine(HqlExprArray & exprs)
 }
 
 
-void HqlCppTranslator::pickBestEngine(WorkflowArray & array)
+void HqlCppTranslator::pickBestEngine(WorkflowArray & workflow)
 {
     if (targetThor())
     {
         unsigned time = msTick();
-        ForEachItemIn(idx2, array)
+        ForEachItemIn(idx2, workflow)
         {
-            HqlExprArray & exprs = array.item(idx2).queryExprs();
+            HqlExprArray & exprs = workflow.item(idx2).queryExprs();
             ForEachItemIn(idx, exprs)
             {
                 if (needsRealThor(&exprs.item(idx)))

+ 184 - 217
ecl/hqlcpp/hqlttcpp.cpp

@@ -981,18 +981,14 @@ void HqlThorBoundaryTransformer::transformRoot(const HqlExprArray & in, HqlExprA
 }
 
 
-void HqlCppTranslator::markThorBoundaries(WorkflowArray & array)
+void HqlCppTranslator::markThorBoundaries(WorkflowItem & curWorkflow)
 {
-    HqlThorBoundaryTransformer thorTransformer(wu(), targetRoxie(), options.maxRootMaybeThorActions, options.resourceConditionalActions, options.resourceSequential);
-    ForEachItemIn(idx, array)
-    {
-        WorkflowItem & cur = array.item(idx);
-        HqlExprArray & exprs = cur.queryExprs();
-        HqlExprArray bounded;
+    HqlExprArray & exprs = curWorkflow.queryExprs();
+    HqlExprArray bounded;
 
-        thorTransformer.transformRoot(exprs, bounded);
-        replaceArray(exprs, bounded);
-    }
+    HqlThorBoundaryTransformer thorTransformer(wu(), targetRoxie(), options.maxRootMaybeThorActions, options.resourceConditionalActions, options.resourceSequential);
+    thorTransformer.transformRoot(exprs, bounded);
+    replaceArray(exprs, bounded);
 }
 
 //---------------------------------------------------------------------------
@@ -1188,27 +1184,20 @@ IHqlExpression * ThorScalarTransformer::createTransformed(IHqlExpression * expr)
 
 */
 
-static void normalizeResultFormat(WorkflowArray & workflow, const HqlCppOptions & options)
+static void normalizeResultFormat(WorkflowItem & curWorkflow, const HqlCppOptions & options)
 {
-    ForEachItemIn(idx, workflow)
-    {
-        WorkflowItem & cur = workflow.item(idx);
-        HqlExprArray & exprs = cur.queryExprs();
+    //Until thor has a way of calling a graph and returning a result we need to call this transformer, so that
+    //scalars that need to be evaluated in thor are correctly hoisted.
+    ThorScalarTransformer transformer(options);
+    HqlExprArray & exprs = curWorkflow.queryExprs();
 
-        //Until thor has a way of calling a graph and returning a result we need to call this transformer, so that
-        //scalars that need to be evaluated in thor are correctly hoisted.
-        {
-            ThorScalarTransformer transformer(options);
-
-            transformer.analyseArray(exprs, 0);
+    transformer.analyseArray(exprs, 0);
 
-            if (transformer.needToTransform())
-            {
-                HqlExprArray transformed;
-                transformer.transformRoot(exprs, transformed);
-                replaceArray(exprs, transformed);
-            }
-        }
+    if (transformer.needToTransform())
+    {
+        HqlExprArray transformed;
+        transformer.transformRoot(exprs, transformed);
+        replaceArray(exprs, transformed);
     }
 }
 
@@ -3470,25 +3459,23 @@ IHqlExpression * ThorHqlTransformer::normalizeTableGrouping(IHqlExpression * exp
 }
 
 
-void HqlCppTranslator::convertLogicalToActivities(WorkflowArray & workflow)
+void HqlCppTranslator::convertLogicalToActivities(WorkflowItem & curWorkflow)
 {
     {
         unsigned time = msTick();
         ThorHqlTransformer transformer(*this, targetClusterType, wu());
-        ForEachItemIn(idx, workflow)
-        {
-            HqlExprArray & exprs = workflow.item(idx).queryExprs();
-            HqlExprArray transformed;
 
-            transformer.transformRoot(exprs, transformed);
+        HqlExprArray & exprs = curWorkflow.queryExprs();
+        HqlExprArray transformed;
 
-            replaceArray(exprs, transformed);
-        }
+        transformer.transformRoot(exprs, transformed);
+
+        replaceArray(exprs, transformed);
         DEBUG_TIMER("EclServer: tree transform: convert logical", msTick()-time);
     }
 
     if (queryOptions().normalizeLocations)
-        normalizeAnnotations(*this, workflow);
+        normalizeAnnotations(*this, curWorkflow.queryExprs());
 }
 
 //------------------------------------------------------------------------
@@ -4700,13 +4687,6 @@ IHqlExpression * optimizeActivities(IHqlExpression * expr, bool optimizeCountCom
     return transformer.transformRoot(expr);
 }
 
-void optimizeActivities(WorkflowArray & array, bool optimizeCountCompare, bool optimizeNonEmpty)
-{
-    ForEachItemIn(idx, array)
-        optimizeActivities(array.item(idx).queryExprs(), optimizeCountCompare, optimizeNonEmpty);
-}
-
-
 IHqlExpression * GlobalAttributeInfo::queryAlias(IHqlExpression * value)
 {
     if (!aliasName)
@@ -6736,9 +6716,9 @@ bool moveUnconditionalEarlier(HqlExprArray & in)
 
 //------------------------------------------------------------------------
 
-void mergeThorGraphs(HqlExprArray & exprs, bool resourceConditionalActions, bool resourceSequential);
+static void mergeThorGraphs(HqlExprArray & exprs, bool resourceConditionalActions, bool resourceSequential);
 
-IHqlExpression * mergeThorGraphs(IHqlExpression * expr, bool resourceConditionalActions, bool resourceSequential)
+static IHqlExpression * mergeThorGraphs(IHqlExpression * expr, bool resourceConditionalActions, bool resourceSequential)
 {
     HqlExprArray args;
     expr->unwindList(args, no_actionlist);
@@ -6747,7 +6727,7 @@ IHqlExpression * mergeThorGraphs(IHqlExpression * expr, bool resourceConditional
 }
 
 
-void mergeThorGraphs(HqlExprArray & exprs, bool resourceConditionalActions, bool resourceSequential)
+static void mergeThorGraphs(HqlExprArray & exprs, bool resourceConditionalActions, bool resourceSequential)
 {
     HqlExprArray thorActions;
     HqlExprArray combined;
@@ -6881,13 +6861,11 @@ void mergeThorGraphs(HqlExprArray & exprs, bool resourceConditionalActions, bool
     replaceArray(exprs, combined);
 }
 
-void mergeThorGraphs(WorkflowArray & array, bool resourceConditionalActions, bool resourceSequential)
+void mergeThorGraphs(WorkflowItem & workflow, bool resourceConditionalActions, bool resourceSequential)
 {
-    ForEachItemIn(idx4, array)
-        groupThorGraphs(array.item(idx4).queryExprs());
+    groupThorGraphs(workflow.queryExprs());
 
-    ForEachItemIn(idx2, array)
-        mergeThorGraphs(array.item(idx2).queryExprs(), resourceConditionalActions, resourceSequential);
+    mergeThorGraphs(workflow.queryExprs(), resourceConditionalActions, resourceSequential);
 }
 
 //------------------------------------------------------------------------
@@ -7416,58 +7394,54 @@ IHqlExpression * NewScopeMigrateTransformer::createTransformed(IHqlExpression *
 
 
 
-void migrateExprToNaturalLevel(WorkflowArray & array, IWorkUnit * wu, HqlCppTranslator & translator)
+void migrateExprToNaturalLevel(WorkflowItem & cur, IWorkUnit * wu, HqlCppTranslator & translator)
 {
     const HqlCppOptions & options = translator.queryOptions();
-    ForEachItemIn(idx, array)
+    HqlExprArray & exprs = cur.queryExprs();
+    if (translator.queryOptions().moveUnconditionalActions)
+        moveUnconditionalEarlier(exprs);
+    translator.checkNormalized(exprs);
+
+    if (options.hoistSimpleGlobal)
     {
-        WorkflowItem & cur = array.item(idx);
-        HqlExprArray & exprs = cur.queryExprs();
-        if (translator.queryOptions().moveUnconditionalActions)
-            moveUnconditionalEarlier(exprs);
+        ScalarGlobalTransformer transformer(translator);
+        HqlExprArray results;
+        transformer.analyseArray(exprs, 0);
+        transformer.transformRoot(exprs, results);
+        replaceArray(exprs, results);
         translator.checkNormalized(exprs);
+    }
 
-        if (options.hoistSimpleGlobal)
-        {
-            ScalarGlobalTransformer transformer(translator);
-            HqlExprArray results;
-            transformer.analyseArray(exprs, 0);
-            transformer.transformRoot(exprs, results);
-            replaceArray(exprs, results);
-            translator.checkNormalized(exprs);
-        }
-
-        translator.traceExpressions("m0", exprs);
-
-        if (options.workunitTemporaries)
-        {
-            ExplicitGlobalTransformer transformer(wu, translator);
+    translator.traceExpressions("m0", exprs);
 
-            transformer.analyseArray(exprs, 0);
-            if (transformer.needToTransform())
-            {
-                HqlExprArray results;
-                transformer.transformRoot(exprs, results);
-                replaceArray(exprs, results);
-            }
-            translator.checkNormalized(exprs);
-        }
-
-        translator.traceExpressions("m1", exprs);
+    if (options.workunitTemporaries)
+    {
+        ExplicitGlobalTransformer transformer(wu, translator);
 
-        if (options.allowScopeMigrate) // && !options.minimizeWorkunitTemporaries)
+        transformer.analyseArray(exprs, 0);
+        if (transformer.needToTransform())
         {
-            NewScopeMigrateTransformer transformer(wu, translator);
             HqlExprArray results;
-
-            transformer.analyseArray(exprs, 0);
             transformer.transformRoot(exprs, results);
             replaceArray(exprs, results);
-            translator.checkNormalized(exprs);
         }
+        translator.checkNormalized(exprs);
+    }
 
-        translator.traceExpressions("m2", exprs);
+    translator.traceExpressions("m1", exprs);
+
+    if (options.allowScopeMigrate) // && !options.minimizeWorkunitTemporaries)
+    {
+        NewScopeMigrateTransformer transformer(wu, translator);
+        HqlExprArray results;
+
+        transformer.analyseArray(exprs, 0);
+        transformer.transformRoot(exprs, results);
+        replaceArray(exprs, results);
+        translator.checkNormalized(exprs);
     }
+
+    translator.traceExpressions("m2", exprs);
 }
 
 void expandGlobalDatasets(WorkflowArray & array, IWorkUnit * wu, HqlCppTranslator & translator)
@@ -7768,20 +7742,16 @@ bool TrivialGraphRemover::isTrivialGraph(IHqlExpression * expr)
 
 }
 
-void removeTrivialGraphs(WorkflowArray & workflow)
+void removeTrivialGraphs(WorkflowItem & curWorkflow)
 {
-    ForEachItemIn(idx, workflow)
+    HqlExprArray & exprs = curWorkflow.queryExprs();
+    TrivialGraphRemover transformer;
+    transformer.analyseArray(exprs, 0);
+    if (transformer.worthTransforming())
     {
-        WorkflowItem & cur = workflow.item(idx);
-        HqlExprArray & exprs = cur.queryExprs();
-        TrivialGraphRemover transformer;
-        transformer.analyseArray(exprs, 0);
-        if (transformer.worthTransforming())
-        {
-            HqlExprArray simplified;
-            transformer.transformRoot(exprs, simplified);
-            replaceArray(exprs, simplified);
-        }
+        HqlExprArray simplified;
+        transformer.transformRoot(exprs, simplified);
+        replaceArray(exprs, simplified);
     }
 }
 
@@ -9850,12 +9820,6 @@ void normalizeAnnotations(HqlCppTranslator & translator, HqlExprArray & exprs)
     DEBUG_TIMERX(translator.queryTimeReporter(), "EclServer: tree transform: normalize.annotations", msTick()-time);
 }
 
-void normalizeAnnotations(HqlCppTranslator & translator, WorkflowArray & workflow)
-{
-    ForEachItemIn(i, workflow)
-        normalizeAnnotations(translator, workflow.item(i).queryExprs());
-}
-
 //---------------------------------------------------------------------------
 
 static HqlTransformerInfo containsCompoundTransformerInfo("ContainsCompoundTransformer");
@@ -12529,36 +12493,12 @@ bool HqlCppTranslator::transformGraphForGeneration(HqlQueryContext & query, Work
 
     unsigned time4 = msTick();
     ::extractWorkflow(*this, exprs, workflow);
+
+
     traceExpressions("workflow", workflow);
     checkNormalized(workflow);
     DEBUG_TIMER("EclServer: tree transform: stored results", msTick()-time4);
 
-#ifdef USE_SELSEQ_UID
-    if (options.normalizeSelectorSequence)
-    {
-        unsigned time = msTick();
-        ForEachItemIn(i, workflow)
-        {
-            LeftRightTransformer normalizer;
-            normalizer.process(workflow.item(i).queryExprs());
-        }
-        DEBUG_TIMERX(queryTimeReporter(), "EclServer: tree transform: left right", msTick()-time);
-        //traceExpressions("after implicit alias", workflow);
-    }
-#endif
-
-    if (queryOptions().createImplicitAliases)
-    {
-        unsigned time = msTick();
-        ForEachItemIn(i, workflow)
-        {
-            ImplicitAliasTransformer normalizer;
-            normalizer.process(workflow.item(i).queryExprs());
-        }
-        DEBUG_TIMERX(queryTimeReporter(), "EclServer: tree transform: implicit alias", msTick()-time);
-        //traceExpressions("after implicit alias", workflow);
-    }
-
     if (outputLibrary && workflow.ordinality() > 1)
     {
         unsigned cnt = 0;
@@ -12575,93 +12515,117 @@ bool HqlCppTranslator::transformGraphForGeneration(HqlQueryContext & query, Work
         }
     }
 
+    ForEachItemIn(i, workflow)
     {
-        unsigned startTime = msTick();
-        hoistNestedCompound(*this, workflow);
-        DEBUG_TIMER("EclServer: tree transform: hoist nested compound", msTick()-startTime);
-    }
+        WorkflowItem & curWorkflow = workflow.item(i);
 
-    if (options.optimizeNestedConditional)
-    {
-        cycle_t time = msTick();
-        ForEachItemIn(idx, workflow)
-            optimizeNestedConditional(workflow.item(idx).queryExprs());
-        DEBUG_TIMER("EclServer: optimize nested conditional", msTick()-time);
-        traceExpressions("nested", workflow);
-        checkNormalized(workflow);
-    }
+#ifdef USE_SELSEQ_UID
+        if (options.normalizeSelectorSequence)
+        {
+            unsigned time = msTick();
+            LeftRightTransformer normalizer;
+            normalizer.process(curWorkflow.queryExprs());
+            DEBUG_TIMERX(queryTimeReporter(), "EclServer: tree transform: left right", msTick()-time);
+            //traceExpressions("after implicit alias", workflow);
+        }
+#endif
 
-    checkNormalized(workflow);
-    //sort(x)[n] -> topn(x, n)[]n, count(x)>n -> count(choosen(x,n+1)) > n and possibly others
-    {
-        unsigned startTime = msTick();
-        optimizeActivities(workflow, !targetThor(), options.optimizeNonEmpty);
-        DEBUG_TIMER("EclServer: tree transform: optimize activities", msTick()-startTime);
-    }
-    checkNormalized(workflow);
+        if (queryOptions().createImplicitAliases)
+        {
+            unsigned time = msTick();
+            ImplicitAliasTransformer normalizer;
+            normalizer.process(curWorkflow.queryExprs());
+            DEBUG_TIMERX(queryTimeReporter(), "EclServer: tree transform: implicit alias", msTick()-time);
+            //traceExpressions("after implicit alias", workflow);
+        }
 
-    unsigned time5 = msTick();
-    migrateExprToNaturalLevel(workflow, wu(), *this);       // Ensure expressions are evaluated at the best level - e.g., counts moved to most appropriate level.
-    DEBUG_TIMER("EclServer: tree transform: migrate", msTick()-time5);
-    //transformToAliases(exprs);
-    traceExpressions("migrate", workflow);
-    checkNormalized(workflow);
+        {
+            unsigned startTime = msTick();
+            hoistNestedCompound(*this, curWorkflow.queryExprs());
+            DEBUG_TIMER("EclServer: tree transform: hoist nested compound", msTick()-startTime);
+        }
 
-    unsigned time2 = msTick();
-    markThorBoundaries(workflow);                                               // work out which engine is going to perform which operation.
-    DEBUG_TIMER("EclServer: tree transform: thor hole", msTick()-time2);
-    traceExpressions("boundary", workflow);
-    checkNormalized(workflow);
+        if (options.optimizeNestedConditional)
+        {
+            cycle_t time = msTick();
+            optimizeNestedConditional(curWorkflow.queryExprs());
+            DEBUG_TIMER("EclServer: optimize nested conditional", msTick()-time);
+            traceExpressions("nested", curWorkflow);
+            checkNormalized(curWorkflow);
+        }
 
-    if (options.optimizeGlobalProjects)
-    {
-        cycle_t time = msTick();
-        ForEachItemIn(idx, workflow)
-            insertImplicitProjects(*this, workflow.item(idx).queryExprs());
-        DEBUG_TIMER("EclServer: global implicit projects", msTick()-time);
-        traceExpressions("implicit", workflow);
-        checkNormalized(workflow);
-    }
+        checkNormalized(curWorkflow);
+        //sort(x)[n] -> topn(x, n)[]n, count(x)>n -> count(choosen(x,n+1)) > n and possibly others
+        {
+            unsigned startTime = msTick();
+            optimizeActivities(curWorkflow.queryExprs(), !targetThor(), options.optimizeNonEmpty);
+            DEBUG_TIMER("EclServer: tree transform: optimize activities", msTick()-startTime);
+        }
+        checkNormalized(curWorkflow);
 
-    unsigned time3 = msTick();
-    normalizeResultFormat(workflow, options);
-    DEBUG_TIMER("EclServer: tree transform: normalize result", msTick()-time3);
-    traceExpressions("results", workflow);
-    checkNormalized(workflow);
+        unsigned time5 = msTick();
+        migrateExprToNaturalLevel(curWorkflow, wu(), *this);       // Ensure expressions are evaluated at the best level - e.g., counts moved to most appropriate level.
+        DEBUG_TIMER("EclServer: tree transform: migrate", msTick()-time5);
+        //transformToAliases(exprs);
+        traceExpressions("migrate", curWorkflow);
+        checkNormalized(curWorkflow);
 
-    optimizePersists(workflow);
+        unsigned time2 = msTick();
+        markThorBoundaries(curWorkflow);                                               // work out which engine is going to perform which operation.
+        DEBUG_TIMER("EclServer: tree transform: thor hole", msTick()-time2);
+        traceExpressions("boundary", curWorkflow);
+        checkNormalized(curWorkflow);
 
-    traceExpressions("per", workflow);
-    checkNormalized(workflow);
-//  flattenDatasets(workflow);
-//  traceExpressions("flatten", workflow);
+        if (options.optimizeGlobalProjects)
+        {
+            cycle_t time = msTick();
+            insertImplicitProjects(*this, curWorkflow.queryExprs());
+            DEBUG_TIMER("EclServer: global implicit projects", msTick()-time);
+            traceExpressions("implicit", curWorkflow);
+            checkNormalized(curWorkflow);
+        }
 
-    {
-        unsigned startTime = msTick();
-        mergeThorGraphs(workflow, options.resourceConditionalActions, options.resourceSequential);          // reduces number of graphs sent to thor
-        DEBUG_TIMER("EclServer: tree transform: merge thor", msTick()-startTime);
-    }
+        unsigned time3 = msTick();
+        normalizeResultFormat(curWorkflow, options);
+        DEBUG_TIMER("EclServer: tree transform: normalize result", msTick()-time3);
+        traceExpressions("results", curWorkflow);
+        checkNormalized(curWorkflow);
 
-    traceExpressions("merged", workflow);
-    checkNormalized(workflow);
+        optimizePersists(curWorkflow.queryExprs());
 
-    if (queryOptions().normalizeLocations)
-        normalizeAnnotations(*this, workflow);
+        traceExpressions("per", curWorkflow);
+        checkNormalized(curWorkflow);
+    //  flattenDatasets(workflow);
+    //  traceExpressions("flatten", workflow);
 
-    spotGlobalCSE(workflow);                                                        // spot CSE within those graphs, and create some more
-    checkNormalized(workflow);
+        {
+            unsigned startTime = msTick();
+            mergeThorGraphs(curWorkflow, options.resourceConditionalActions, options.resourceSequential);          // reduces number of graphs sent to thor
+            DEBUG_TIMER("EclServer: tree transform: merge thor", msTick()-startTime);
+        }
 
-    //expandGlobalDatasets(workflow, wu(), *this);
+        traceExpressions("merged", curWorkflow);
+        checkNormalized(curWorkflow);
 
-    {
-        unsigned startTime = msTick();
-        mergeThorGraphs(workflow, options.resourceConditionalActions, options.resourceSequential);
-        DEBUG_TIMER("EclServer: tree transform: merge thor", msTick()-startTime);
+        if (queryOptions().normalizeLocations)
+            normalizeAnnotations(*this, curWorkflow.queryExprs());
+
+        spotGlobalCSE(curWorkflow);                                                        // spot CSE within those graphs, and create some more
+        checkNormalized(curWorkflow);
+
+        //expandGlobalDatasets(workflow, wu(), *this);
+
+        {
+            unsigned startTime = msTick();
+            mergeThorGraphs(curWorkflow, options.resourceConditionalActions, options.resourceSequential);
+            DEBUG_TIMER("EclServer: tree transform: merge thor", msTick()-startTime);
+        }
+        checkNormalized(curWorkflow);
+
+        removeTrivialGraphs(curWorkflow);
+        checkNormalized(curWorkflow);
     }
-    checkNormalized(workflow);
 
-    removeTrivialGraphs(workflow);
-    checkNormalized(workflow);
 
 #ifndef PICK_ENGINE_EARLY
     if (options.pickBestEngine)
@@ -12669,22 +12633,25 @@ bool HqlCppTranslator::transformGraphForGeneration(HqlQueryContext & query, Work
 #endif
     updateClusterType();
 
-    traceExpressions("before convert to logical", workflow);
+    ForEachItemIn(i2, workflow)
+    {
+        WorkflowItem & curWorkflow = workflow.item(i2);
+        traceExpressions("before convert to logical", curWorkflow);
 
-    convertLogicalToActivities(workflow);                                           // e.g., merge disk reads, transform group, all to sort etc.
+        convertLogicalToActivities(curWorkflow);                                           // e.g., merge disk reads, transform group, all to sort etc.
 
-#ifndef _DEBUG
-    if (options.regressionTest)
-#endif
-    {
-        unsigned startTime = msTick();
-        ForEachItemIn(icheck, workflow)
-            checkDependencyConsistency(workflow.item(icheck).queryExprs());
-        DEBUG_TIMER("EclServer: tree transform: check dependency", msTick()-startTime);
-    }
+    #ifndef _DEBUG
+        if (options.regressionTest)
+    #endif
+        {
+            unsigned startTime = msTick();
+            checkDependencyConsistency(curWorkflow.queryExprs());
+            DEBUG_TIMER("EclServer: tree transform: check dependency", msTick()-startTime);
+        }
 
-    traceExpressions("end transformGraphForGeneration", workflow);
-    checkNormalized(workflow);
+        traceExpressions("end transformGraphForGeneration", curWorkflow);
+        checkNormalized(curWorkflow);
+    }
     return true;
 }
 

+ 4 - 6
ecl/hqlcpp/hqlttcpp.ipp

@@ -1085,7 +1085,6 @@ protected:
 };
 
 void normalizeAnnotations(HqlCppTranslator & translator, HqlExprArray & exprs);
-void normalizeAnnotations(HqlCppTranslator & translator, WorkflowArray & workflow);
 
 //---------------------------------------------------------------------------
 
@@ -1216,13 +1215,12 @@ void hoistNestedCompound(HqlCppTranslator & _translator, HqlExprArray & exprs);
 void hoistNestedCompound(HqlCppTranslator & _translator, WorkflowArray & workflow);
 
 //---------------------------------------------------------------------------
-void expandGlobalDatasets(WorkflowArray & array, IWorkUnit * wu, HqlCppTranslator & translator);
-void mergeThorGraphs(WorkflowArray & array, bool resourceConditionalActions, bool resourceSequential);
-void migrateExprToNaturalLevel(WorkflowArray & array, IWorkUnit * wu, HqlCppTranslator & translator);
-void removeTrivialGraphs(WorkflowArray & workflow);
+void expandGlobalDatasets(WorkflowItem & curWorkflow, IWorkUnit * wu, HqlCppTranslator & translator);
+void mergeThorGraphs(WorkflowItem & curWorkflow, bool resourceConditionalActions, bool resourceSequential);
+void migrateExprToNaturalLevel(WorkflowItem & curWorkflow, IWorkUnit * wu, HqlCppTranslator & translator);
+void removeTrivialGraphs(WorkflowItem & curWorkflow);
 void extractWorkflow(HqlCppTranslator & translator, HqlExprArray & exprs, WorkflowArray & out);
 void optimizeActivities(HqlExprArray & exprs, bool optimizeCountCompare, bool optimizeNonEmpty);
-void optimizeActivities(WorkflowArray & array, bool optimizeCountCompare, bool optimizeNonEmpty);
 IHqlExpression * optimizeActivities(IHqlExpression * expr, bool optimizeCountCompare, bool optimizeNonEmpty);
 IHqlExpression * insertImplicitProjects(HqlCppTranslator & translator, IHqlExpression * expr, bool optimizeSpills);
 void insertImplicitProjects(HqlCppTranslator & translator, HqlExprArray & exprs);