Skip to content

Commit 7d28e89

Browse files
l46kokcopybara-github
authored andcommitted
Add ConstantFoldingOptions
PiperOrigin-RevId: 599969298
1 parent f9f370d commit 7d28e89

File tree

4 files changed

+63
-14
lines changed

4 files changed

+63
-14
lines changed

optimizer/src/main/java/dev/cel/optimizer/optimizers/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ java_library(
1414
tags = [
1515
],
1616
deps = [
17+
"//:auto_value",
1718
"//bundle:cel",
1819
"//common",
1920
"//common:compiler_common",

optimizer/src/main/java/dev/cel/optimizer/optimizers/ConstantFoldingOptimizer.java

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import static com.google.common.collect.ImmutableList.toImmutableList;
1717
import static com.google.common.collect.MoreCollectors.onlyElement;
1818

19+
import com.google.auto.value.AutoValue;
1920
import com.google.common.collect.ImmutableList;
2021
import dev.cel.bundle.Cel;
2122
import dev.cel.common.CelAbstractSyntaxTree;
@@ -47,9 +48,22 @@
4748
* calls and select statements with their evaluated result.
4849
*/
4950
public final class ConstantFoldingOptimizer implements CelAstOptimizer {
50-
private static final int MAX_ITERATION_COUNT = 400;
51+
private static final ConstantFoldingOptimizer INSTANCE =
52+
new ConstantFoldingOptimizer(ConstantFoldingOptions.newBuilder().build());
5153

52-
public static final ConstantFoldingOptimizer INSTANCE = new ConstantFoldingOptimizer();
54+
/** Returns a default instance of constant folding optimizer with preconfigured defaults. */
55+
public static ConstantFoldingOptimizer getInstance() {
56+
return INSTANCE;
57+
}
58+
59+
/**
60+
* Returns a new instance of constant folding optimizer configured with the provided {@link
61+
* ConstantFoldingOptions}.
62+
*/
63+
public static ConstantFoldingOptimizer newInstance(
64+
ConstantFoldingOptions constantFoldingOptions) {
65+
return new ConstantFoldingOptimizer(constantFoldingOptions);
66+
}
5367

5468
// Use optional.of and optional.none as sentinel function names for folding optional calls.
5569
// TODO: Leverage CelValue representation of Optionals instead when available.
@@ -58,6 +72,7 @@ public final class ConstantFoldingOptimizer implements CelAstOptimizer {
5872
private static final CelExpr OPTIONAL_NONE_EXPR =
5973
CelExpr.ofCallExpr(0, Optional.empty(), OPTIONAL_NONE_FUNCTION, ImmutableList.of());
6074

75+
private final ConstantFoldingOptions constantFoldingOptions;
6176
private final MutableAst mutableAst;
6277

6378
@Override
@@ -67,7 +82,7 @@ public CelAbstractSyntaxTree optimize(CelNavigableAst navigableAst, Cel cel)
6782
int iterCount = 0;
6883
while (true) {
6984
iterCount++;
70-
if (iterCount == MAX_ITERATION_COUNT) {
85+
if (iterCount >= constantFoldingOptions.maxIterationLimit()) {
7186
throw new IllegalStateException("Max iteration count reached.");
7287
}
7388
Optional<CelExpr> foldableExpr =
@@ -553,7 +568,37 @@ private CelAbstractSyntaxTree pruneOptionalStructElements(
553568
return ast;
554569
}
555570

556-
private ConstantFoldingOptimizer() {
557-
this.mutableAst = MutableAst.newInstance(MAX_ITERATION_COUNT);
571+
/** Options to configure how Constant Folding behave. */
572+
@AutoValue
573+
public abstract static class ConstantFoldingOptions {
574+
public abstract int maxIterationLimit();
575+
576+
/** Builder for configuring the {@link ConstantFoldingOptions}. */
577+
@AutoValue.Builder
578+
public abstract static class Builder {
579+
580+
/**
581+
* Limit the number of iteration while performing constant folding. An exception is thrown if
582+
* the iteration count exceeds the set value.
583+
*/
584+
public abstract Builder maxIterationLimit(int value);
585+
586+
public abstract ConstantFoldingOptions build();
587+
588+
Builder() {}
589+
}
590+
591+
/** Returns a new options builder with recommended defaults pre-configured. */
592+
public static Builder newBuilder() {
593+
return new AutoValue_ConstantFoldingOptimizer_ConstantFoldingOptions.Builder()
594+
.maxIterationLimit(400);
595+
}
596+
597+
ConstantFoldingOptions() {}
598+
}
599+
600+
private ConstantFoldingOptimizer(ConstantFoldingOptions constantFoldingOptions) {
601+
this.constantFoldingOptions = constantFoldingOptions;
602+
this.mutableAst = MutableAst.newInstance(constantFoldingOptions.maxIterationLimit());
558603
}
559604
}

optimizer/src/test/java/dev/cel/optimizer/optimizers/ConstantFoldingOptimizerTest.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import dev.cel.optimizer.CelOptimizationException;
3131
import dev.cel.optimizer.CelOptimizer;
3232
import dev.cel.optimizer.CelOptimizerFactory;
33+
import dev.cel.optimizer.optimizers.ConstantFoldingOptimizer.ConstantFoldingOptions;
3334
import dev.cel.parser.CelStandardMacro;
3435
import dev.cel.parser.CelUnparser;
3536
import dev.cel.parser.CelUnparserFactory;
@@ -53,7 +54,7 @@ public class ConstantFoldingOptimizerTest {
5354

5455
private static final CelOptimizer CEL_OPTIMIZER =
5556
CelOptimizerFactory.standardCelOptimizerBuilder(CEL)
56-
.addAstOptimizers(ConstantFoldingOptimizer.INSTANCE)
57+
.addAstOptimizers(ConstantFoldingOptimizer.getInstance())
5758
.build();
5859

5960
private static final CelUnparser CEL_UNPARSER = CelUnparserFactory.newUnparser();
@@ -211,7 +212,7 @@ public void constantFold_macros_macroCallMetadataPopulated(String source, String
211212
.build();
212213
CelOptimizer celOptimizer =
213214
CelOptimizerFactory.standardCelOptimizerBuilder(cel)
214-
.addAstOptimizers(ConstantFoldingOptimizer.INSTANCE)
215+
.addAstOptimizers(ConstantFoldingOptimizer.getInstance())
215216
.build();
216217
CelAbstractSyntaxTree ast = cel.compile(source).getAst();
217218

@@ -253,7 +254,7 @@ public void constantFold_macros_withoutMacroCallMetadata(String source) throws E
253254
.build();
254255
CelOptimizer celOptimizer =
255256
CelOptimizerFactory.standardCelOptimizerBuilder(cel)
256-
.addAstOptimizers(ConstantFoldingOptimizer.INSTANCE)
257+
.addAstOptimizers(ConstantFoldingOptimizer.getInstance())
257258
.build();
258259
CelAbstractSyntaxTree ast = cel.compile(source).getAst();
259260

@@ -299,7 +300,7 @@ public void constantFold_withMacroCallPopulated_comprehensionsAreReplacedWithNot
299300
.build();
300301
CelOptimizer celOptimizer =
301302
CelOptimizerFactory.standardCelOptimizerBuilder(cel)
302-
.addAstOptimizers(ConstantFoldingOptimizer.INSTANCE)
303+
.addAstOptimizers(ConstantFoldingOptimizer.getInstance())
303304
.build();
304305
CelAbstractSyntaxTree ast =
305306
cel.compile("[1, 1 + 1, 1 + 1+ 1].map(i, i).filter(j, j % 2 == x)").getAst();
@@ -384,17 +385,19 @@ public void constantFold_astProducesConsistentlyNumberedIds() throws Exception {
384385
public void iterationLimitReached_throws() throws Exception {
385386
StringBuilder sb = new StringBuilder();
386387
sb.append("0");
387-
for (int i = 1; i < 400; i++) {
388+
for (int i = 1; i < 200; i++) {
388389
sb.append(" + ").append(i);
389-
} // 0 + 1 + 2 + 3 + ... 400
390+
} // 0 + 1 + 2 + 3 + ... 200
390391
Cel cel =
391392
CelFactory.standardCelBuilder()
392-
.setOptions(CelOptions.current().maxParseRecursionDepth(400).build())
393+
.setOptions(CelOptions.current().maxParseRecursionDepth(200).build())
393394
.build();
394395
CelAbstractSyntaxTree ast = cel.compile(sb.toString()).getAst();
395396
CelOptimizer optimizer =
396397
CelOptimizerFactory.standardCelOptimizerBuilder(cel)
397-
.addAstOptimizers(ConstantFoldingOptimizer.INSTANCE)
398+
.addAstOptimizers(
399+
ConstantFoldingOptimizer.newInstance(
400+
ConstantFoldingOptions.newBuilder().maxIterationLimit(200).build()))
398401
.build();
399402

400403
CelOptimizationException e =

optimizer/src/test/java/dev/cel/optimizer/optimizers/SubexpressionOptimizerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ public void cse_applyConstFoldingAfter() throws Exception {
616616
.addAstOptimizers(
617617
SubexpressionOptimizer.newInstance(
618618
SubexpressionOptimizerOptions.newBuilder().populateMacroCalls(true).build()),
619-
ConstantFoldingOptimizer.INSTANCE)
619+
ConstantFoldingOptimizer.getInstance())
620620
.build();
621621

622622
CelAbstractSyntaxTree optimizedAst = optimizer.optimize(ast);

0 commit comments

Comments
 (0)