changeset 632:07640ab913fd

First part of storing qs in ranges flys-artifacts/trunk@1997 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 24 May 2011 14:46:45 +0000
parents a9af60c84dca
children d08f77e7f7e8
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableCacheKey.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory2.java
diffstat 6 files changed, 287 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue May 24 13:24:24 2011 +0000
+++ b/flys-artifacts/ChangeLog	Tue May 24 14:46:45 2011 +0000
@@ -1,3 +1,20 @@
+2011-05-24	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java:
+	  Moved cache name to WstValueTableCacheKey. Do not cache null references.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTableCacheKey.java:
+	  Moved cache name into this class.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java:
+	  Store QRangeTree for each column of value table. TODO: Use them!
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory2.java:
+	  Intended as a replacement for WstValueTableFactory, but is work in progress.
+
+	* src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java: Fixed
+	  index errors and added methods to dump as graphviz graph.
+
 2011-05-24  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/states/WQSelect.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Tue May 24 13:24:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Tue May 24 14:46:45 2011 +0000
@@ -105,7 +105,7 @@
     public QRangeTree() {
     }
 
-    /** wstQRanges need to sorted by range.a */
+    /** wstQRanges need to be sorted by range.a */
     public QRangeTree(List<WstQRange> wstQRanges) {
 
         if (wstQRanges.isEmpty()) {
@@ -124,23 +124,52 @@
                 wstQRange.getQ().doubleValue());
         }
 
+        root = wireTree(nodes);
+    }
+
+    public QRangeTree(List<Object []> qRanges, int start, int stop) {
+
+        if (stop <= start) {
+            return;
+        }
+
+        Node [] nodes = new Node[stop-start];
+        for (int i = 0; i < nodes.length; ++i) {
+            Object [] qRange = qRanges.get(i + start);
+            Double q = (Double)qRange[1];
+            Double a = (Double)qRange[2];
+            Double b = (Double)qRange[3];
+
+            nodes[i] = new Node(
+                a != null ? a.doubleValue() : -Double.MAX_VALUE,
+                b != null ? b.doubleValue() :  Double.MAX_VALUE,
+                q.doubleValue());
+        }
+
+        root = wireTree(nodes);
+    }
+
+    protected static Node wireTree(Node [] nodes) {
         for (int i = 0; i < nodes.length; ++i) {
             Node node = nodes[i];
             if (i > 0             ) node.prev = nodes[i-1];
             if (i < nodes.length-1) node.next = nodes[i+1];
         }
 
-        root = buildTree(nodes, 0, nodes.length-1);
+        return buildTree(nodes, 0, nodes.length-1);
     }
 
     protected static Node buildTree(Node [] nodes, int lo, int hi) {
+
+        if (lo > hi) {
+            return null;
+        }
+
         int mid = (lo + hi) >> 1;
         Node parent = nodes[mid];
 
-        if (hi > lo) {
-            parent.left  = buildTree(nodes, lo, mid-1);
-            parent.right = buildTree(nodes, mid+1, hi);
-        }
+        parent.left  = buildTree(nodes, lo, mid-1);
+        parent.right = buildTree(nodes, mid+1, hi);
 
         return parent;
     }
@@ -148,5 +177,40 @@
     public double findQ(double pos) {
         return root != null ? root.findQ(pos) : Double.NaN;
     }
