changeset 500:d50cd3a632e0

Importer: Use BigDecimals in hashing to prevent numerical problems. Cache ranges globally, too. flys-backend/trunk@1854 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 08 May 2011 22:41:07 +0000
parents cce054f27dac
children 04d449f7f0c9
files flys-backend/ChangeLog flys-backend/src/main/java/de/intevation/flys/importer/IdValueKey.java flys-backend/src/main/java/de/intevation/flys/importer/ImportDischargeTableValue.java flys-backend/src/main/java/de/intevation/flys/importer/ImportRange.java flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java flys-backend/src/main/java/de/intevation/flys/importer/ImporterSession.java
diffstat 6 files changed, 98 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/flys-backend/ChangeLog	Sun May 08 21:34:43 2011 +0000
+++ b/flys-backend/ChangeLog	Sun May 08 22:41:07 2011 +0000
@@ -1,3 +1,20 @@
+2011-05-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/importer/IdValueKey.java:
+	  Use BigDecimals as representation for the numeric components
+	  which prevents running into unique constraint problems
+	  caused by imprecision.
+
+	* src/main/java/de/intevation/flys/importer/ImportRange.java,
+	  src/main/java/de/intevation/flys/importer/ImporterSession.java:
+	  Ranges are now cached globally, too.
+
+	* src/main/java/de/intevation/flys/importer/ImportWstColumn.java:
+	  Improved logging.
+
+	* src/main/java/de/intevation/flys/importer/ImportDischargeTableValue.java:
+	  Removed superfluous imports.
+
 2011-05-08	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/importer/StaFileParser.java:
--- a/flys-backend/src/main/java/de/intevation/flys/importer/IdValueKey.java	Sun May 08 21:34:43 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/IdValueKey.java	Sun May 08 22:41:07 2011 +0000
@@ -2,45 +2,48 @@
 
 import de.intevation.flys.model.WstColumnValue;
 import de.intevation.flys.model.DischargeTableValue;
+import de.intevation.flys.model.Range;
 
