Skip to content

Commit

Permalink
Added cache for functions
Browse files Browse the repository at this point in the history
  • Loading branch information
MrEasy committed May 16, 2022
1 parent b4b4d2c commit 1f34da9
Showing 1 changed file with 37 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

import org.apache.commons.jxpath.CompiledExpression;
import org.apache.commons.jxpath.ExceptionHandler;
Expand Down Expand Up @@ -89,6 +90,8 @@ public class JXPathContextReferenceImpl extends JXPathContext {
private static final Compiler COMPILER = new TreeCompiler();
private static final Map<String, Expression> compiled;

private static final Map<Integer, Function> functionCache;

private static NodePointerFactory[] nodeFactoryArray;
private static final Collection<NodePointerFactory> nodeFactories = new CopyOnWriteArrayList<>();

Expand All @@ -98,14 +101,22 @@ public class JXPathContextReferenceImpl extends JXPathContext {
CACHE_STATISTICS = Boolean.getBoolean("jxpath.cache.statistics");
USE_SOFT_CACHE = "true".equalsIgnoreCase(System.getProperty("jxpath.cache.soft", "true"));
if (CACHE_ENABLED) {
final int compileCacheSize = Integer.getInteger("jxpath.cache.size", 50_000);
final int cacheSize = Integer.getInteger("jxpath.cache.size", 50_000);
if (USE_SOFT_CACHE) {
compiled = new SoftConcurrentHashMap<>(compileCacheSize);
compiled = new SoftConcurrentHashMap<>(cacheSize);
functionCache = new SoftConcurrentHashMap<>(cacheSize);
} else {
compiled = new LinkedHashMap<String, Expression>() {
@Override
protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
return this.size() > compileCacheSize;
return this.size() > cacheSize;
}
};

functionCache = new LinkedHashMap<Integer, Function>() {
@Override
protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
return this.size() > cacheSize;
}
};
}
Expand All @@ -123,6 +134,7 @@ protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
}
else {
compiled = null;
functionCache = null;
}

nodeFactories.add(new CollectionPointerFactory());
Expand Down Expand Up @@ -765,16 +777,37 @@ public NodePointer getVariablePointer(QName name) {
* @return Function
*/
public Function getFunction(QName functionName, Object[] parameters) {
Function func = null;
int hashParameters;
if (parameters == null) {
hashParameters = 0;
}
else
{
List<Object> paramList = Arrays.asList(parameters);
List<Class> classList = paramList.stream().map(p -> p.getClass()).collect(Collectors.toList());
hashParameters = Arrays.hashCode(classList.toArray());
}
Integer functionHash = Integer.valueOf(Objects.hash(functionName, hashParameters));
if (CACHE_ENABLED) {
func = functionCache.get(functionHash);
if (func != null) {
return func;
}
}

String namespace = functionName.getPrefix();
String name = functionName.getName();
JXPathContext funcCtx = this;
Function func = null;
Functions funcs;
while (funcCtx != null) {
funcs = funcCtx.getFunctions();
if (funcs != null) {
func = funcs.getFunction(namespace, name, parameters);
if (func != null) {
if (CACHE_ENABLED) {
functionCache.put(functionHash, func);
}
return func;
}
}
Expand Down

0 comments on commit 1f34da9

Please sign in to comment.