# HG changeset patch # User Ingo Weinzierl # Date 1273134776 0 # Node ID c07d9f9a738c4db8e80ce8a4de9f85910417c554 # Parent a5e0384fe464f6a78c70652d0397edc591a81131 Removed bugs that existed in the caching mechanism (issue264, issue268). gnv-artifacts/trunk@1067 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/ChangeLog Thu May 06 08:32:56 2010 +0000 @@ -1,3 +1,33 @@ +2010-05-06 Ingo Weinzierl + + Issue264 & Issue268 (Removed bugs in the caching mechanism) + + * src/main/java/de/intevation/gnv/state/DefaultInputData.java: Implemented + hashCode() and equals(.) method. The hashCode() method is used while + creating hashes for caching elements (see StateBase). + + * src/main/java/de/intevation/gnv/state/StateBase.java: Improved hash + creation. The hashes are used as keys for the caching mechanism. The key + contains the uuid of the current artifact, the state id and a hash code + created by InputData elements. User input is stored in a TreeMap instead + of a HashMap, because the elements in a TreeMap are sorted. This is very + import for us, because we need a defined order to create equal hashes if + the input data elements, uuid and state id are equal. + + * src/main/java/de/intevation/gnv/state/MeasurementState.java: Replaced the + HashMap to store user input with a TreeMap which elements are sorted. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Added some more debug output that shows the usage of the cache. + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Removed a critical bug that avoided using this product type if no cache + have been initialized. + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java: Adjusted + getHash(.) method call. + 2010-05-04 Tim Englich * doc/conf/conf.xml: diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputData.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputData.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputData.java Thu May 06 08:32:56 2010 +0000 @@ -161,5 +161,53 @@ return null; } + @Override + public int hashCode() { + logger.debug("*************************************"); + logger.debug("HashCode name: " + name); + + int hash = 0; + + hash ^= name.hashCode(); + + if (value != null) { + hash ^= value.hashCode() << 2; + } + + if (object != null) { + hash ^= object.hashCode() << 4; + } + + logger.debug("HashCode value: " + hash); + logger.debug("*************************************"); + + return hash; + } + + + @Override + public boolean equals(Object o) { + if (!(o instanceof DefaultInputData)) + return false; + + DefaultInputData other = (DefaultInputData) o; + + if (!name.equals(other.name)) + return false; + + if ((value == null) && (other.value == null)) + return false; + + if (!value.equals(other.value)) + return false; + + if (!(object == null) && (other.object == null)) + return false; + + if (!(object == other.object)) + return false; + + return true; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/MeasurementState.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/MeasurementState.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/MeasurementState.java Thu May 06 08:32:56 2010 +0000 @@ -22,10 +22,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.TreeMap; import org.apache.log4j.Logger; @@ -388,7 +388,7 @@ } if (inputData == null) { - inputData = new HashMap(); + inputData = new TreeMap(); } ExtendedInputData extended = new ExtendedInputData( diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputStateBase.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputStateBase.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputStateBase.java Thu May 06 08:32:56 2010 +0000 @@ -209,7 +209,7 @@ // we use a cache log.info("Using cache."); Cache cache = factory.getCache(); - String key = "chart_" + getHash(); + String key = "chart_" + getHash(uuid); net.sf.ehcache.Element value = cache.get(key); if (value != null) { @@ -242,7 +242,7 @@ log.debug("Fetch chart [" + uuid + "] from cache"); CacheFactory cacheFactory = CacheFactory.getInstance(); if (cacheFactory.isInitialized()) { - String key = "chart_" + getHash(); + String key = "chart_" + getHash(uuid); net.sf.ehcache.Element object = cacheFactory.getCache().get(key); if (object != null) { @@ -302,7 +302,7 @@ protected void removeChartResult(String uuid) { log.debug("OutputStateBase.getChartResult"); if (CacheFactory.getInstance().isInitialized()) { - String key = "chart_" + getHash(); + String key = "chart_" + getHash(uuid); log.debug("Hash for Queryelements: " + key); net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); if (value != null) { @@ -321,7 +321,7 @@ CacheFactory cacheFactory = CacheFactory.getInstance(); if (cacheFactory.isInitialized()) { - String key = "chart_" + getHash(); + String key = "chart_" + getHash(uuid); net.sf.ehcache.Element object = cacheFactory.getCache().get(key); if (object != null) cacheFactory.getCache().remove(key); @@ -335,7 +335,7 @@ log.debug("Prufify chart [" + uuid + "]"); CacheFactory cacheFactory = CacheFactory.getInstance(); if (cacheFactory.isInitialized()) { - String key = "chart_" + getHash(); + String key = "chart_" + getHash(uuid); cacheFactory.getCache().put(new net.sf.ehcache.Element(key, chart)); } } diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java Thu May 06 08:32:56 2010 +0000 @@ -13,6 +13,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; +import java.util.TreeMap; import javax.xml.xpath.XPathConstants; @@ -243,8 +245,7 @@ InputValue inputValue = this.inputValues.get(tmpItem.getName()); if (inputValue != null) { if (this.inputData == null) { - this.inputData = new HashMap( - inputData.size()); + this.inputData = new TreeMap(); } boolean valid = InputValidator.isInputValid(tmpItem.getValue(), @@ -348,8 +349,7 @@ InputValue inputValue = this.inputValues.get(tmpItem.getName()); if (inputValue != null) { if (this.inputData == null) { - this.inputData = new HashMap( - inputData.size()); + this.inputData = new TreeMap(); } boolean valid = InputValidator.isInputValid(tmpItem.getValue(), @@ -462,6 +462,7 @@ InputData data = this.inputData.get(value); if (data != null && this.inputValues.containsKey(data.getName())) { + int size = this.inputValues.get(data.getName()) .usedInQueries(); String type = this.inputValues.get(data.getName()) @@ -695,7 +696,7 @@ String uuid) { State parent = getParent(); - if (parent != null && parent instanceof StateBase) { + if (parent instanceof StateBase) { ((StateBase) parent).describeStatic( artCreator, creator, document, staticNode, context, uuid); } @@ -712,7 +713,7 @@ Node staticNode, CallMeta callMeta ) { - InputData data = inputData.get(dataName); + InputData data = dataName!= null ? inputData.get(dataName) : null; if (data == null) { return; @@ -937,15 +938,25 @@ protected void setHash(String uuid) { - this.hash = uuid + - HASH_ID_SEPARATOR + - id + - HASH_ID_SEPARATOR + - inputData.hashCode(); + String newHash = uuid + HASH_ID_SEPARATOR + id + HASH_ID_SEPARATOR; + Set keys = inputData.keySet(); + + int nhash = 0; + int shift = 0; + + for (Object o: keys) { + nhash ^= inputData.get(o).hashCode() << shift; + shift += 2; + } + + log.info("### OLD HASH: " + hash); + log.info("### NEW HASH: " + (newHash + nhash)); + + this.hash = newHash + nhash; } - protected String getHash() { + protected String getHash(String uuid) { return this.hash; } @@ -954,9 +965,10 @@ CacheFactory factory = CacheFactory.getInstance(); if (factory.isInitialized()) { // we use a cache - log.debug("Using cache."); Cache cache = factory.getCache(); - String key = getHash(); + String key = getHash(uuid); + + log.debug("Using cache - key: " + key); net.sf.ehcache.Element value = cache.get(key); if (value != null) { @@ -973,6 +985,7 @@ List data = queryDatabase(filterValues, uuid); cache.put(new net.sf.ehcache.Element(key, data)); + return data; } catch (QueryException qe) { diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java Thu May 06 08:32:56 2010 +0000 @@ -163,69 +163,73 @@ @Override protected Object getChartResult(String uuid, CallContext callContext) { log.debug("HorizontalProfileMeshCrossOutputState.getChartResult"); - Collection result = null; - if (CacheFactory.getInstance().isInitialized()) { - String key = uuid + super.getID(); - log.debug("Hash for Queryelements: " + key); - net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); - if (value != null) { - result = (Collection) (value.getObjectValue()); - }else{ - - InputData meshLine = inputData.get("mesh_linestring"); - InputData meshId = inputData.get("meshid"); - - if (meshLine == null) { - log.error("mesh_linestring is not defined"); - throw new IllegalStateException("missing mesh_linestring"); - } - - if (meshId == null) { - log.error("meshid is not defined"); - throw new IllegalStateException("missing meshid"); - } - - Coordinate [] coords = WKTUtils.toCoordinates( - meshLine.getValue()); - - if (coords == null) { - throw new IllegalStateException("cannot read coordinates"); - } - try { - String additionWhere = USE_INDEX_BUFFER - ? WKTUtils.worldCoordinatesToIndex( - coords, - result, - meshId.getValue(), - ijkQueryID) - : WKTUtils.TRUE_EXPRESSION; - - String[] addedFilterValues = StringUtils.append( - generateFilterValuesFromInputData(), - additionWhere); + String key = getHash(uuid); + if (CacheFactory.getInstance().isInitialized()) { + log.debug("Using cache - key: " + key); + net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); - QueryExecutor queryExecutor = QueryExecutorFactory - .getInstance() - .getQueryExecutor(); - - result = process( - Arrays.asList(coords), - numSamples(callContext), - queryExecutor.executeQuery( - queryID, - addedFilterValues)); - } - catch (QueryException e) { - log.error(e,e); - } - - if (CacheFactory.getInstance().isInitialized()) { - CacheFactory.getInstance().getCache().put(new net.sf.ehcache.Element(key, result)); - } - + if (value != null) { + log.debug("Found element in cache."); + return (Collection) (value.getObjectValue()); } } + + log.debug("Not using cache or element not found."); + Collection result = null; + + InputData meshLine = inputData.get("mesh_linestring"); + InputData meshId = inputData.get("meshid"); + + if (meshLine == null) { + log.error("mesh_linestring is not defined"); + throw new IllegalStateException("missing mesh_linestring"); + } + + if (meshId == null) { + log.error("meshid is not defined"); + throw new IllegalStateException("missing meshid"); + } + + Coordinate [] coords = WKTUtils.toCoordinates( + meshLine.getValue()); + + if (coords == null) { + throw new IllegalStateException("cannot read coordinates"); + } + + try { + String additionWhere = USE_INDEX_BUFFER + ? WKTUtils.worldCoordinatesToIndex( + coords, + result, + meshId.getValue(), + ijkQueryID) + : WKTUtils.TRUE_EXPRESSION; + + String[] addedFilterValues = StringUtils.append( + generateFilterValuesFromInputData(), + additionWhere); + + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + + result = process( + Arrays.asList(coords), + numSamples(callContext), + queryExecutor.executeQuery( + queryID, + addedFilterValues)); + } + catch (QueryException e) { + log.error(e,e); + } + + if (CacheFactory.getInstance().isInitialized()) { + CacheFactory.getInstance().getCache().put(new net.sf.ehcache.Element(key, result)); + } + return result; } diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java Thu May 06 08:32:56 2010 +0000 @@ -501,15 +501,18 @@ throws StateException { CacheFactory cf = CacheFactory.getInstance(); - String key = getHash(); + String key = getHash(uuid); if (cf.isInitialized()) { + log.debug("Using cache - key: " + key); net.sf.ehcache.Element value = cf.getCache().get(key); if (value != null) { - return (AttributedPoint2ds)value.getObjectValue(); + log.debug("Found element in cache."); + return (AttributedPoint2ds)value.getObjectValue(); } } + log.debug("Not using cache or element not found."); AttributedPoint2ds result = produceResult(callContext); if (result != null && cf.isInitialized()) { diff -r a5e0384fe464 -r c07d9f9a738c gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java Tue May 04 14:24:23 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java Thu May 06 08:32:56 2010 +0000 @@ -158,12 +158,11 @@ @Override protected Object getChartResult(String uuid, CallContext callContext) { log.debug("VerticalCrossSectionOutputState.getChartResult"); - String key = getHash(); - log.debug("Hash: "+key); + String key = getHash(uuid); CacheFactory factory = CacheFactory.getInstance(); if (factory.isInitialized()) { - log.info("Using a cachce."); + log.info("Using a cachce - key: " + key); Cache cache = factory.getCache(); Element element = cache.get(key);