ARTEMIS-4693 Improve XPath filter performance

In most use cases there are broker instances with few XPath filters performed
many times, so reusing a compiled XPath expression improves XPath filter
performance
This commit is contained in:
Domenico Francesco Bruscino 2024-03-19 08:51:34 +01:00 committed by clebertsuconic
parent 71d3393224
commit 6736c525e6
1 changed files with 9 additions and 1 deletions

View File

@ -19,6 +19,7 @@ package org.apache.activemq.artemis.selector.filter;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import java.io.StringReader; import java.io.StringReader;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -36,6 +37,7 @@ public class JAXPXPathEvaluator implements XPathExpression.XPathEvaluator {
private final String xpathExpression; private final String xpathExpression;
private final XPath xpath; private final XPath xpath;
private final DocumentBuilder builder; private final DocumentBuilder builder;
private final javax.xml.xpath.XPathExpression compiledXPathExpression;
public JAXPXPathEvaluator(String xpathExpression, DocumentBuilder builder) { public JAXPXPathEvaluator(String xpathExpression, DocumentBuilder builder) {
this.xpathExpression = xpathExpression; this.xpathExpression = xpathExpression;
@ -43,6 +45,12 @@ public class JAXPXPathEvaluator implements XPathExpression.XPathEvaluator {
synchronized (FACTORY) { synchronized (FACTORY) {
this.xpath = FACTORY.newXPath(); this.xpath = FACTORY.newXPath();
} }
try {
this.compiledXPathExpression = xpath.compile(xpathExpression);
} catch (XPathExpressionException e) {
throw new IllegalArgumentException(e);
}
} }
@Override @Override
@ -61,7 +69,7 @@ public class JAXPXPathEvaluator implements XPathExpression.XPathEvaluator {
protected boolean evaluate(InputSource inputSource) { protected boolean evaluate(InputSource inputSource) {
try { try {
synchronized (builder) { synchronized (builder) {
return ((Boolean)xpath.evaluate(xpathExpression, builder.parse(inputSource), XPathConstants.BOOLEAN)).booleanValue(); return ((Boolean)compiledXPathExpression.evaluate(builder.parse(inputSource), XPathConstants.BOOLEAN)).booleanValue();
} }
} catch (Exception e) { } catch (Exception e) {
logger.debug("Failed to evaluate XPath expression {}", xpathExpression, inputSource, e); logger.debug("Failed to evaluate XPath expression {}", xpathExpression, inputSource, e);