+import java.math.BigDecimal;
 
 public class IdValueKey {
 
-    protected int    id;
-    protected double a;
-    protected double b;
+    protected int        id;
+    protected BigDecimal a;
+    protected BigDecimal b;
 
 
     public IdValueKey(WstColumnValue value) {
         this.id = value.getWstColumn().getId();
-        this.a  = value.getPosition().doubleValue();
-        this.b  = value.getW().doubleValue();
+        this.a  = value.getPosition();
+        this.b  = value.getW();
     }
 
     public IdValueKey(DischargeTableValue value) {
         this.id = value.getDischargeTable().getId();
-        this.a  = value.getQ().doubleValue();
-        this.b  = value.getW().doubleValue();
+        this.a  = value.getQ();
+        this.b  = value.getW();
+    }
+
+    public IdValueKey(Range value) {
+        this.id = value.getRiver().getId();
+        this.a  = value.getA();
+        this.b  = value.getB();
     }
 
 
-    public IdValueKey(int id, double a, double b) {
+    public IdValueKey(int id, BigDecimal a, BigDecimal b) {
         this.id = id;
         this.a  = a;
         this.b  = b;
     }
 
-    private static final int hashDouble(double d) {
-        long v = Double.doubleToLongBits(d);
-        return (int)(v^(v>>>32));
+    private static final int hashCode(BigDecimal d) {
+        return d != null ? d.hashCode() : 0;
     }
 
     public int hashCode() {
-        int a = id;
-        int b = hashDouble(a);
-        int c = hashDouble(b);
-
-        return (a | (b << 10) | (c << 20));
+        return id | (hashCode(a) << 10) | (hashCode(b) << 20);
     }
 
 
@@ -51,9 +54,13 @@
 
         IdValueKey other = (IdValueKey) obj;
 
-        return id == other.id
-            && a  == other.a
-            && b  == other.b;
+        return !((id != other.id) 
+            || (a == null && other.a != null) 
+            || (a != null && other.a == null) 
+            || (a != null && !a.equals(other)) 
+            || (b == null && other.b != null) 
+            || (b != null && other.b == null) 
+            || (b != null && !b.equals(other)));
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportDischargeTableValue.java	Sun May 08 21:34:43 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportDischargeTableValue.java	Sun May 08 22:41:07 2011 +0000
@@ -1,10 +1,6 @@
 package de.intevation.flys.importer;
 
 import java.math.BigDecimal;
-import java.util.List;
-
-import org.hibernate.Session;
-import org.hibernate.Query;
 
 import de.intevation.flys.model.DischargeTable;
 import de.intevation.flys.model.DischargeTableValue;
@@ -12,24 +8,18 @@
 
 public class ImportDischargeTableValue
 {
-    private Integer id;
-
     private BigDecimal q;
     private BigDecimal w;
 
-    private ImportDischargeTable dischargeTable;
-
     private DischargeTableValue peer;
 
-
     public ImportDischargeTableValue() {
     }
 
 
     public ImportDischargeTableValue(BigDecimal q, BigDecimal w) {
-        this.dischargeTable = dischargeTable;
-        this.q              = q;
-        this.w              = w;
+        this.q = q;
+        this.w = w;
     }
 
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportRange.java	Sun May 08 21:34:43 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportRange.java	Sun May 08 22:41:07 2011 +0000
@@ -3,11 +3,6 @@
 import de.intevation.flys.model.Range;
 import de.intevation.flys.model.River;
 
-import org.hibernate.Session;
-import org.hibernate.Query;
-
-import java.util.List;
-
 import java.math.BigDecimal;
 
 import org.apache.log4j.Logger;
@@ -67,21 +62,7 @@
 
     public Range getPeer(River river) {
         if (peer == null) {
-            Session session = ImporterSession.getInstance().getDatabaseSession();
-            Query query = session.createQuery(
-                "from Range where a=:a and b=:b and river=:river");
-            query.setParameter("a", a);
-            query.setParameter("b", b);
-            query.setParameter("river", river);
-            //log.debug("a: " + a + " b: " + b + " river.id: " + river.getId());
-            List<Range> ranges = query.list();
-            if (ranges.isEmpty()) {
-                peer = new Range(a, b, river);
-                session.save(peer);
-            }
-            else {
-                peer = ranges.get(0);
-            }
+            peer = ImporterSession.getInstance().getRange(river, a, b);
         }
         return peer;
     }
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java	Sun May 08 21:34:43 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportWstColumn.java	Sun May 08 22:41:07 2011 +0000
@@ -89,7 +89,7 @@
     }
 
     public void storeDependencies(River river) {
-        log.info("store column '" + description + "'");
+        log.info("store column '" + name + "'");
         WstColumn column = getPeer(river);
         log.info("store q ranges");
         for (ImportWstColumnQRange columnQRange: columnQRanges) {
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImporterSession.java	Sun May 08 21:34:43 2011 +0000
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImporterSession.java	Sun May 08 22:41:07 2011 +0000
@@ -17,9 +17,15 @@
 import de.intevation.flys.model.WstColumn;
 import de.intevation.flys.model.DischargeTableValue;
 import de.intevation.flys.model.DischargeTable;
+import de.intevation.flys.model.Range;
+import de.intevation.flys.model.River;
+
+import org.apache.log4j.Logger;
 
 public class ImporterSession
 {
+    private static Logger log = Logger.getLogger(ImporterSession.class);
+
     private static final ThreadLocal<ImporterSession> SESSION =
         new ThreadLocal<ImporterSession>() {
             @Override
@@ -34,6 +40,8 @@
 
     protected Map<IdValueKey, DischargeTableValue> dischargeTableValues;
 
+    protected Map<IdValueKey, Range> ranges;
+
     public static ImporterSession getInstance() {
         return SESSION.get();
     }
@@ -58,10 +66,7 @@
             loadWstColumnValues();
         }
 
-        IdValueKey key = new IdValueKey(
-            column.getId(),
-            position.doubleValue(),
-            w.doubleValue());
+        IdValueKey key = new IdValueKey(column.getId(), position, w);
 
         WstColumnValue wcv = wstColumnValues.get(key);
 
@@ -79,6 +84,7 @@
     }
 
     protected void loadWstColumnValues() {
+        log.info("load wst column values");
         wstColumnValues = new HashMap<IdValueKey, WstColumnValue>();
 
         Query query = databaseSession.createQuery("from WstColumnValue");
@@ -87,6 +93,7 @@
             WstColumnValue wcv = (WstColumnValue)iter.next();
             wstColumnValues.put(new IdValueKey(wcv), wcv);
         }
+        log.info(wstColumnValues.size() + " values loaded");
     }
 
     public DischargeTableValue getDischargeTableValue(
@@ -98,10 +105,7 @@
             loadDischargeTableValues();
         }
 
-        IdValueKey key = new IdValueKey(
-            table.getId(),
-            q.doubleValue(),
-            w.doubleValue());
+        IdValueKey key = new IdValueKey(table.getId(), q, w);
 
         DischargeTableValue dtv = dischargeTableValues.get(key);
 
@@ -119,6 +123,8 @@
     }
 
     protected void loadDischargeTableValues() {
+        log.info("load discharge table values");
+
         dischargeTableValues = new HashMap<IdValueKey, DischargeTableValue>();
 
         Query query = databaseSession.createQuery("from DischargeTableValue");
@@ -127,6 +133,43 @@
             DischargeTableValue dtv = (DischargeTableValue)iter.next();
             dischargeTableValues.put(new IdValueKey(dtv), dtv);
         }
+        log.info(dischargeTableValues.size() + " values loaded");
+    }
+
+    public Range getRange(River river, BigDecimal a, BigDecimal b) {
+
+        if (ranges == null) {
+            loadRanges();
+        }
+
+        IdValueKey key = new IdValueKey(river.getId(), a, b);
+
+        Range range = ranges.get(key);
+
+        if (ranges != null) {
+            return range;
+        }
+
+        range = new Range(a, b, river);
+
+        databaseSession.save(range);
+
+        ranges.put(key, range);
+
+        return range;
+    }
+
+    protected void loadRanges() {
+        log.info("load ranges");
+        ranges = new HashMap<IdValueKey, Range>();
+
+        Query query = databaseSession.createQuery("from Range");
+
+        for (Iterator iter = query.iterate(); iter.hasNext();) {
+            Range range = (Range)iter.next();
+            ranges.put(new IdValueKey(range), range);
+        }
+        log.info(ranges.size() + " values loaded");
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org