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