changeset 478:db430bd9e0e0

Implemented a WstColumnValue cache to speed up inserting WST files into database. flys-backend/trunk@1734 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 20 Apr 2011 07:21:03 +0000 (2011-04-20)
parents 0addc2663a4d
children f9653fc8ef7b
files flys-backend/ChangeLog flys-backend/src/main/java/de/intevation/flys/importer/ImportWst.java flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java flys-backend/src/main/java/de/intevation/flys/importer/WstColumnValueKey.java
diffstat 5 files changed, 162 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/flys-backend/ChangeLog	Mon Apr 18 17:01:00 2011 +0000
+++ b/flys-backend/ChangeLog	Wed Apr 20 07:21:03 2011 +0000
@@ -1,3 +1,23 @@
+2011-04-20  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/WstColumnValueKey.java:
+	  New. This class is used as distinct key of a WstColumnValue - e.g. as
+	  key in a map.
+
+	* src/main/java/de/intevation/flys/importer/ImportWst.java: A
+	  WstColumnValue cache is build up while initialization. This cache
+	  contains all WstColumnValues that exist in the database.
+
+	* src/main/java/de/intevation/flys/importer/ImportWstColumn.java: New
+	  constructor that takes the WstColumnValues cache. It is used to
+	  initialize new ImportWstColumnValue objects.
+
+	* src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java:
+	  Speedup: A ImportWstColumnValue has a WstColumnValues cache that
+	  contains all WstColumnValues existing in the database. This makes it
+	  unnecessary to call an sql statement for each WstColumnValue to
+	  determine its existence in the database.
+
 2011-04-18	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* doc/schema/postgresql.sql, doc/schema/postgresql-cleanup.sql:
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportWst.java	Mon Apr 18 17:01:00 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWst.java	Wed Apr 20 07:21:03 2011 +0000
@@ -1,17 +1,26 @@
 package de.intevation.flys.importer;
 
 import de.intevation.flys.model.Wst;
+import de.intevation.flys.model.WstColumnValue;
 import de.intevation.flys.model.River;
 
+import de.intevation.flys.backend.SessionFactoryProvider;
+
+import org.apache.log4j.Logger;
+
 import org.hibernate.Session;
+import org.hibernate.SessionFactory;
 import org.hibernate.Query;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.ArrayList;
 
 public class ImportWst
 {
+    private static Logger logger = Logger.getLogger(ImportWst.class);
+
     protected String description;
 
     protected Integer kind;
@@ -19,11 +28,16 @@
     //protected Map<String, ImportWstColumn> columns;
     protected List<ImportWstColumn> columns;
 
+    protected Map<WstColumnValueKey, WstColumnValue> wstCache;
+
     protected Wst peer;
 
     public ImportWst() {
         kind = 0;
         columns = new ArrayList<ImportWstColumn>();
+
+        // This cache is used to avoid db queries for each WstColumnValue later
+        wstCache = getWstColumnValueCache();
     }
 
     public ImportWst(String description) {
@@ -41,7 +55,7 @@
 
     public void setNumberColumns(int numColumns) {
         for (int i = 0; i < numColumns; ++i) {
-            columns.add(new ImportWstColumn(this, null, null, i));
+            columns.add(new ImportWstColumn(this, null, null, i, wstCache));
         }
     }
 
@@ -61,6 +75,40 @@
         }
     }
 
