]> source.dussan.org Git - jackcess.git/commitdiff
add result caching for pure expressions
authorJames Ahlborn <jtahlborn@yahoo.com>
Thu, 15 Dec 2016 20:08:06 +0000 (20:08 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Thu, 15 Dec 2016 20:08:06 +0000 (20:08 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1071 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/expr/Expression.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java

index c5accc5e346dbad30d624608ffde0b16aa848192..99d695f3790a8e4eb45fd8b64ffb76082c6032e2 100644 (file)
@@ -27,4 +27,6 @@ public interface Expression
   public Boolean evalCondition(RowContext ctx);
 
   public String toDebugString();
+
+  public boolean isPure();
 }
index f8f6e12dbfa9efbece1f097fdea75037e52764e8..263e7ff5524867d56ab84b230135c62764cb22cc 100644 (file)
@@ -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<Token> trimSpaces(List<Token> tokens) {
@@ -1847,4 +1853,42 @@ public class Expressionator
       _endRangeExpr.toString(sb, isDebug);
     }
   }
+
+  /**
+   * Wrapper for a <i>pure</i> 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();
+    }
+  }
 }