From: James Ahlborn Date: Thu, 15 Dec 2016 20:08:06 +0000 (+0000) Subject: add result caching for pure expressions X-Git-Tag: jackcess-2.2.0~24^2~56 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c42fa3b60a6e5de6bef10fabe56bd53cac49b57a;p=jackcess.git add result caching for pure expressions git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1071 f203690c-595d-4dc9-a70b-905162fa7fd2 --- diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java b/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java index c5accc5..99d695f 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java @@ -27,4 +27,6 @@ public interface Expression public Boolean evalCondition(RowContext ctx); public String toDebugString(); + + public boolean isPure(); } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java index f8f6e12..263e7ff 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java @@ -420,7 +420,13 @@ public class Expressionator return null; } - return parseExpression(new TokBuf(exprType, tokens, context), false); + Expr expr = parseExpression(new TokBuf(exprType, tokens, context), false); + if(expr.isPure()) { + // for now, just cache at top-level for speed (could in theory cache + // intermediate values?) + expr = new MemoizedPureExpression(expr); + } + return expr; } private static List trimSpaces(List tokens) { @@ -1847,4 +1853,42 @@ public class Expressionator _endRangeExpr.toString(sb, isDebug); } } + + /** + * Wrapper for a pure Expr which caches the result of evaluation. + */ + private static final class MemoizedPureExpression extends Expr + { + private final Expr _expr; + private Value _val; + + private MemoizedPureExpression(Expr expr) { + _expr = expr; + } + + @Override + protected Value eval(RowContext ctx) { + if(_val == null) { + // since expr is pure, row context should not be used + _val = _expr.eval(null); + } + return _val; + } + + @Override + public boolean isPure() { + return true; + } + + @Override + protected void toString(StringBuilder sb, boolean isDebug) { + // don't display this class in debug string + _expr.toString(sb, isDebug); + } + + @Override + protected void toExprString(StringBuilder sb, boolean isDebug) { + throw new UnsupportedOperationException(); + } + } }