diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridInventory.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridInventory.java index 9ffb16bda6..50bf8419f4 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridInventory.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridInventory.java @@ -89,6 +89,9 @@ import com.raytheon.viz.grid.util.RadarAdapter; * Mar 25, 2009 brockwoo Initial creation * Nov 20, 2009 #3387 jelkins Use derived script's variableId instead of filename * Nov 21, 2009 #3576 rjpeter Refactored use of DerivParamDesc. + * Feb 26, 2013 1659 bsteffen Add time agnostic caching to grid derived + * parameters. + * * * * @author brockwoo @@ -324,12 +327,32 @@ public class GridInventory extends AbstractInventory implements newQuery.remove(GridInventory.LEVEL_ONE_QUERY); newQuery.remove(GridInventory.LEVEL_TWO_QUERY); newQuery.remove(GridInventory.MASTER_LEVEL_QUERY); - // Hopefully this results in querying all times for this model. - DataTime[] times = CatalogQuery.performTimeQuery(newQuery, false, - null); - + String modelName = null; + Collection times = null; + if (newQuery.size() == 2 && newQuery.containsKey(PLUGIN_NAME_QUERY) + && newQuery.containsKey(MODEL_NAME_QUERY)) { + // Only use the cache if the only constraint left are pluginName + // and datasetId and datasetId is an Equals constraint. This is + // almost always the case. + RequestConstraint modelRc = newQuery.get(MODEL_NAME_QUERY); + if (modelRc.getConstraintType() == ConstraintType.EQUALS) { + modelName = modelRc.getConstraintValue(); + times = GridTimeCache.getInstance() + .getModelTimes(modelName); + } + } + if (times == null) { + // This should query all times for this model. + DataTime[] timesArray = CatalogQuery.performTimeQuery(newQuery, + false, null); + times = Arrays.asList(timesArray); + if (modelName != null) { + GridTimeCache.getInstance().setModelTimes(modelName, + new HashSet(times)); + } + } if (times != null) { - rval = new ArrayList(Arrays.asList(times)); + rval = new ArrayList(times); } } if (processRadar) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridTimeCache.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridTimeCache.java index f60d5235d6..01cc7a27e5 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridTimeCache.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/inv/GridTimeCache.java @@ -19,19 +19,22 @@ **/ package com.raytheon.viz.grid.inv; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace; /** - * Cache times for GridRequestableNode's to avoid multiple trips to edex for the - * same data. The hit rate tends to be low when requesting individual products - * but can get very high when requesting complex derived parameters or model - * families since often many of the derived parameters can have dependencies on - * the same base parameters. + * Cache times for grid data to avoid multiple trips to edex for the same data. + * This caches times for GridRequestableNodes and also times for a whole model. + * The hit rate tends to be low when requesting individual products but can get + * very high when requesting complex derived parameters or model families since + * often many of the derived parameters can have dependencies on the same base + * parameters. * *
  * 
@@ -39,6 +42,8 @@ import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Jun 10, 2010            bsteffen     Initial creation
+ * Feb 26, 2013 1659       bsteffen    Add time agnostic caching to grid derived
+ *                                     parameters.
  * 
  * 
* @@ -48,16 +53,13 @@ import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace; public class GridTimeCache { - protected static final int CACHE_SIZE = 500; + protected static final int CACHE_SIZE = 1000; protected static final int CACHE_TIME = 300000; - private static GridTimeCache instance; + private final static GridTimeCache instance = new GridTimeCache(); public static GridTimeCache getInstance() { - if (instance == null) { - instance = new GridTimeCache(); - } return instance; } @@ -65,20 +67,23 @@ public class GridTimeCache { } - private class CacheEntry { + private class CacheEntry { - public CacheEntry(Set times) { + public CacheEntry(Set times) { this.insertTime = System.currentTimeMillis(); this.times = times; } - public long insertTime; + public final long insertTime; - public Set times; + public final Set times; } - private Map cache = new LinkedHashMap( + /** + * This map handles caching for GridRequestableNodes + */ + private final Map> cache = new LinkedHashMap>( 135, .75f, true) { private static final long serialVersionUID = 2022670836957170184L; @@ -96,7 +101,8 @@ public class GridTimeCache { * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) */ @Override - protected boolean removeEldestEntry(Entry eldest) { + protected boolean removeEldestEntry( + Entry> eldest) { if (this.size() > CACHE_SIZE) { // It is normal for stale entries to stay in the map until this // purges them, but we want some logging for non stale entries. @@ -120,31 +126,69 @@ public class GridTimeCache { } }; - public synchronized void setTimes(GridRequestableNode gNode, - Set times) { - cache.put(new GridMapKey(gNode.getRequestConstraintMap()), - new CacheEntry(times)); + /** + * This is the cache for all times for a model. + */ + private final Map> modelCache = new HashMap>(); + + public void setTimes(GridRequestableNode gNode, Set times) { + synchronized (cache) { + cache.put(new GridMapKey(gNode.getRequestConstraintMap()), + new CacheEntry(times)); + } } - public synchronized Set getTimes(GridRequestableNode gNode) { - GridMapKey key = new GridMapKey(gNode.getRequestConstraintMap()); - CacheEntry entry = cache.get(key); - if (entry == null) { - return null; + public Set getTimes(GridRequestableNode gNode) { + synchronized (cache) { + GridMapKey key = new GridMapKey(gNode.getRequestConstraintMap()); + CacheEntry entry = cache.get(key); + if (entry == null) { + return null; + } + if (entry.insertTime + CACHE_TIME < System.currentTimeMillis()) { + cache.remove(key); + return null; + } + return entry.times; } - if (entry.insertTime + CACHE_TIME < System.currentTimeMillis()) { - cache.remove(key); - return null; + } + + public void setModelTimes(String modelName, Set times) { + synchronized (modelCache) { + modelCache.put(modelName, new CacheEntry(times)); + } + } + + public Set getModelTimes(String modelName) { + synchronized (modelCache) { + CacheEntry entry = modelCache.get(modelName); + if (entry == null) { + return null; + } + if (entry.insertTime + CACHE_TIME < System.currentTimeMillis()) { + modelCache.remove(modelName); + return null; + } + return entry.times; } - return entry.times; } public synchronized void clearTimes(GridMapKey key) { - cache.remove(key); + synchronized (cache) { + cache.remove(key); + } + synchronized (modelCache) { + modelCache.remove(key.modelName); + } } public synchronized void flush() { - cache.clear(); + synchronized (cache) { + cache.clear(); + } + synchronized (modelCache) { + modelCache.clear(); + } } }