diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/CompiledStatement.java @ 972:0c8aca463bd4

Added caching support for the static part of the datacage. flys-artifacts/trunk@2398 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 22 Jul 2011 16:55:36 +0000
parents 2c8fc60125b9
children c30ada285d45
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/CompiledStatement.java	Fri Jul 22 11:18:00 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/meta/CompiledStatement.java	Fri Jul 22 16:55:36 2011 +0000
@@ -5,7 +5,7 @@
 
 import java.util.List;
 import java.util.Map;
-import java.util.HashMap;
+import java.util.TreeMap;
 import java.util.ArrayList;
 
 import java.sql.PreparedStatement;
@@ -13,8 +13,16 @@
 import java.sql.Connection;
 import java.sql.ResultSet;
 
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import de.intevation.flys.artifacts.cache.CacheFactory;
+
 public class CompiledStatement
 {
+    public static final String DATACAGE_DB_CACHE =
+        "datacage.db";
+
     public static final Pattern VAR =
         Pattern.compile("\\$\\{([a-zA-Z0-9_-]+)\\}");
 
@@ -25,12 +33,15 @@
 
     protected PreparedStatement preparedStatement;
 
+    protected int numVars;
+
     public CompiledStatement() {
     }
 
     public CompiledStatement(String original) {
         this.original = original;
-        positions = new HashMap<String, List<Integer>>();
+        // TreeMap to ensure order
+        positions = new TreeMap<String, List<Integer>>();
         compile();
     }
 
@@ -40,7 +51,7 @@
 
         Matcher m = VAR.matcher(original);
 
-        int index = 1;
+        int index = 0;
 
         while (m.find()) {
             String key = m.group(1);
@@ -56,6 +67,8 @@
 
         m.appendTail(sb);
 
+        numVars = index;
+
         statement = sb.toString();
     }
 
@@ -63,7 +76,65 @@
         return statement;
     }
 
-    public ResultData execute(Connection connection, StackFrames frames)
+    protected ResultData executeCached(
+        Cache       cache,
+        Connection  connection,
+        StackFrames frames
+    )
+    throws SQLException
+    {
+        Object [] values = new Object[numVars];
+
+        StringBuilder sb = new StringBuilder(original);
+
+        for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) {
+            String key   = entry.getKey();
+            Object value = frames.get(key);
+            sb.append(';').append(key).append(':').append(value);
+            for (Integer index: entry.getValue()) {
+                values[index] = value;
+            }
+        }
+
+        // XXX: Maybe too many collisions?
+        // String key = original + Arrays.hashCode(values);
+        String key = sb.toString();
+
+        Element element = cache.get(key);
+
+        if (element != null) {
+            return (ResultData)element.getValue();
+        }
+
+        if (preparedStatement == null) {
+            preparedStatement = connection.prepareStatement(statement);
+        }
+
+        for (int i = 0; i < values.length; ++i) {
+            preparedStatement.setObject(i+1, values[i]);
+        }
+
+        ResultData data;
+
+        ResultSet result = preparedStatement.executeQuery();
+        try {
+            data = new ResultData(preparedStatement.getMetaData())
+                .addAll(result);
+        }
+        finally {
+            result.close();
+        }
+
+        element = new Element(key, data);
+        cache.put(element);
+
+        return data;
+    }
+
+    protected ResultData executeUncached(
+        Connection  connection,
+        StackFrames frames
+    ) 
     throws SQLException
     {
         if (preparedStatement == null) {
@@ -73,7 +144,7 @@
         for (Map.Entry<String, List<Integer>> entry: positions.entrySet()) {
             Object value = frames.get(entry.getKey());
             for (Integer index: entry.getValue()) {
-                preparedStatement.setObject(index, value);
+                preparedStatement.setObject(index+1, value);
             }
         }
 
@@ -87,6 +158,16 @@
         }
     }
 
+    public ResultData execute(Connection connection, StackFrames frames)
+    throws SQLException
+    {
+        Cache cache = CacheFactory.getCache(DATACAGE_DB_CACHE);
+
+        return cache != null
+            ? executeCached(cache, connection, frames)
+            : executeUncached(connection, frames);
+    }
+
     public void close() {
         if (preparedStatement != null) {
             try {

http://dive4elements.wald.intevation.org