+
+    public Map<WstColumnValueKey, WstColumnValue> getWstColumnValueCache() {
+        SessionFactory sessionFactory =
+            SessionFactoryProvider.createSessionFactory();
+
+        Session session = sessionFactory.openSession();
+
+        Importer.sessionHolder.set(session);
+
+        try {
+            Query query = session.createQuery("from WstColumnValue");
+
+            List<WstColumnValue> values = query.list();
+            Map<WstColumnValueKey, WstColumnValue> cache =
+                new HashMap<WstColumnValueKey, WstColumnValue>();
+
+            for (WstColumnValue value: values) {
+                cache.put(
+                    new WstColumnValueKey(value),
+                    value);
+            }
+
+            logger.info("++++++++++++++++++++++++++++++++++++++++++++++++++++");
+            logger.info(cache.size() + " WstColumnValue objects in WST cache.");
+            logger.info("++++++++++++++++++++++++++++++++++++++++++++++++++++");
+
+            return cache;
+        }
+        finally {
+            session.close();
+            Importer.sessionHolder.remove();
+        }
+    }
+
     public Wst getPeer(River river) {
         if (peer == null) {
             Session session = Importer.sessionHolder.get();
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java	Mon Apr 18 17:01:00 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java	Wed Apr 20 07:21:03 2011 +0000
@@ -2,6 +2,7 @@
 
 import de.intevation.flys.model.Wst;
 import de.intevation.flys.model.WstColumn;
+import de.intevation.flys.model.WstColumnValue;
 import de.intevation.flys.model.River;
 
 import org.hibernate.Session;
@@ -9,6 +10,7 @@
 
 import java.util.List;
 import java.util.ArrayList;
+import java.util.Map;
 
 import java.math.BigDecimal;
 
@@ -22,6 +24,8 @@
     protected List<ImportWstColumnQRange> columnQRanges;
     protected List<ImportWstColumnValue>  columnValues;
 
+    protected Map<WstColumnValueKey, WstColumnValue> wstCache;
+
     protected WstColumn peer;
 
     public ImportWstColumn() {
@@ -33,13 +37,15 @@
         ImportWst wst,
         String    name,
         String    description,
-        Integer   position
+        Integer   position,
+        Map<WstColumnValueKey, WstColumnValue> wstCache
     ) {
         this();
         this.wst         = wst;
         this.name        = name;
         this.description = description;
         this.position    = position;
+        this.wstCache    = wstCache;
     }
 
     public ImportWst getWst() {
@@ -76,7 +82,7 @@
 
     public void addColumnValue(BigDecimal position, BigDecimal w) {
         columnValues.add(
-            new ImportWstColumnValue(this, position, w));
+            new ImportWstColumnValue(this, position, w, wstCache));
     }
 
     public void addColumnQRange(ImportWstQRange columnQRange) {
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java	Mon Apr 18 17:01:00 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumnValue.java	Wed Apr 20 07:21:03 2011 +0000
@@ -6,17 +6,23 @@
 
 import java.math.BigDecimal;
 
+import org.apache.log4j.Logger;
+
 import org.hibernate.Session;
-import org.hibernate.Query;
 
-import java.util.List;
+import java.util.Map;
+
 
 public class ImportWstColumnValue
 {
+    protected Logger logger = Logger.getLogger(ImportWstColumnValue.class);
+
     protected BigDecimal      position;
     protected BigDecimal      w;
     protected ImportWstColumn wstColumn;
 
+    protected Map<WstColumnValueKey, WstColumnValue> cache;
+
     protected WstColumnValue  peer;
 
     public ImportWstColumnValue() {
@@ -25,11 +31,13 @@
     public ImportWstColumnValue(
         ImportWstColumn wstColumn,
         BigDecimal      position,
-        BigDecimal      w
+        BigDecimal      w,
+        Map<WstColumnValueKey, WstColumnValue> cache
     ) {
         this.wstColumn = wstColumn;
         this.position  = position;
         this.w         = w;
+        this.cache     = cache;
     }
 
     public BigDecimal getPosition() {
@@ -59,22 +67,25 @@
     public WstColumnValue getPeer(River river) {
         if (peer == null) {
             WstColumn c = wstColumn.getPeer(river);
+
+            // check the cache before we fire a db query
+            WstColumnValue value = cache.get(new WstColumnValueKey(
+                c.getId(),
+                position.doubleValue(),
+                w.doubleValue()));
+
+            if (value != null) {
+                peer = value;
+                return peer;
+            }
+
             Session session = Importer.sessionHolder.get();
-            Query query = session.createQuery(
-                "from WstColumnValue where " +
-                "wstColumn=:c and position=:p and w=:w");
-            query.setParameter("c", c);
-            query.setParameter("p", position);
-            query.setParameter("w", w);
-            List<WstColumnValue> values = query.list();
-            if (values.isEmpty()) {
-                peer = new WstColumnValue(c, position, w);
-                session.save(peer);
-            }
-            else {
-                peer = values.get(0);
-            }
+            peer = new WstColumnValue(c, position, w);
+            session.save(peer);
+
+            cache.put(new WstColumnValueKey(peer), peer);
         }
+
         return peer;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/WstColumnValueKey.java	Wed Apr 20 07:21:03 2011 +0000
@@ -0,0 +1,56 @@
+package de.intevation.flys.importer;
+
+import de.intevation.flys.model.WstColumnValue;
+
+
+public class WstColumnValueKey {
+
+    protected int    wstColumnId;
+    protected double position;
+    protected double w;
+
+
+    public WstColumnValueKey(WstColumnValue value) {
+        this.wstColumnId = value.getWstColumn().getId();
+        this.position    = value.getPosition().doubleValue();
+        this.w           = value.getW().doubleValue();
+    }
+
+
+    public WstColumnValueKey(int wstColumnId, double position, double w) {
+        this.wstColumnId = wstColumnId;
+        this.position    = position;
+        this.w           = w;
+    }
+
+
+    public int hashCode() {
+        int a = new Integer(wstColumnId).hashCode();
+        int b = new Double(position).hashCode();
+        int c = new Double(w).hashCode();
+
+        return (a ^ (b << 3) ^ (c << 6));
+    }
+
+
+    public boolean equals(Object obj) {
+        if (!(obj instanceof WstColumnValueKey)) {
+            return false;
+        }
+
+        WstColumnValueKey other = (WstColumnValueKey) obj;
+
+        if (this.wstColumnId != other.wstColumnId) {
+            return false;
+        }
+        else if (this.position != other.position) {
+            return false;
+        }
+        else if (this.w != other.w) {
+            return false;
+        }
+
+        return true;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org