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; }
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 } }
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); } }
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; }