diff backend/src/main/java/org/dive4elements/river/importer/ImportCrossSectionLine.java @ 8986:392bbcd8a88b

Database inserts accelerated by suppressing unnecessary database queries for new data series
author mschaefer
date Sun, 08 Apr 2018 18:07:06 +0200
parents 36455dfcb788
children
line wrap: on
line diff
--- a/backend/src/main/java/org/dive4elements/river/importer/ImportCrossSectionLine.java	Fri Apr 06 14:13:14 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/ImportCrossSectionLine.java	Sun Apr 08 18:07:06 2018 +0200
@@ -8,18 +8,18 @@
 
 package org.dive4elements.river.importer;
 
-import org.dive4elements.river.model.CrossSection;
-import org.dive4elements.river.model.CrossSectionPoint;
-import org.dive4elements.river.model.CrossSectionLine;
-
-import org.hibernate.Session;
-import org.hibernate.Query;
-
+import java.util.Comparator;
 import java.util.List;
-import java.util.Comparator;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.dive4elements.river.importer.common.StoreMode;
+import org.dive4elements.river.model.CrossSection;
+import org.dive4elements.river.model.CrossSectionLine;
+import org.dive4elements.river.model.CrossSectionPoint;
+import org.hibernate.Query;
+import org.hibernate.Session;
+
 /**
  * A CrossSectionLine (containing points) ready to be transformed into a mapped
  * object and written to db (used in importer).
@@ -27,39 +27,42 @@
 public class ImportCrossSectionLine
 {
     public static final Comparator<CrossSectionPoint> INDEX_CMP =
-        new Comparator<CrossSectionPoint>() {
-            public int compare(CrossSectionPoint a, CrossSectionPoint b) {
-                return a.getColPos().compareTo(b.getColPos());
-            }
-        };
+            new Comparator<CrossSectionPoint>() {
+        @Override
+        public int compare(final CrossSectionPoint a, final CrossSectionPoint b) {
+            return a.getColPos().compareTo(b.getColPos());
+        }
+    };
 
     protected Double km;
     protected ImportCrossSection crossSection;
     protected List<XY> points;
+    protected StoreMode storeMode;
 
     protected CrossSectionLine peer;
 
     public ImportCrossSectionLine() {
     }
 
-    public ImportCrossSectionLine(Double km, List<XY> points) {
+    public ImportCrossSectionLine(final Double km, final List<XY> points) {
         this.km     = km;
         this.points = points;
+        this.storeMode = StoreMode.NONE;
     }
 
     public ImportCrossSection getCrossSection() {
-        return crossSection;
+        return this.crossSection;
     }
 
-    public void setCrossSection(ImportCrossSection crossSection) {
+    public void setCrossSection(final ImportCrossSection crossSection) {
         this.crossSection = crossSection;
     }
 
     public Double getKm() {
-        return km;
+        return this.km;
     }
 
-    public void setKm(Double km) {
+    public void setKm(final Double km) {
         this.km = km;
     }
 
@@ -70,35 +73,37 @@
 
     /** Write a line and its points. */
     protected void storePoints() {
-        CrossSectionLine csl = getPeer();
-
-        Map<CrossSectionPoint, CrossSectionPoint> map =
-            new TreeMap<CrossSectionPoint, CrossSectionPoint>(INDEX_CMP);
+        final CrossSectionLine csl = getPeer();
+        if (this.storeMode == StoreMode.INSERT) {
+            insertPoints();
+            return;
+        }
+        final Map<CrossSectionPoint, CrossSectionPoint> map =
+                new TreeMap<>(INDEX_CMP);
 
         // Build index for faster (index) collision lookup.
-        List<CrossSectionPoint> ps = csl.getPoints();
+        final List<CrossSectionPoint> ps = csl.getPoints();
         if (ps != null) {
-            for (CrossSectionPoint point: ps) {
+            for (final CrossSectionPoint point: ps) {
                 map.put(point, point);
             }
         }
 
-        Session session =
-            ImporterSession.getInstance().getDatabaseSession();
+        final Session session = ImporterSession.getInstance().getDatabaseSession();
 
-        CrossSectionPoint key = new CrossSectionPoint();
+        final CrossSectionPoint key = new CrossSectionPoint();
 
         // Somehow it looks as if even with the map it is still possible that
         // multiple points with same id enter hibernate (and then violate a
         // constraint). -> TODO
-        for (XY xy: points) {
+        for (final XY xy: this.points) {
             key.setColPos(xy.getIndex());
             CrossSectionPoint csp = map.get(key);
             if (csp == null) { // create new
                 csp = new CrossSectionPoint(
-                    csl, key.getColPos(),
-                    Double.valueOf(xy.getX()),
-                    Double.valueOf(xy.getY()));
+                        csl, key.getColPos(),
+                        Double.valueOf(xy.getX()),
+                        Double.valueOf(xy.getY()));
             }
             else { // update old
                 csp.setX(Double.valueOf(xy.getX()));
@@ -108,29 +113,41 @@
         }
     }
 
+    /**
+     * Insert the points of a new line into the database without previously querying the database
+     */
+    private void insertPoints() {
+        final Session session = ImporterSession.getInstance().getDatabaseSession();
+        for (final XY xy : this.points) {
+            session.save(new CrossSectionPoint(getPeer(), xy.getIndex(), xy.getX(), xy.getY()));
+        }
+    }
+
     /** Pull database-mapped object from db, or create (and save) one. */
     public CrossSectionLine getPeer() {
-        if (peer == null) {
-            CrossSection cs = crossSection.getPeer();
-
-            Session session =
-                ImporterSession.getInstance().getDatabaseSession();
-
-            Query query = session.createQuery(
-                "from CrossSectionLine where crossSection=:cs and km=:km");
-            query.setParameter("cs", cs);
-            query.setParameter("km", km);
-
-            List<CrossSectionLine> lines = query.list();
-            if (lines.isEmpty()) {
-                peer = new CrossSectionLine(cs, km);
-                session.save(peer);
+        if (this.peer == null) {
+            final CrossSection cs = this.crossSection.getPeer();
+            final Session session = ImporterSession.getInstance().getDatabaseSession();
+            List<CrossSectionLine> lines;
+            if (this.crossSection.storeMode == StoreMode.INSERT)
+                lines = null;
+            else {
+                final Query query = session.createQuery("from CrossSectionLine where crossSection=:cs and km=:km");
+                query.setParameter("cs", cs);
+                query.setParameter("km", this.km);
+                lines = query.list();
+            }
+            if ((lines == null) || lines.isEmpty()) {
+                this.peer = new CrossSectionLine(cs, this.km);
+                session.save(this.peer);
+                this.storeMode = StoreMode.INSERT;
             }
             else {
-                peer = lines.get(0);
+                this.peer = lines.get(0);
+                this.storeMode = StoreMode.UPDATE;
             }
         }
-        return peer;
+        return this.peer;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org