This is an automated email from the ASF dual-hosted git repository.
mariofusco pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 0af05e67b6 [KIE-1085] avoid wasteful creation of a custom operator per
constraint at runtime when using the executable model (#5844)
0af05e67b6 is described below
commit 0af05e67b6e3c5aad14dd5b4cbb9f363cab932b5
Author: Mario Fusco <[email protected]>
AuthorDate: Mon Apr 15 08:26:05 2024 +0200
[KIE-1085] avoid wasteful creation of a custom operator per constraint at
runtime when using the executable model (#5844)
---
.../model/codegen/execmodel/PackageModel.java | 9 +++++++
.../generator/expressiontyper/ExpressionTyper.java | 7 +++--
.../generator/operatorspec/CustomOperatorSpec.java | 30 +++++++++++++++++-----
.../integrationtests/CustomOperatorTest.java | 21 +++++++++++++++
4 files changed, 57 insertions(+), 10 deletions(-)
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
index 254ddbb8e5..b3e157b96e 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
@@ -87,6 +87,7 @@ import
org.drools.model.codegen.execmodel.generator.QueryGenerator;
import org.drools.model.codegen.execmodel.generator.QueryParameter;
import org.drools.model.codegen.execmodel.generator.TypedExpression;
import org.drools.model.codegen.execmodel.generator.WindowReferenceGenerator;
+import
org.drools.model.codegen.execmodel.generator.operatorspec.CustomOperatorSpec;
import org.drools.model.codegen.execmodel.util.lambdareplace.CreatedClass;
import org.drools.model.functions.PredicateInformation;
import org.drools.modelcompiler.util.StringUtil;
@@ -187,6 +188,8 @@ public class PackageModel {
private final boolean prototypesAllowed;
+ private final CustomOperatorSpec customOperatorSpec = new
CustomOperatorSpec();
+
private PackageModel( ReleaseId releaseId, String name,
KnowledgeBuilderConfigurationImpl configuration, DialectCompiletimeRegistry
dialectCompiletimeRegistry, DRLIdGenerator exprIdGenerator) {
this(name, configuration, dialectCompiletimeRegistry, exprIdGenerator,
getPkgUUID(configuration, releaseId, name));
}
@@ -293,6 +296,10 @@ public class PackageModel {
return exprIdGenerator;
}
+ public CustomOperatorSpec getCustomOperatorSpec() {
+ return customOperatorSpec;
+ }
+
public void addImports(Collection<String> imports) {
this.imports.addAll(imports);
}
@@ -612,6 +619,8 @@ public class PackageModel {
rulesClass.addMember( generateListField("org.drools.model.Global",
"globals", globals.isEmpty() && !hasRuleUnit) );
+ customOperatorSpec.getOperatorDeclarations().forEach( op ->
rulesClass.addMember( parseBodyDeclaration( op ) ) );
+
if ( !typeMetaDataExpressions.isEmpty() ) {
BodyDeclaration<?> typeMetaDatasList =
parseBodyDeclaration("java.util.List<org.drools.model.TypeMetaData>
typeMetaDatas = new java.util.ArrayList<>();");
rulesClass.addMember(typeMetaDatasList);
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
index 62795cec94..928ca3f62a 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
@@ -66,14 +66,13 @@ import com.github.javaparser.ast.type.ReferenceType;
import com.github.javaparser.ast.type.Type;
import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
import org.drools.model.codegen.execmodel.errors.ParseExpressionErrorResult;
-import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.ModelGenerator;
import org.drools.model.codegen.execmodel.generator.RuleContext;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.TypedExpression;
import org.drools.model.codegen.execmodel.generator.UnificationTypedExpression;
import
org.drools.model.codegen.execmodel.generator.drlxparse.NumberAndStringArithmeticOperationCoercion;
-import
org.drools.model.codegen.execmodel.generator.operatorspec.CustomOperatorSpec;
import
org.drools.model.codegen.execmodel.generator.operatorspec.NativeOperatorSpec;
import org.drools.model.codegen.execmodel.generator.operatorspec.OperatorSpec;
import
org.drools.model.codegen.execmodel.generator.operatorspec.TemporalOperatorSpec;
@@ -126,8 +125,8 @@ import static
org.drools.model.codegen.execmodel.generator.expressiontyper.Flatt
import static org.drools.mvel.parser.MvelParser.parseType;
import static org.drools.mvel.parser.printer.PrintUtil.printNode;
import static org.drools.util.ClassUtils.extractGenericType;
-import static org.drools.util.ClassUtils.getter2property;
import static org.drools.util.ClassUtils.getTypeArgument;
+import static org.drools.util.ClassUtils.getter2property;
import static org.drools.util.ClassUtils.toRawClass;
import static org.kie.internal.ruleunit.RuleUnitUtil.isDataSource;
@@ -482,7 +481,7 @@ public class ExpressionTyper {
if ( org.drools.model.functions.Operator.Register.hasOperator(
operator ) ) {
return NativeOperatorSpec.INSTANCE;
}
- return CustomOperatorSpec.INSTANCE;
+ return ruleContext.getPackageModel().getCustomOperatorSpec();
}
private TypedExpressionResult
toTypedExpressionFromMethodCallOrField(Expression drlxExpr) {
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/operatorspec/CustomOperatorSpec.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/operatorspec/CustomOperatorSpec.java
index d484855c23..a5d2578bdd 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/operatorspec/CustomOperatorSpec.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/operatorspec/CustomOperatorSpec.java
@@ -18,14 +18,22 @@
*/
package org.drools.model.codegen.execmodel.generator.operatorspec;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.github.javaparser.ast.expr.MethodCallExpr;
import org.drools.base.base.ValueType;
import org.drools.compiler.rule.builder.EvaluatorDefinition;
-import com.github.javaparser.ast.expr.MethodCallExpr;
-import org.drools.model.functions.Operator;
import org.drools.model.codegen.execmodel.generator.RuleContext;
+import org.drools.model.functions.Operator;
public class CustomOperatorSpec extends NativeOperatorSpec {
- public static final CustomOperatorSpec INSTANCE = new CustomOperatorSpec();
+
+ private Set<String> generatedOperators = new HashSet<>();
+
+ private List<String> operatorDeclarations = new ArrayList<>();
@Override
protected Operator addOperatorArgument( RuleContext context,
MethodCallExpr methodCallExpr, String opName ) {
@@ -34,10 +42,20 @@ public class CustomOperatorSpec extends NativeOperatorSpec {
throw new RuntimeException( "Unknown custom operator: " + opName );
}
- String arg = "new " + CustomOperatorWrapper.class.getCanonicalName() +
"( new " + evalDef.getClass().getCanonicalName() + "().getEvaluator(" +
- ValueType.class.getCanonicalName() + ".OBJECT_TYPE, \"" +
opName + "\", false, null), \"" + opName + "\")";
+ String operatorInstance = "OPERATOR_" + opName + "_INSTANCE";
+
+ if (generatedOperators.add(opName)) {
+ String operatorFieldDeclaration = "public static final " +
Operator.class.getCanonicalName() + ".SingleValue<Object, Object> " +
operatorInstance +
+ " = new " + CustomOperatorWrapper.class.getCanonicalName()
+ "( new " + evalDef.getClass().getCanonicalName() + "().getEvaluator(" +
+ ValueType.class.getCanonicalName() + ".OBJECT_TYPE, \"" +
opName + "\", false, null), \"" + opName + "\");";
+ operatorDeclarations.add(operatorFieldDeclaration);
+ }
- methodCallExpr.addArgument( arg );
+ methodCallExpr.addArgument(
context.getPackageModel().getRulesFileNameWithPackage() + "." +
operatorInstance );
return null;
}
+
+ public List<String> getOperatorDeclarations() {
+ return operatorDeclarations;
+ }
}
diff --git
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CustomOperatorTest.java
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CustomOperatorTest.java
index 1ffeee7c02..8f7c8ef7aa 100644
---
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CustomOperatorTest.java
+++
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CustomOperatorTest.java
@@ -69,6 +69,18 @@ public class CustomOperatorTest {
customOperatorUsingCollections(constraints);
}
+ @Test
+ public void testNoOperatorInstancesCreatedAtRuntime() {
+ String constraints =
+ " $alice : Person(name == \"Alice\")\n" +
+ " $bob : Person(name == \"Bob\", addresses supersetOf
$alice.addresses)\n" +
+ " Person(name == \"Bob\", addresses supersetOf
$alice.addresses)\n";
+
+ customOperatorUsingCollections(constraints);
+
+
assertThat(SupersetOfEvaluatorDefinition.INSTANCES_COUNTER).isEqualTo(0);
+ }
+
@Test
public void testCustomOperatorUsingCollectionsInverted() {
// DROOLS-6983
@@ -90,6 +102,9 @@ public class CustomOperatorTest {
System.setProperty(EvaluatorOption.PROPERTY_NAME + "supersetOf",
SupersetOfEvaluatorDefinition.class.getName());
try {
final KieBase kbase =
KieBaseUtil.getKieBaseFromKieModuleFromDrl("custom-operator-test",
kieBaseTestConfiguration, drl);
+
+ SupersetOfEvaluatorDefinition.INSTANCES_COUNTER = 0;
+
final KieSession ksession = kbase.newKieSession();
try {
final Person alice = new Person("Alice", 30);
@@ -118,6 +133,12 @@ public class CustomOperatorTest {
private Evaluator[] evaluator;
+ static int INSTANCES_COUNTER = 0;
+
+ public SupersetOfEvaluatorDefinition() {
+ INSTANCES_COUNTER++;
+ }
+
public String[] getEvaluatorIds() {
return SupersetOfEvaluatorDefinition.SUPPORTED_IDS;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]