Explorar o código

HPCC-13845 Improve the generated code for constant inline datasets

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday %!s(int64=10) %!d(string=hai) anos
pai
achega
29b3ba2dea

+ 2 - 0
ecl/hqlcpp/hqlcatom.cpp

@@ -451,6 +451,7 @@ IIdAtom * newDegroupArgId;
 IIdAtom * newExistsAggregateArgId;
 IIdAtom * newFunnelArgId;
 IIdAtom * newGraphLoopResultWriteArgId;
+IIdAtom * newLibraryConstantRawIteratorArgId;
 IIdAtom * newLocalResultReadArgId;
 IIdAtom * newLocalResultSpillArgId;
 IIdAtom * newMemorySpillReadArgId;
@@ -1100,6 +1101,7 @@ MODULE_INIT(INIT_PRIORITY_HQLATOM-1)
     MAKEID(newExistsAggregateArg);
     MAKEID(newFunnelArg);
     MAKEID(newGraphLoopResultWriteArg);
+    MAKEID(newLibraryConstantRawIteratorArg);
     MAKEID(newLocalResultReadArg);
     MAKEID(newLocalResultSpillArg);
     MAKEID(newMemorySpillReadArg);

+ 1 - 0
ecl/hqlcpp/hqlcatom.hpp

@@ -451,6 +451,7 @@ extern IIdAtom * newDegroupArgId;
 extern IIdAtom * newExistsAggregateArgId;
 extern IIdAtom * newFunnelArgId;
 extern IIdAtom * newGraphLoopResultWriteArgId;
+extern IIdAtom * newLibraryConstantRawIteratorArgId;
 extern IIdAtom * newLocalResultReadArgId;
 extern IIdAtom * newLocalResultSpillArgId;
 extern IIdAtom * newMemorySpillReadArgId;

+ 1 - 1
ecl/hqlcpp/hqlcpp.ipp

@@ -1249,7 +1249,7 @@ public:
     void createInlineDictionaryRows(HqlExprArray & args, ConstantRowArray & boundRows, IHqlExpression * keyRecord, IHqlExpression * nullRow);
     bool buildConstantRows(ConstantRowArray & boundRows, IHqlExpression * transforms);
     void doBuildDatasetLimit(BuildCtx & ctx, IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format);
-    bool doBuildDatasetInlineTable(BuildCtx & ctx, IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format);
+    bool doBuildConstantDatasetInlineTable(IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format);
     bool doBuildDictionaryInlineTable(BuildCtx & ctx, IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format);
     void doBuildDatasetNull(IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format);
 

+ 5 - 5
ecl/hqlcpp/hqlcppds.cpp

@@ -2207,7 +2207,7 @@ void HqlCppTranslator::doBuildDataset(BuildCtx & ctx, IHqlExpression * expr, CHq
             break;
         }
     case no_inlinetable:
-        if (doBuildDatasetInlineTable(ctx, expr, tgt, format))
+        if (doBuildConstantDatasetInlineTable(expr, tgt, format))
             return;
         break;
     case no_compound:
