AMQ-9052: Selectors - improve perfomance of Equals and Not

This commit is contained in:
Enrico Olivelli 2022-08-17 10:42:37 +02:00
parent 2c193ea01d
commit a978eb5115
3 changed files with 81 additions and 41 deletions

View File

@ -214,36 +214,66 @@ public abstract class ComparisonExpression extends BinaryExpression implements B
@SuppressWarnings({ "rawtypes" }) @SuppressWarnings({ "rawtypes" })
private static BooleanExpression doCreateEqual(Expression left, Expression right) { private static BooleanExpression doCreateEqual(Expression left, Expression right) {
return new ComparisonExpression(left, right) { return new EqualsExpression(left, right);
}
public Object evaluate(MessageEvaluationContext message) throws JMSException { private static class EqualsExpression extends ComparisonExpression {
Object lv = left.evaluate(message); EqualsExpression(Expression left, Expression right) {
Object rv = right.evaluate(message); super(left, right);
}
// If one of the values is null public Object evaluate(MessageEvaluationContext message) throws JMSException {
if (lv == null ^ rv == null) { Object lv = left.evaluate(message);
if (lv == null) { Object rv = right.evaluate(message);
return null;
} // If one of the values is null
return Boolean.FALSE; if (lv == null ^ rv == null) {
} if (lv == null) {
if (lv == rv || lv.equals(rv)) { return null;
return Boolean.TRUE;
}
if (lv instanceof Comparable && rv instanceof Comparable) {
return compare((Comparable)lv, (Comparable)rv);
} }
return Boolean.FALSE; return Boolean.FALSE;
} }
if (lv == rv || lv.equals(rv)) {
protected boolean asBoolean(int answer) { return Boolean.TRUE;
return answer == 0;
} }
if (lv instanceof Comparable && rv instanceof Comparable) {
public String getExpressionSymbol() { return compare((Comparable) lv, (Comparable) rv);
return "=";
} }
}; return Boolean.FALSE;
}
@Override
public boolean matches(MessageEvaluationContext message) throws JMSException {
Object lv = left.evaluate(message);
Object rv = right.evaluate(message);
// If one of the values is null
if (lv == null ^ rv == null) {
return false;
}
if (lv == rv || lv.equals(rv)) {
return true;
}
if (lv.getClass() == rv.getClass()) {
// same class, but 'equals' return false, and they are not the same object
// there is no point in doing 'compare'
// this case happens often while comparing non equals Strings
return false;
}
if (lv instanceof Comparable && rv instanceof Comparable) {
Boolean compareResult = compare((Comparable) lv, (Comparable) rv);
return compareResult != null && compareResult;
}
return false;
}
protected boolean asBoolean(int answer) {
return answer == 0;
}
public String getExpressionSymbol() {
return "=";
}
} }
public static BooleanExpression createGreaterThan(final Expression left, final Expression right) { public static BooleanExpression createGreaterThan(final Expression left, final Expression right) {
@ -286,7 +316,6 @@ public abstract class ComparisonExpression extends BinaryExpression implements B
public String getExpressionSymbol() { public String getExpressionSymbol() {
return "<"; return "<";
} }
}; };
} }
@ -491,5 +520,4 @@ public abstract class ComparisonExpression extends BinaryExpression implements B
Object object = evaluate(message); Object object = evaluate(message);
return object != null && object == Boolean.TRUE; return object != null && object == Boolean.TRUE;
} }
} }

View File

@ -141,7 +141,6 @@ public abstract class LogicExpression implements BooleanExpression {
public String getExpressionSymbol() { public String getExpressionSymbol() {
return "OR"; return "OR";
} }
} }
private static class ANDExpression extends LogicExpression { private static class ANDExpression extends LogicExpression {

View File

@ -86,7 +86,6 @@ public abstract class UnaryExpression implements Expression {
} else { } else {
return Boolean.FALSE; return Boolean.FALSE;
} }
} }
public String toString() { public String toString() {
@ -132,19 +131,7 @@ public abstract class UnaryExpression implements Expression {
}; };
public static BooleanExpression createNOT(BooleanExpression left) { public static BooleanExpression createNOT(BooleanExpression left) {
return new BooleanUnaryExpression(left) { return new NotExpression(left);
public Object evaluate(MessageEvaluationContext message) throws JMSException {
Boolean lvalue = (Boolean)right.evaluate(message);
if (lvalue == null) {
return null;
}
return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
}
public String getExpressionSymbol() {
return "NOT";
}
};
} }
public static BooleanExpression createXPath(final String xpath) { public static BooleanExpression createXPath(final String xpath) {
@ -243,7 +230,6 @@ public abstract class UnaryExpression implements Expression {
return false; return false;
} }
return toString().equals(o.toString()); return toString().equals(o.toString());
} }
/** /**
@ -254,4 +240,31 @@ public abstract class UnaryExpression implements Expression {
*/ */
public abstract String getExpressionSymbol(); public abstract String getExpressionSymbol();
private static class NotExpression extends BooleanUnaryExpression {
public NotExpression(BooleanExpression right) {
super(right);
}
public Object evaluate(MessageEvaluationContext message) throws JMSException {
Boolean lvalue = (Boolean) right.evaluate(message);
if (lvalue == null) {
return null;
}
return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
}
@Override
public boolean matches(MessageEvaluationContext message) throws JMSException {
Boolean lvalue = (Boolean) right.evaluate(message);
if (lvalue == null) {
// NOT NULL returns NULL that eventually fails the selector
return false;
}
return !lvalue;
}
public String getExpressionSymbol() {
return "NOT";
}
}
} }