From a24fae69c344d8c92d6fcc2b98e6352b4fb66469 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Tue, 20 Jun 2023 14:49:23 +0200 Subject: [PATCH 1/3] DROOLS-7475 Proposed feature for ['key'] accessor see also https://github.com/kiegroup/drools-ansible-rulebook-integration/pull/56#discussion_r1235164928 make IndexableExpression interface so downstream can leverage this rather than specific concrete class --- .../main/java/org/drools/model/PrototypeDSL.java | 10 +++++----- .../java/org/drools/model/PrototypeExpression.java | 14 +++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java index dab43ff1e0f..37a6d3d1981 100644 --- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java +++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java @@ -132,8 +132,8 @@ public PrototypePatternDef expr(PrototypeExpression left, ConstraintOperator ope Prototype prototype = getPrototype(); Function1 leftExtractor; AlphaIndex alphaIndex = null; - if (left instanceof PrototypeExpression.PrototypeFieldValue && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType) { - String fieldName = ((PrototypeExpression.PrototypeFieldValue) left).getFieldName(); + if (left instanceof PrototypeExpression.IndexableExpression && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType) { + String fieldName = ((PrototypeExpression.IndexableExpression) left).getFieldName(); Index.ConstraintType constraintType = (Index.ConstraintType) operator; Prototype.Field field = prototype.getField(fieldName); Object value = ((PrototypeExpression.FixedValue) right).getValue(); @@ -186,13 +186,13 @@ other, asPredicate2(left.asFunction(prototype), operator, right.asFunction(other } private BetaIndex createBetaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Prototype otherPrototype) { - if (left instanceof PrototypeExpression.PrototypeFieldValue && operator instanceof Index.ConstraintType && right instanceof PrototypeExpression.PrototypeFieldValue) { - String fieldName = ((PrototypeExpression.PrototypeFieldValue) left).getFieldName(); + if (left instanceof PrototypeExpression.IndexableExpression && operator instanceof Index.ConstraintType && right instanceof PrototypeExpression.IndexableExpression) { + String fieldName = ((PrototypeExpression.IndexableExpression) left).getFieldName(); Index.ConstraintType constraintType = (Index.ConstraintType) operator; Prototype.Field field = prototype.getField(fieldName); Function1 extractor = getFieldValueExtractor(prototype, fieldName); - String otherFieldName = ((PrototypeExpression.PrototypeFieldValue) right).getFieldName(); + String otherFieldName = ((PrototypeExpression.IndexableExpression) right).getFieldName(); Function1 otherExtractor = getFieldValueExtractor(otherPrototype, otherFieldName); Class fieldClass = (Class) (field != null && field.isTyped() ? field.getType() : Object.class); diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java index da0192a9d74..52d33bb3b7e 100644 --- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java +++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java @@ -32,6 +32,17 @@ interface EvaluableExpression { Object evaluate(Map factsMap); } + /** + * Represent an expression which can be indexed (alpha/beta) by a given key + */ + interface IndexableExpression { + + /** + * the key to be used for indexing the expression + */ + String getFieldName(); + } + Function1 asFunction(Prototype prototype); Collection getImpactedFields(); @@ -137,7 +148,7 @@ public Collection getImpactedFields() { } } - class PrototypeFieldValue implements PrototypeExpression { + class PrototypeFieldValue implements PrototypeExpression, IndexableExpression { private final String fieldName; @@ -150,6 +161,7 @@ public Function1 asFunction(Prototype prototype) { return prototype.getFieldValueExtractor(fieldName)::apply; } + @Override public String getFieldName() { return fieldName; } From 6e26bb37ee1ea07085fad88230dde18ada0e95a4 Mon Sep 17 00:00:00 2001 From: mariofusco Date: Tue, 20 Jun 2023 17:12:48 +0200 Subject: [PATCH 2/3] fix PrototypeDSL --- .../main/java/org/drools/model/PrototypeDSL.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java index 37a6d3d1981..6c2906d932d 100644 --- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java +++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java @@ -130,21 +130,18 @@ public PrototypePatternDef expr(PrototypeExpression left, ConstraintOperator ope } Prototype prototype = getPrototype(); - Function1 leftExtractor; + Function1 leftExtractor = left.asFunction(prototype); AlphaIndex alphaIndex = null; if (left instanceof PrototypeExpression.IndexableExpression && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType) { String fieldName = ((PrototypeExpression.IndexableExpression) left).getFieldName(); Index.ConstraintType constraintType = (Index.ConstraintType) operator; Prototype.Field field = prototype.getField(fieldName); Object value = ((PrototypeExpression.FixedValue) right).getValue(); - leftExtractor = getFieldValueExtractor(prototype, fieldName); Class fieldClass = (Class) (field != null && field.isTyped() ? field.getType() : value != null ? value.getClass() : null); if (fieldClass != null) { alphaIndex = alphaIndexedBy(fieldClass, constraintType, getFieldIndex(prototype, fieldName, field), leftExtractor, value); } - } else { - leftExtractor = left.asFunction(prototype); } Set reactOnFields = new HashSet<>(); @@ -190,10 +187,8 @@ private BetaIndex createBetaIndex(PrototypeExpression left, ConstraintOperator o String fieldName = ((PrototypeExpression.IndexableExpression) left).getFieldName(); Index.ConstraintType constraintType = (Index.ConstraintType) operator; Prototype.Field field = prototype.getField(fieldName); - Function1 extractor = getFieldValueExtractor(prototype, fieldName); - - String otherFieldName = ((PrototypeExpression.IndexableExpression) right).getFieldName(); - Function1 otherExtractor = getFieldValueExtractor(otherPrototype, otherFieldName); + Function1 extractor = left.asFunction(prototype); + Function1 otherExtractor = right.asFunction(otherPrototype); Class fieldClass = (Class) (field != null && field.isTyped() ? field.getType() : Object.class); return betaIndexedBy( fieldClass, constraintType, getFieldIndex(prototype, fieldName, field), extractor, otherExtractor ); @@ -272,10 +267,6 @@ private PrototypeVariable[] findRightPrototypeVariables(PrototypeExpression righ private static boolean evaluateConstraint(Object leftValue, ConstraintOperator operator, Object rightValue) { return leftValue != Prototype.UNDEFINED_VALUE && rightValue != Prototype.UNDEFINED_VALUE && operator.asPredicate().test(leftValue, rightValue); } - - private Function1 getFieldValueExtractor(Prototype prototype, String fieldName) { - return prototype.getFieldValueExtractor(fieldName)::apply; - } } public static class PrototypeSubPatternDefImpl extends PrototypePatternDefImpl { From a26fce129055244517e2c94b5b239e53f318047c Mon Sep 17 00:00:00 2001 From: tarilabs Date: Wed, 21 Jun 2023 12:23:12 +0200 Subject: [PATCH 3/3] implement code review feedback --- .../java/org/drools/model/PrototypeDSL.java | 8 ++--- .../org/drools/model/PrototypeExpression.java | 29 +++++++++---------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java index 6c2906d932d..aea97784cce 100644 --- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java +++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java @@ -132,8 +132,8 @@ public PrototypePatternDef expr(PrototypeExpression left, ConstraintOperator ope Prototype prototype = getPrototype(); Function1 leftExtractor = left.asFunction(prototype); AlphaIndex alphaIndex = null; - if (left instanceof PrototypeExpression.IndexableExpression && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType) { - String fieldName = ((PrototypeExpression.IndexableExpression) left).getFieldName(); + if (left.getIndexingKey().isPresent() && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType) { + String fieldName = left.getIndexingKey().get(); Index.ConstraintType constraintType = (Index.ConstraintType) operator; Prototype.Field field = prototype.getField(fieldName); Object value = ((PrototypeExpression.FixedValue) right).getValue(); @@ -183,8 +183,8 @@ other, asPredicate2(left.asFunction(prototype), operator, right.asFunction(other } private BetaIndex createBetaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Prototype otherPrototype) { - if (left instanceof PrototypeExpression.IndexableExpression && operator instanceof Index.ConstraintType && right instanceof PrototypeExpression.IndexableExpression) { - String fieldName = ((PrototypeExpression.IndexableExpression) left).getFieldName(); + if (left.getIndexingKey().isPresent() && operator instanceof Index.ConstraintType && right.getIndexingKey().isPresent()) { + String fieldName = left.getIndexingKey().get(); Index.ConstraintType constraintType = (Index.ConstraintType) operator; Prototype.Field field = prototype.getField(fieldName); Function1 extractor = left.asFunction(prototype); diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java index 52d33bb3b7e..07d88908148 100644 --- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java +++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java @@ -21,6 +21,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.drools.model.functions.Function1; @@ -32,20 +33,16 @@ interface EvaluableExpression { Object evaluate(Map factsMap); } - /** - * Represent an expression which can be indexed (alpha/beta) by a given key - */ - interface IndexableExpression { - - /** - * the key to be used for indexing the expression - */ - String getFieldName(); - } - Function1 asFunction(Prototype prototype); Collection getImpactedFields(); + + /** + * if indexable, return a key for alpha/beta indexing + */ + default Optional getIndexingKey() { + return Optional.empty(); + } static PrototypeExpression fixedValue(Object value) { return new FixedValue(value); @@ -148,7 +145,7 @@ public Collection getImpactedFields() { } } - class PrototypeFieldValue implements PrototypeExpression, IndexableExpression { + class PrototypeFieldValue implements PrototypeExpression { private final String fieldName; @@ -162,8 +159,8 @@ public Function1 asFunction(Prototype prototype) { } @Override - public String getFieldName() { - return fieldName; + public Optional getIndexingKey() { + return Optional.of(fieldName); } @Override @@ -201,12 +198,12 @@ public Collection getPrototypeVariables() { @Override public Object evaluate(Map factsMap) { - return protoVar.getPrototype().getFieldValueExtractor(getFieldName()).apply(factsMap.get(protoVar)); + return protoVar.getPrototype().getFieldValueExtractor(getIndexingKey().get()).apply(factsMap.get(protoVar)); } @Override public String toString() { - return "PrototypeFieldValue{" + getFieldName() + " on " + protoVar + "}"; + return "PrototypeFieldValue{" + getIndexingKey() + " on " + protoVar + "}"; } }