+
+    private static final String name(Object o) {
+        return String.valueOf(System.identityHashCode(o) & 0xffffffffL);
+    }
+
+    public String toGraph() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("subgraph c");
+        sb.append(name(this));
+        sb.append(" {\n");
+        if (root != null) {
+            java.util.Stack<Node> stack = new java.util.Stack<Node>();
+            stack.push(root);
+            while (!stack.empty()) {
+                Node current = stack.pop();
+                String name = "n" + name(current);
+                sb.append(name);
+                sb.append(" [label=\"");
+                sb.append(current.a).append(", ").append(current.b);
+                sb.append(": ").append(current.q).append("\"]\n");
+                if (current.left != null) {
+                    String leftName = name(current.left);
+                    sb.append(name).append(" -- n").append(leftName).append("\n");
+                    stack.push(current.left);
+                }
+                if (current.right != null) {
+                    String rightName = name(current.right);
+                    sb.append(name).append(" -- n").append(rightName).append("\n");
+                    stack.push(current.right);
+                }
+            }
+        }
+        sb.append("}\n");
+        return sb.toString();
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Tue May 24 13:24:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Tue May 24 14:46:45 2011 +0000
@@ -30,6 +30,8 @@
     {
         protected String name;
 
+        protected QRangeTree qRangeTree;
+
         public Column() {
         }
 
@@ -44,6 +46,14 @@
         public void setName(String name) {
             this.name = name;
         }
+
+        public QRangeTree getQRangeTree() {
+            return qRangeTree;
+        }
+
+        public void setQRangeTree(QRangeTree qRangeTree) {
+            this.qRangeTree = qRangeTree;
+        }
     }
     // class Column
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableCacheKey.java	Tue May 24 13:24:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableCacheKey.java	Tue May 24 14:46:45 2011 +0000
@@ -5,6 +5,8 @@
 public final class WstValueTableCacheKey
 implements         Serializable
 {
+    public static final String CACHE_NAME = "wst-value-table";
+
     private int riverId;
     private int kind;
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java	Tue May 24 13:24:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java	Tue May 24 14:46:45 2011 +0000
@@ -28,8 +28,6 @@
 {
     private static Logger log = Logger.getLogger(WstValueTableFactory.class);
 
-    public static final String CACHE_NAME = "wst-value-table";
-
     // TODO: put this into a property file
     public static final String SQL_POS_WQ = 
         "SELECT position, w, q, column_pos" +
@@ -45,7 +43,7 @@
 
     public static WstValueTable getTable(River river, int kind) {
 
-        Cache cache = CacheFactory.getCache(CACHE_NAME);
+        Cache cache = CacheFactory.getCache(WstValueTableCacheKey.CACHE_NAME);
 
         WstValueTableCacheKey cacheKey;
 
@@ -63,7 +61,7 @@
 
         WstValueTable valueTable = getTableUncached(river, kind);
 
-        if (cacheKey != null) {
+        if (valueTable != null && cacheKey != null) {
             log.debug("store wst value table in cache");
             Element element = new Element(cacheKey, valueTable);
             cache.put(element);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory2.java	Tue May 24 14:46:45 2011 +0000
@@ -0,0 +1,186 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.List;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import de.intevation.flys.artifacts.cache.CacheFactory;
+
+import de.intevation.flys.backend.SessionHolder;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.model.River;
+import de.intevation.flys.model.Wst;
+
+import org.hibernate.Session;
+import org.hibernate.Query;
+import org.hibernate.SQLQuery;
+
+import org.hibernate.type.StandardBasicTypes;
+
+public class WstValueTableFactory2
+{
+    private static Logger log = Logger.getLogger(WstValueTableFactory2.class);
+
+    public static final int DEFAULT_KIND = 0;
+
+    // TODO: put this into a property file
+
+    public static final String HQL_WST =
+        "from Wst where river=:river and kind=:kind";
+
+    public static final String SQL_SELECT_NAMES_POS =
+        "SELECT position, name FROM wst_columns " +
+        "WHERE wst_id = :wst_id ORDER BY position";
+
+    public static final String SQL_SELECT_QS =
+        "SELECT column_pos, q, a, b FROM wst_q_values " +
+        "WHERE wst_id = :wst_id";
+
+    public static final String SQL_SELECT_WS =
+        "SELECT km, w, column_pos FROM wst_w_values " +
+        "WHERE wst_id = :wst_id";
+
+    private WstValueTableFactory2() {
+    }
+
+    public static WstValueTable getTable(River river) {
+        return getTable(river, DEFAULT_KIND);
+    }
+
+    public static WstValueTable getTable(River river, int kind) {
+
+        Cache cache = CacheFactory.getCache(WstValueTableCacheKey.CACHE_NAME);
+
+        WstValueTableCacheKey cacheKey;
+
+        if (cache != null) {
+            cacheKey = new WstValueTableCacheKey(river.getId(), kind);
+            Element element = cache.get(cacheKey);
+            if (element != null) {
+                log.debug("got wst value table from cache");
+                return (WstValueTable)element.getValue();
+            }
+        }
+        else {
+            cacheKey = null;
+        }
+
+        WstValueTable valueTable = getTableUncached(river, kind);
+
+        if (valueTable != null && cacheKey != null) {
+            log.debug("store wst value table in cache");
+            Element element = new Element(cacheKey, valueTable);
+            cache.put(element);
+        }
+
+        return valueTable;
+    }
+
+    public static WstValueTable getTableUncached(River river) {
+        return getTableUncached(river, DEFAULT_KIND);
+    }
+
+    public static WstValueTable getTableUncached(River river, int kind) {
+
+        Session session = SessionHolder.HOLDER.get();
+
+        Query query = session.createQuery(HQL_WST);
+        query.setParameter("river", river);
+        query.setInteger("kind",    kind);
+
+        List<Wst> wsts = query.list();
+
+        if (wsts.isEmpty()) {
+            return null;
+        }
+
+        Wst wst = wsts.get(0);
+
+        SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_NAMES_POS)
+            .addScalar("position",   StandardBasicTypes.INTEGER)
+            .addScalar("name",       StandardBasicTypes.STRING);
+
+        sqlQuery.setInteger("wst_id", wst.getId());
+
+        List<Object []> columnNames = sqlQuery.list();
+
+        WstValueTable.Column [] columns =
+            new WstValueTable.Column[columnNames.size()];
+
+        for (int i = 0; i < columns.length; ++i) {
+            columns[i] = new WstValueTable.Column(
+                (String)columnNames.get(i)[1]);
+        }
+
+        sqlQuery = session.createSQLQuery(SQL_SELECT_QS)
+            .addScalar("column_pos", StandardBasicTypes.INTEGER)
+            .addScalar("q",          StandardBasicTypes.DOUBLE)
+            .addScalar("a",          StandardBasicTypes.DOUBLE)
+            .addScalar("b",          StandardBasicTypes.DOUBLE);
+
+        sqlQuery.setInteger("wst_id", wst.getId());
+
+        Integer lastColumn = null;
+
+        List<Object []> qRanges = sqlQuery.list();
+        int start = -1;
+
+        int Q = qRanges.size();
+
+        for (int i = 0; i < Q; ++i) {
+            Object [] qRange = qRanges.get(i);
+            Integer columnId = (Integer)qRange[0];
+            if (lastColumn == null) {
+                lastColumn = columnId;
+                start = i;
+            }
+            else if (!lastColumn.equals(columnId)) {
+                QRangeTree qRangeTree = new QRangeTree(qRanges, start, i);
+                columns[lastColumn].setQRangeTree(qRangeTree);
+                lastColumn = columnId;
+                start = i;
+            }
+        }
+
+        if (start != -1) {
+            QRangeTree qRangeTree = new QRangeTree(qRanges, start, Q);
+            columns[lastColumn].setQRangeTree(qRangeTree);
+        }
+
+        /* This is debug code to visualize the q ranges trees 
+
+        java.io.PrintWriter out = null;
+        try {
+            out = new java.io.PrintWriter(
+                new java.io.FileWriter(
+                    "/tmp/qranges" + System.currentTimeMillis() + ".dot"));
+
+            out.println("graph \"Q ranges trees\" {");
+
+            for (int i = 0; i < columns.length; ++i) {
+                QRangeTree tree = columns[i].getQRangeTree();
+                out.println(tree.toGraph());
+            }
+
+            out.println("}");
+
+            out.flush();
+        }
+        catch (java.io.IOException ioe) {
+            log.error(ioe);
+        }
+        finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+        */
+        // TODO: Implement me!
+
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org