changeset 2127:0c7847b8e85e

Speed up the join of calculation results and the km annotations. flys-artifacts/trunk@3698 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 17 Jan 2012 18:26:45 +0000
parents d626ae185305
children bf67eb014443
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/LocationProvider.java
diffstat 2 files changed, 73 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue Jan 17 17:05:18 2012 +0000
+++ b/flys-artifacts/ChangeLog	Tue Jan 17 18:26:45 2012 +0000
@@ -1,3 +1,10 @@
+2012-01-17	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/LocationProvider.java:
+	  Cache a TreeMap<km, annotation string> of the annotation values of whole 
+	  rivers. This is _much_ more efficient than firing an HQL/SQL statement for 
+	  each km and caching these results.
+
 2012-01-17	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/FastCrossSectionLine.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/LocationProvider.java	Tue Jan 17 17:05:18 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/LocationProvider.java	Tue Jan 17 18:26:45 2012 +0000
@@ -7,15 +7,39 @@
 
 import de.intevation.flys.model.Annotation;
 import de.intevation.flys.model.Position;
+import de.intevation.flys.model.Range;
 
 import de.intevation.flys.artifacts.cache.CacheFactory;
 import de.intevation.flys.artifacts.model.AnnotationsFactory;
 
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import java.io.Serializable;
+
 
 public class LocationProvider {
 
+    public static final double EPSILON = 1e-5;
+
+    public static class KmComparator
+    implements          Serializable, Comparator<Double>
+    {
+        @Override
+        public int compare(Double a, Double b) {
+            double diff = a - b;
+            if (diff < -EPSILON) return -1;
+            if (diff > +EPSILON) return +1;
+            return 0;
+        }
+    } // class KmComparator
+
     public static final String CACHE_KEY = "location-provider";
 
+    public static final String PREFIX = "lp-";
+
 
     private static final Logger logger =
         Logger.getLogger(LocationProvider.class);
@@ -24,66 +48,64 @@
     private LocationProvider() {
     }
 
+    public static String getLocation(String river, double km) {
 
-    public static String getLocation(String river, double km) {
-        return getLocation(getLocationHash(river, km), river, km);
+        Double KM = Double.valueOf(km);
+
+        return getKmMap(river, KM).get(KM);
     }
 
-
-    public static String getLocation(String hash, String river, double km) {
-        logger.debug("Fetch location for '" + river + "' at '" + km + "'");
+    protected static Map<Double, String> getKmMap(String river, double km) {
 
         Cache cache = CacheFactory.getCache(CACHE_KEY);
 
-        if (cache != null) {
-            return getCachedLocation(cache, hash, river, km);
+        if (cache == null) {
+            return uncachedKmMap(river, km);
         }
-        else {
-            logger.info("No Cache for Locations configured.");
-            return getUncachedLocation(river, km);
+
+        String key = PREFIX + river;
+
+        Element element = cache.get(key);
+
+        if (element != null) {
+            return (Map<Double, String>)element.getValue();
         }
+
+        Map<Double, String> map = uncachedKmMap(river, null);
+
+        cache.put(new Element(key, map));
+
+        return map;
     }
 
-
-    protected static String getCachedLocation(
-        Cache cache,
-        String hash,
+    protected static Map<Double, String> uncachedKmMap(
         String river,
-        double km
+        Double queryKm
     ) {
-        logger.debug("Fetch location from cache.");
-
-        Element element = cache.get(hash);
-
-        if (element == null) {
-            logger.debug("Element is not in cache yet.");
-
-            String location = getUncachedLocation(river, km);
-            element = new Element(hash, location);
-            cache.put(element);
+        Map<Double, String> map =
+            new TreeMap<Double, String>(new KmComparator());
+        
+        if (queryKm != null) {
+            Annotation annotation =
+                AnnotationsFactory.getAnnotation(river, queryKm);
+            if (annotation != null) {
+                map.put(queryKm, annotation.getPosition().getValue());
+            }
+            return map;
         }
 
-        return (String) element.getValue();
-    }
-
-
-    protected static String getUncachedLocation(String river, double km) {
-        logger.debug("Fetch location from backend.");
-
-        Annotation annotation = AnnotationsFactory.getAnnotation(river, km);
-
-        if (annotation != null) {
-            logger.debug("Found an annotation.");
-            Position pos = annotation.getPosition();
-            return pos.getValue();
+        for (Iterator<Annotation> iter =
+            AnnotationsFactory.getAnnotationsIterator(river);
+            iter.hasNext();
+        ) {
+            Annotation annotation = iter.next();
+            Position pos   = annotation.getPosition();
+            Range    range = annotation.getRange();
+            Double   km    = range.getA().doubleValue();
+            map.put(km, pos.getValue());
         }
 
-        return "";
-    }
-
-
-    protected static String getLocationHash(String river, double km) {
-        return river + "#" + km;
+        return map;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org