Beispiel #1
0
bool HqlCppCaseInfo::buildReturn(BuildCtx & ctx)
{
    if (pairs.ordinality() == 0)
    {
        translator.buildReturn(ctx, defaultValue);
    }
    else if (cond.get() && constantCases)
    {
        processBranches();

        BuildCtx subctx(ctx);
        CHqlBoundExpr test;
        buildSwitchCondition(ctx, test);

        if (complexCompare)
        {
            buildGeneralReturn(subctx);
        }
        else
        {
            //if canBuildArrayLookup(test)
            //if use a lookup table to map value->constants
            if (test.queryType()->getTypeCode() != type_real)
                buildSwitchMap(subctx, NULL, test.expr);
            else
                buildGeneralReturn(subctx);
        }
    }
    else
        buildGeneralReturn(ctx);

    return true;
}
bool CppFilterExtractor::createGroupingMonitor(BuildCtx ctx, const char * listName, IHqlExpression * expr, unsigned & maxField)
{
    switch (expr->getOperator())
    {
    case no_if:
        {
            IHqlExpression * cond = expr->queryChild(0);
            if (expr->queryChild(2)->isConstant() && isIndependentOfScope(cond))
            {
                BuildCtx subctx(ctx);
                translator.buildFilter(subctx, expr->queryChild(0));
                createGroupingMonitor(subctx, listName, expr->queryChild(1), maxField);
                return true;        // may still be keyed
            }
            break;
        }
    case no_select:
        {
            size32_t offset = 0;
            ForEachItemIn(i, keyableSelects)
            {
                IHqlExpression & cur = keyableSelects.item(i);
                size32_t curSize = cur.queryType()->getSize();
                if (!createValueSets && curSize == UNKNOWN_LENGTH)
                    break;
                if (expr == &cur)
                {
                    maxField = i+1;
                    if (createValueSets)
                    {
                        StringBuffer type;
                        translator.buildRtlFieldType(type, expr->queryChild(1), queryRecord(tableExpr));
                        ctx.addQuotedF("%s->append(FFkeyed, createWildFieldFilter(%u, %s));", listName, i, type.str());
                    }
                    else
                    {
                        //MORE: Check the type of the field is legal.
                        ctx.addQuotedF("%s->append(createWildKeySegmentMonitor(%u, %u, %u));", listName, i, offset, curSize);
                    }
                    return true;
                }
                offset += curSize;
            }
            break;
        }
    case no_constant:
        return true;
    }
Beispiel #3
0
void HqlCppCaseInfo::buildChop3Map(BuildCtx & ctx, const CHqlBoundTarget & target, CHqlBoundExpr & test, IHqlExpression * temp, unsigned start, unsigned end)
{
    if ((end - start) <= 2)
        buildChop2Map(ctx, target, test, start, end);
    else
    {
        unsigned mid = start + (end - start) / 2;
        generateCompareVar(ctx, temp, test, queryCompare(mid));
        OwnedHqlExpr test1 = createValue(no_eq, LINK(temp), getZero());
        OwnedHqlExpr test2 = createValue(no_lt, LINK(temp), getZero());

        BuildCtx subctx(ctx);
        IHqlStmt * if1 = subctx.addFilter(test1);                   // if (test == 0)
        translator.buildExprAssign(subctx, target, queryReturn(mid));  //   target = value(n)
        subctx.selectElse(if1);                                                         // else
        IHqlStmt * if2 = subctx.addFilter(test2);                   //   if (test < 0)
        buildChop3Map(subctx, target, test, temp, start, mid);      //       repeat for start..mid
        subctx.selectElse(if2);                                                         //   else
        buildChop3Map(subctx, target, test, temp, mid+1, end);      //       repeat for min..end
    }
}
Beispiel #4
0
void HqlCppCaseInfo::buildChop2Map(BuildCtx & ctx, const CHqlBoundTarget & target, CHqlBoundExpr & test, unsigned start, unsigned end)
{
    BuildCtx subctx(ctx);
    
    if ((end - start) <= 3)             // (1,2,3) avg(2) cf. (2,2,3) avg(2.3)
    {
        //optimize the case where they all create the same value
        bool same = true;
        unsigned index;
        for (index=start+1; index < end; ++index)
        {
            if (queryReturn(index-1) != queryReturn(index))
            {
                same = false;
                break;
            }
        }
        
        if (same)
        {
            CompoundBuilder cb(no_or);
            for (index=start; index < end; ++index)
            {
                IHqlExpression * compare = queryCompare(index);
                IHqlExpression * cond  = createCompareExpr(no_eq, test.getTranslatedExpr(), LINK(compare));
                cb.addOperand(cond);
            }
            OwnedHqlExpr compound = cb.getCompound();
            translator.buildFilter(subctx, compound);
            translator.buildExprAssign(subctx, target, queryReturn(start));
        }
        else
        {
            IHqlStmt * stmt = NULL;
            for (index=start; index < end; ++index)
            {
                if (stmt)
                    subctx.selectElse(stmt);
                
                IHqlExpression * compare = queryCompare(index);
                OwnedHqlExpr cond  = createCompareExpr(no_eq, test.getTranslatedExpr(), LINK(compare));
                CHqlBoundExpr bound;
                translator.buildExpr(subctx, cond, bound);
                stmt = subctx.addFilter(bound.expr);
                translator.buildExprAssign(subctx, target, queryReturn(index));
            }
        }
    }
    else
    {
        unsigned mid = start + (end - start) / 2;
        
        IHqlExpression * compare = queryCompare(mid);
        OwnedHqlExpr cond  = createCompareExpr(no_lt, test.getTranslatedExpr(), LINK(compare));
        CHqlBoundExpr bound;
        translator.buildExpr(subctx, cond, bound);
        IHqlStmt * stmt = subctx.addFilter(bound.expr);

        buildChop2Map(subctx, target, test, start, mid);
        subctx.selectElse(stmt);
        buildChop2Map(subctx, target, test, mid, end);
    }
}
Beispiel #5
0
bool HqlCppCaseInfo::buildAssign(BuildCtx & ctx, const CHqlBoundTarget & target)
{
    if (pairs.ordinality() == 0)
    {
        translator.buildExprAssign(ctx, target, defaultValue);
    }
    else if (cond.get() && constantCases)
    {
        processBranches();

        BuildCtx subctx(ctx);
        CHqlBoundExpr test;
        buildSwitchCondition(ctx, test);

        if (complexCompare)
        {
            if (pairs.ordinality() > INLINE_COMPARE_THRESHOLD)
            {
                if (okToAlwaysEvaluateDefault() || hasLibraryChop())
                    buildLoopChopMap(subctx, target, test);
                else
                    buildGeneralAssign(subctx, target);
            }
            else 
            {
                if (okToAlwaysEvaluateDefault())
                    buildChop3Map(subctx, target, test);
                else
                    buildGeneralAssign(subctx, target);
            }
        }
        else
        {
            ITypeInfo * condType = test.queryType()->queryPromotedType();
            if (!queryBuildArrayLookup(subctx, target, test))
            {
                if (condType->getTypeCode() != type_real)
                {
                    OwnedHqlExpr search = test.getTranslatedExpr();
                    if (constantValues && (condType->getTypeCode() == type_int) && (pairs.ordinality() > INTEGER_SEARCH_THRESHOLD) && canBuildStaticList(resultType))
                        buildIntegerSearchMap(subctx, target, search);
                    else
                        buildSwitchMap(subctx, &target, test.expr);
                }
                else
                {
                    if (okToAlwaysEvaluateDefault() && pairs.ordinality() > 4)
                    {
                        translator.buildExprAssign(ctx, target, defaultValue);
                        buildChop2Map(subctx, target, test, 0, pairs.ordinality());
                    }
                    else
                        buildGeneralAssign(subctx, target);
                }
            }
        }
    }
    else
        buildGeneralAssign(ctx, target);

    return true;
}