@@ -2400,7 +2400,7 @@ void HqlCppTranslator::buildDatasetAssign(BuildCtx & ctx, const CHqlBoundTarget
             if (options.canLinkConstantRows || (expr->queryChild(0)->numChildren() > INLINE_TABLE_EXPAND_LIMIT))
             {
                 CHqlBoundExpr bound;
-                if (doBuildDatasetInlineTable(ctx, expr, bound, FormatNatural))
+                if (doBuildConstantDatasetInlineTable(expr, bound, FormatNatural))
                 {
                     OwnedHqlExpr translated = bound.getTranslatedExpr();
                     buildDatasetAssign(ctx, target, translated);
@@ -2808,21 +2808,21 @@ bool HqlCppTranslator::buildConstantRows(ConstantRowArray & boundRows, IHqlExpre
     return true;
 }
 
-bool HqlCppTranslator::doBuildDatasetInlineTable(BuildCtx & ctx, IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format)
+bool HqlCppTranslator::doBuildConstantDatasetInlineTable(IHqlExpression * expr, CHqlBoundExpr & tgt, ExpressionFormat format)
 {
     if (!options.generateStaticInlineTables)
         return false;
 
+    BuildCtx declareCtx(*code, literalAtom);
     IHqlExpression * transforms = expr->queryChild(0);
     IHqlExpression * record = expr->queryRecord();
     if (transforms->numChildren() == 0)
     {
         OwnedHqlExpr null = createDataset(no_null, LINK(record));
-        buildDataset(ctx, null, tgt, format);
+        buildDataset(declareCtx, null, tgt, format);
         return true;
     }
 
-    BuildCtx declareCtx(*code, literalAtom);
     //Remove unique id when checking for constant datasets already generated
     OwnedHqlExpr exprKey = removeAttribute(expr, _uid_Atom);
     if (declareCtx.getMatchExpr(exprKey, tgt))

+ 1 - 0
ecl/hqlcpp/hqlcppsys.ecl

@@ -772,6 +772,7 @@ const char * cppSystemText[]  = {
     "   boolean newExistsAggregateArg(boolean _meta) : include, pseudoentrypoint='new CLibraryExistsAggregateArg';",
     "   boolean newFunnelArg(boolean _ordered, boolean _sequential, boolean _meta) : include, pseudoentrypoint='new CLibraryFunnelArg';",
     "   boolean newGraphLoopResultWriteArg(boolean _meta) : include, pseudoentrypoint='new CLibraryGraphLoopResultWriteArg';",
+    "   boolean newLibraryConstantRawIteratorArg(linkcounted dataset _x, boolean meta) : include, pseudoentrypoint='new CLibraryConstantRawIteratorArg';",
     "   boolean newLocalResultReadArg(unsigned4 _sequence, boolean meta) : include, pseudoentrypoint='new CLibraryLocalResultReadArg';",
     "   boolean newLocalResultSpillArg(unsigned4 _sequence, boolean _usedOutside, boolean meta) : include, pseudoentrypoint='new CLibraryLocalResultSpillArg';",
     "   boolean newNullArg(boolean meta) : include, pseudoentrypoint='new CLibraryNullArg';",

+ 33 - 35
ecl/hqlcpp/hqlhtcpp.cpp

@@ -16932,6 +16932,26 @@ ABoundActivity * HqlCppTranslator::doBuildActivityInlineTable(BuildCtx & ctx, IH
         return doBuildActivityCreateRow(ctx, row, true);
     }
 
+    if (values->isConstant())
+    {
+        CHqlBoundExpr bound;
+        if (doBuildConstantDatasetInlineTable(expr, bound, FormatNatural))
+        {
+            OwnedHqlExpr constDataset = bound.getTranslatedExpr();
+
+            Owned<ActivityInstance> instance = new ActivityInstance(*this, ctx, TAKlinkedrawiterator, expr, "LinkedRawIterator");
+            instance->graphLabel.set("Inline Dataset");
+            instance->setImplementationClass(newLibraryConstantRawIteratorArgId);
+            buildActivityFramework(instance);
+
+            buildInstancePrefix(instance);
+            instance->addConstructorParameter(constDataset);
+            buildInstanceSuffix(instance);
+
+            return instance->getBoundActivity();
+        }
+    }
+
     Owned<ActivityInstance> instance = new ActivityInstance(*this, ctx, TAKinlinetable, expr, "InlineTable");
 
     //-----------------
@@ -16946,47 +16966,25 @@ ABoundActivity * HqlCppTranslator::doBuildActivityInlineTable(BuildCtx & ctx, IH
     IHqlExpression * self = selfCursor->querySelector();
 
     unsigned maxRows = values->numChildren();
-    bool done = false;
-    if (values->isConstant())
+    if (maxRows)
     {
-        CHqlBoundExpr bound;
-        if (doBuildDatasetInlineTable(funcctx, expr, bound, FormatNatural))
-        {
-            OwnedHqlExpr whichRow = createVariable("row", LINK(unsignedType));
-            BuildCtx subctx(funcctx);
-            OwnedHqlExpr test = createValue(no_ge, makeBoolType(), LINK(whichRow), getSizetConstant(maxRows));
-            subctx.addFilter(test);
-            buildReturn(subctx, queryZero());
-            OwnedHqlExpr ds = bound.getTranslatedExpr();
-            OwnedHqlExpr thisRow = createRowF(no_selectnth, LINK(ds), adjustValue(whichRow, 1), createAttribute(noBoundCheckAtom), NULL);
-            buildAssign(funcctx, self, thisRow);
-            buildReturnRecordSize(funcctx, selfCursor);
-            done = true;
-        }
-    }
+        StringBuffer s;
+        BuildCtx switchctx(funcctx);
+        switchctx.addQuotedCompound("switch (row)");
 
-    if (!done)
-    {
-        if (maxRows)
+        unsigned row;
+        for (row = 0; row < maxRows; row++)
         {
-            StringBuffer s;
-            BuildCtx switchctx(funcctx);
-            switchctx.addQuotedCompound("switch (row)");
-
-            unsigned row;
-            for (row = 0; row < maxRows; row++)
-            {
-                BuildCtx casectx(switchctx);
-                casectx.addQuotedCompound(s.clear().append("case ").append(row).append(":"));
+            BuildCtx casectx(switchctx);
+            casectx.addQuotedCompound(s.clear().append("case ").append(row).append(":"));
 
-                IHqlExpression * cur = values->queryChild(row);
-                OwnedHqlExpr rowValue = createRow(no_createrow, LINK(cur));
-                buildAssign(casectx, self, rowValue);
-                buildReturnRecordSize(casectx, selfCursor);
-            }
+            IHqlExpression * cur = values->queryChild(row);
+            OwnedHqlExpr rowValue = createRow(no_createrow, LINK(cur));
+            buildAssign(casectx, self, rowValue);
+            buildReturnRecordSize(casectx, selfCursor);
         }
-        funcctx.addReturn(queryZero());
     }
+    funcctx.addReturn(queryZero());
 
     OwnedHqlExpr rowsExpr = getSizetConstant(maxRows);
     doBuildUnsigned64Function(instance->startctx, "numRows", rowsExpr);

+ 27 - 0
rtl/include/eclhelper_base.hpp

@@ -3721,6 +3721,33 @@ protected:
     IOutputMetaData * meta;
 };
 
+class CLibraryConstantRawIteratorArg : public CThorLinkedRawIteratorArg
+{
+public:
+    inline CLibraryConstantRawIteratorArg(unsigned _numRows, byte * * _rows, IOutputMetaData * _meta)
+        : meta(_meta), numRows(_numRows), rows(_rows)
+    {
+        cur = 0;
+    }
+
+    virtual void onStart(const byte *, MemoryBuffer * ) { cur = 0U; }
+
+    virtual byte * next()
+    {
+        if (cur < numRows)
+            return rows[cur++];
+        return NULL;
+    }
+
+    virtual IOutputMetaData * queryOutputMeta() { return meta; }
+
+protected:
+    unsigned numRows;
+    IOutputMetaData * meta;
+    byte * * rows;
+    unsigned cur;
+};
+
 class EclProcess : public RtlCInterface, implements IEclProcess
 {
 public: