Issue #1941: Speed up iscMosaic by properly utilizing WECache.
Change-Id: Ic8d7ea31cf8f1a989c4f06c0a60c9a351ed8ce8e Former-commit-id:60bcd26d36
[formerly60bcd26d36
[formerly f3d7241b3eafb86046cdcc6c28197244b55f21e9]] Former-commit-id:159302cf8c
Former-commit-id:14701c14d7
This commit is contained in:
parent
e039d2cc13
commit
cec8443e3f
2 changed files with 264 additions and 101 deletions
|
@ -24,7 +24,9 @@ import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import com.raytheon.edex.plugin.gfe.config.IFPServerConfig;
|
import com.raytheon.edex.plugin.gfe.config.IFPServerConfig;
|
||||||
|
@ -35,7 +37,6 @@ import com.raytheon.edex.plugin.gfe.server.lock.LockManager;
|
||||||
import com.raytheon.edex.plugin.gfe.util.SendNotifications;
|
import com.raytheon.edex.plugin.gfe.util.SendNotifications;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory;
|
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord;
|
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
|
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo;
|
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
|
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
|
import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
|
||||||
|
@ -77,6 +78,9 @@ import com.raytheon.uf.common.time.TimeRange;
|
||||||
* Jan 22, 2010 4248 njensen Better error msgs
|
* Jan 22, 2010 4248 njensen Better error msgs
|
||||||
* Jul 25, 2012 #957 dgilling Implement getEditArea().
|
* Jul 25, 2012 #957 dgilling Implement getEditArea().
|
||||||
* Apr 23, 2013 #1937 dgilling Implement get().
|
* Apr 23, 2013 #1937 dgilling Implement get().
|
||||||
|
* Apr 23, 2013 #1941 dgilling Implement put(), add methods to build
|
||||||
|
* Scalar/VectorGridSlices, refactor
|
||||||
|
* Discrete/WeatherGridSlices builders.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -234,6 +238,76 @@ public class IFPWE {
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the provided grid slices into this weather element's permanent
|
||||||
|
* storage.
|
||||||
|
*
|
||||||
|
* @param inventory
|
||||||
|
* A Map of TimeRanges to IGridSlices to be saved. Time is the
|
||||||
|
* slice's valid time.
|
||||||
|
* @param timeRangeSpan
|
||||||
|
* The replacement time range of grids to be saved. Must cover
|
||||||
|
* each individual TimeRange in inventory.
|
||||||
|
* @throws GfeException
|
||||||
|
* If an error occurs while trying to obtain a lock on the
|
||||||
|
* destination database.
|
||||||
|
*/
|
||||||
|
public void put(LinkedHashMap<TimeRange, IGridSlice> inventory,
|
||||||
|
TimeRange timeRangeSpan) throws GfeException {
|
||||||
|
statusHandler.debug("Getting lock for ParmID: " + parmId + " TR: "
|
||||||
|
+ timeRangeSpan);
|
||||||
|
ServerResponse<List<LockTable>> lockResponse = LockManager
|
||||||
|
.getInstance().requestLockChange(
|
||||||
|
new LockRequest(parmId, timeRangeSpan, LockMode.LOCK),
|
||||||
|
wsId, siteId);
|
||||||
|
if (lockResponse.isOkay()) {
|
||||||
|
statusHandler.debug("LOCKING: Lock granted for: " + wsId
|
||||||
|
+ " for time range: " + timeRangeSpan);
|
||||||
|
} else {
|
||||||
|
statusHandler.error("Could not lock TimeRange " + timeRangeSpan
|
||||||
|
+ " for parm [" + parmId + "]: " + lockResponse.message());
|
||||||
|
throw new GfeException("Request lock failed. "
|
||||||
|
+ lockResponse.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GFERecord> records = new ArrayList<GFERecord>(inventory.size());
|
||||||
|
for (Entry<TimeRange, IGridSlice> entry : inventory.entrySet()) {
|
||||||
|
GFERecord rec = new GFERecord(parmId, entry.getKey());
|
||||||
|
rec.setGridHistory(entry.getValue().getHistory());
|
||||||
|
rec.setMessageData(entry.getValue());
|
||||||
|
records.add(rec);
|
||||||
|
}
|
||||||
|
SaveGridRequest sgr = new SaveGridRequest(parmId, timeRangeSpan,
|
||||||
|
records);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ServerResponse<?> sr = GridParmManager.saveGridData(
|
||||||
|
Arrays.asList(sgr), wsId, siteId);
|
||||||
|
if (sr.isOkay()) {
|
||||||
|
SendNotifications.send(sr.getNotifications());
|
||||||
|
} else {
|
||||||
|
statusHandler.error("Unable to save grids for parm [" + parmId
|
||||||
|
+ "] over time range " + timeRangeSpan + ": "
|
||||||
|
+ sr.message());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
ServerResponse<List<LockTable>> unLockResponse = LockManager
|
||||||
|
.getInstance().requestLockChange(
|
||||||
|
new LockRequest(parmId, timeRangeSpan,
|
||||||
|
LockMode.UNLOCK), wsId, siteId);
|
||||||
|
if (unLockResponse.isOkay()) {
|
||||||
|
statusHandler.debug("LOCKING: Unlocked for: " + wsId + " TR: "
|
||||||
|
+ timeRangeSpan);
|
||||||
|
} else {
|
||||||
|
statusHandler.error("Could not unlock TimeRange "
|
||||||
|
+ timeRangeSpan + " for parm [" + parmId + "]: "
|
||||||
|
+ lockResponse.message());
|
||||||
|
throw new GfeException("Request unlock failed. "
|
||||||
|
+ unLockResponse.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setItem(TimeRange time, IGridSlice gridSlice,
|
private void setItem(TimeRange time, IGridSlice gridSlice,
|
||||||
List<GridDataHistory> gdh) throws GfeException {
|
List<GridDataHistory> gdh) throws GfeException {
|
||||||
GFERecord rec = new GFERecord(parmId, time);
|
GFERecord rec = new GFERecord(parmId, time);
|
||||||
|
@ -373,9 +447,7 @@ public class IFPWE {
|
||||||
public void setItemDiscrete(TimeRange time, byte[] discreteData,
|
public void setItemDiscrete(TimeRange time, byte[] discreteData,
|
||||||
String keys, List<GridDataHistory> gdhList) throws GfeException {
|
String keys, List<GridDataHistory> gdhList) throws GfeException {
|
||||||
IGridSlice gridSlice = buildDiscreteSlice(time, discreteData, keys,
|
IGridSlice gridSlice = buildDiscreteSlice(time, discreteData, keys,
|
||||||
gpi.getGridType());
|
gdhList);
|
||||||
gridSlice
|
|
||||||
.setHistory(gdhList.toArray(new GridDataHistory[gdhList.size()]));
|
|
||||||
setItem(time, gridSlice, gdhList);
|
setItem(time, gridSlice, gdhList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,9 +465,7 @@ public class IFPWE {
|
||||||
public void setItemWeather(TimeRange time, byte[] weatherData, String keys,
|
public void setItemWeather(TimeRange time, byte[] weatherData, String keys,
|
||||||
List<GridDataHistory> gdhList) throws GfeException {
|
List<GridDataHistory> gdhList) throws GfeException {
|
||||||
IGridSlice gridSlice = buildWeatherSlice(time, weatherData, keys,
|
IGridSlice gridSlice = buildWeatherSlice(time, weatherData, keys,
|
||||||
gpi.getGridType());
|
gdhList);
|
||||||
gridSlice
|
|
||||||
.setHistory(gdhList.toArray(new GridDataHistory[gdhList.size()]));
|
|
||||||
setItem(time, gridSlice, gdhList);
|
setItem(time, gridSlice, gdhList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,60 +503,96 @@ public class IFPWE {
|
||||||
return keys.toArray(new String[keys.size()]);
|
return keys.toArray(new String[keys.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a ScalarGridSlice to store.
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* The valid time of the slice.
|
||||||
|
* @param data
|
||||||
|
* A float array that corresponds to the slice's data.
|
||||||
|
* @param history
|
||||||
|
* The GridDataHistory for the new slice.
|
||||||
|
* @return A ScalarGridSlice based on the provided data, valid for the given
|
||||||
|
* time, with the provided history.
|
||||||
|
*/
|
||||||
|
public ScalarGridSlice buildScalarSlice(TimeRange time, float[] data,
|
||||||
|
List<GridDataHistory> history) {
|
||||||
|
return new ScalarGridSlice(time, gpi, history, new Grid2DFloat(gpi
|
||||||
|
.getGridLoc().getNx(), gpi.getGridLoc().getNy(), data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a VectorGridSlice to store.
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* The valid time of the slice.
|
||||||
|
* @param magData
|
||||||
|
* A float array that corresponds to the slice's magnitude data.
|
||||||
|
* @param dirData
|
||||||
|
* A float array that corresponds to the slice's directional
|
||||||
|
* data.
|
||||||
|
* @param history
|
||||||
|
* The GridDataHistory for the new slice.
|
||||||
|
* @return A VectorGridSlice based on the provided data, valid for the given
|
||||||
|
* time, with the provided history.
|
||||||
|
*/
|
||||||
|
public VectorGridSlice buildVectorSlice(TimeRange time, float[] magData,
|
||||||
|
float[] dirData, List<GridDataHistory> history) {
|
||||||
|
return new VectorGridSlice(time, gpi, history, new Grid2DFloat(gpi
|
||||||
|
.getGridLoc().getNx(), gpi.getGridLoc().getNy(), magData),
|
||||||
|
new Grid2DFloat(gpi.getGridLoc().getNx(), gpi.getGridLoc()
|
||||||
|
.getNy(), dirData));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a discrete grid slice to store
|
* Builds a discrete grid slice to store
|
||||||
*
|
*
|
||||||
* @param time
|
* @param time
|
||||||
* the time of the data
|
* The valid time of the data.
|
||||||
* @param slice
|
* @param bytes
|
||||||
* an Object[] { byte[], String } corresponding to discrete/wx
|
* A byte[] corresponding to discrete
|
||||||
* types
|
* @param keyString
|
||||||
* @param type
|
* Python encoded form of discrete keys.
|
||||||
* the type of the data
|
* @param history
|
||||||
|
* histories for this grid.
|
||||||
* @return
|
* @return
|
||||||
* @throws GfeException
|
|
||||||
*/
|
*/
|
||||||
private IGridSlice buildDiscreteSlice(TimeRange time, byte[] bytes,
|
public DiscreteGridSlice buildDiscreteSlice(TimeRange time, byte[] bytes,
|
||||||
String keyString, GridType type) throws GfeException {
|
String keyString, List<GridDataHistory> history) {
|
||||||
List<DiscreteKey> discreteKeyList = new ArrayList<DiscreteKey>();
|
List<DiscreteKey> discreteKeyList = new ArrayList<DiscreteKey>();
|
||||||
List<String> keys = GfeUtil.discreteKeyStringToList(keyString);
|
List<String> keys = GfeUtil.discreteKeyStringToList(keyString);
|
||||||
|
|
||||||
for (String k : keys) {
|
for (String k : keys) {
|
||||||
discreteKeyList.add(new DiscreteKey(siteId, k, parmId));
|
discreteKeyList.add(new DiscreteKey(siteId, k, parmId));
|
||||||
}
|
}
|
||||||
return new DiscreteGridSlice(
|
return new DiscreteGridSlice(time, gpi, history, new Grid2DByte(gpi
|
||||||
time,
|
.getGridLoc().getNx(), gpi.getGridLoc().getNy(), bytes),
|
||||||
gpi,
|
discreteKeyList);
|
||||||
new GridDataHistory[] {},
|
|
||||||
new Grid2DByte(gpi.getGridLoc().getNx(), gpi.getGridLoc()
|
|
||||||
.getNy(), bytes),
|
|
||||||
discreteKeyList.toArray(new DiscreteKey[discreteKeyList.size()]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a weather grid slice to store
|
* Builds a weather grid slice to store
|
||||||
*
|
*
|
||||||
* @param time
|
* @param time
|
||||||
* the time of the data
|
* The valid time of the data.
|
||||||
* @param slice
|
* @param bytes
|
||||||
* an Object[] { byte[], String } corresponding to weather/wx
|
* A byte[] corresponding to weather
|
||||||
* types
|
* @param keyString
|
||||||
* @param type
|
* Python encoded form of weather keys.
|
||||||
* the type of the data
|
* @param history
|
||||||
|
* histories for this grid.
|
||||||
* @return
|
* @return
|
||||||
* @throws GfeException
|
|
||||||
*/
|
*/
|
||||||
private IGridSlice buildWeatherSlice(TimeRange time, byte[] bytes,
|
public WeatherGridSlice buildWeatherSlice(TimeRange time, byte[] bytes,
|
||||||
String keyString, GridType type) throws GfeException {
|
String keyString, List<GridDataHistory> history) {
|
||||||
List<WeatherKey> weatherKeyList = new ArrayList<WeatherKey>();
|
List<WeatherKey> weatherKeyList = new ArrayList<WeatherKey>();
|
||||||
List<String> keys = GfeUtil.discreteKeyStringToList(keyString);
|
List<String> keys = GfeUtil.discreteKeyStringToList(keyString);
|
||||||
for (String k : keys) {
|
for (String k : keys) {
|
||||||
weatherKeyList.add(new WeatherKey(siteId, k));
|
weatherKeyList.add(new WeatherKey(siteId, k));
|
||||||
}
|
}
|
||||||
return new WeatherGridSlice(time, gpi, new GridDataHistory[] {},
|
return new WeatherGridSlice(time, gpi, history, new Grid2DByte(gpi
|
||||||
new Grid2DByte(gpi.getGridLoc().getNx(), gpi.getGridLoc()
|
.getGridLoc().getNx(), gpi.getGridLoc().getNy(), bytes),
|
||||||
.getNy(), bytes),
|
weatherKeyList);
|
||||||
weatherKeyList.toArray(new WeatherKey[weatherKeyList.size()]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,6 +32,7 @@ import numpy
|
||||||
import JUtil
|
import JUtil
|
||||||
|
|
||||||
from java.util import ArrayList
|
from java.util import ArrayList
|
||||||
|
from java.util import LinkedHashMap
|
||||||
from com.raytheon.uf.common.dataplugin.gfe.grid import Grid2DFloat
|
from com.raytheon.uf.common.dataplugin.gfe.grid import Grid2DFloat
|
||||||
from com.raytheon.uf.common.dataplugin.gfe.grid import Grid2DByte
|
from com.raytheon.uf.common.dataplugin.gfe.grid import Grid2DByte
|
||||||
from com.raytheon.uf.common.time import TimeRange
|
from com.raytheon.uf.common.time import TimeRange
|
||||||
|
@ -74,7 +75,8 @@ from com.raytheon.uf.edex.database.cluster import ClusterTask
|
||||||
# 07/06/09 1995 bphillip Initial Creation.
|
# 07/06/09 1995 bphillip Initial Creation.
|
||||||
# 01/17/13 15588 jdynina Fixed Publish history removal
|
# 01/17/13 15588 jdynina Fixed Publish history removal
|
||||||
# 03/12/13 1759 dgilling Remove unnecessary command line
|
# 03/12/13 1759 dgilling Remove unnecessary command line
|
||||||
# processing.
|
# processing.
|
||||||
|
# 04/24/13 1941 dgilling Re-port WECache to match A1.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -86,53 +88,49 @@ ISC_USER="isc"
|
||||||
|
|
||||||
class WECache(object):
|
class WECache(object):
|
||||||
def __init__(self, we, tr=None):
|
def __init__(self, we, tr=None):
|
||||||
self._grids = []
|
|
||||||
self._hist = []
|
|
||||||
self._we = we
|
self._we = we
|
||||||
self._inv = []
|
self._inv = {}
|
||||||
theKeys = self._we.getKeys()
|
self._invCache = None
|
||||||
|
|
||||||
for i in range(0, theKeys.size()):
|
|
||||||
self._inv.append(iscUtil.transformTime(theKeys.get(i)))
|
|
||||||
|
|
||||||
|
javaInv = self._we.getKeys()
|
||||||
|
pyInv = []
|
||||||
|
for i in xrange(javaInv.size()):
|
||||||
|
pyInv.append(iscUtil.transformTime(javaInv.get(i)))
|
||||||
|
|
||||||
# Dont get grids outside of the passed in timerange.
|
# Dont get grids outside of the passed in timerange.
|
||||||
if tr:
|
if tr:
|
||||||
tokill = []
|
tokill = []
|
||||||
for i, t in enumerate(self._inv):
|
for i, t in enumerate(pyInv):
|
||||||
if not self.overlaps(tr, t):
|
if not self.overlaps(tr, t):
|
||||||
tokill.append(i)
|
tokill.append(i)
|
||||||
tokill.reverse()
|
tokill.reverse()
|
||||||
for i in tokill:
|
for i in tokill:
|
||||||
del self._inv[i]
|
del pyInv[i]
|
||||||
|
|
||||||
|
javaTRs = ArrayList()
|
||||||
|
for tr in pyInv:
|
||||||
|
javaTRs.add(iscUtil.toJavaTimeRange(tr))
|
||||||
|
gridsAndHist = self._we.get(javaTRs, True)
|
||||||
|
for idx, tr in enumerate(pyInv):
|
||||||
|
pair = gridsAndHist.get(idx)
|
||||||
|
g = self.__encodeGridSlice(pair.getFirst())
|
||||||
|
h = self.__encodeGridHistory(pair.getSecond())
|
||||||
|
self._inv[tr] = (g, h)
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
return tuple(self._inv)
|
if not self._invCache:
|
||||||
|
self._invCache = tuple(sorted(self._inv.keys(), key=lambda t: t[0]))
|
||||||
|
return self._invCache
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
grid = self._we.getItem(iscUtil.toJavaTimeRange(key))
|
try:
|
||||||
history = grid.getGridDataHistory()
|
return self._inv[key]
|
||||||
hist = []
|
except KeyError:
|
||||||
for i in range(0, history.size()):
|
grid = self._we.getItem(iscUtil.toJavaTimeRange(key))
|
||||||
hist.append(history.get(i))
|
pyGrid = self.__encodeGridSlice(grid)
|
||||||
gridType = grid.getGridInfo().getGridType().toString()
|
history = grid.getGridDataHistory()
|
||||||
if gridType == "SCALAR":
|
pyHist = self.__encodeGridHistory(history)
|
||||||
return (grid.__numpy__[0], hist)
|
return (pyGrid, pyHist)
|
||||||
elif gridType == "VECTOR":
|
|
||||||
vecGrids = grid.__numpy__
|
|
||||||
return ((vecGrids[0], vecGrids[1]), hist)
|
|
||||||
elif gridType == "WEATHER":
|
|
||||||
keys = grid.getKeys()
|
|
||||||
keyList = []
|
|
||||||
for theKey in keys:
|
|
||||||
keyList.append(theKey.toString())
|
|
||||||
return ((grid.__numpy__[0], keyList), hist)
|
|
||||||
elif gridType == "DISCRETE":
|
|
||||||
keys = grid.getKey()
|
|
||||||
keyList = []
|
|
||||||
for theKey in keys:
|
|
||||||
keyList.append(theKey.toString())
|
|
||||||
return ((grid.__numpy__[0], keyList), hist)
|
|
||||||
|
|
||||||
def __setitem__(self, tr, value):
|
def __setitem__(self, tr, value):
|
||||||
if value is None:
|
if value is None:
|
||||||
|
@ -142,48 +140,106 @@ class WECache(object):
|
||||||
|
|
||||||
# Remove any overlapping grids
|
# Remove any overlapping grids
|
||||||
tokill = []
|
tokill = []
|
||||||
for i, itr in enumerate(self._inv):
|
for itr in self._inv:
|
||||||
if self.overlaps(tr, itr):
|
if self.overlaps(tr, itr):
|
||||||
tokill.append(i)
|
tokill.append(itr)
|
||||||
tokill.reverse()
|
|
||||||
for i in tokill:
|
for i in tokill:
|
||||||
del self._inv[i]
|
del self._inv[i]
|
||||||
|
self._invCache = None
|
||||||
|
|
||||||
# Now add the new grid if it exists
|
# Now add the new grid if it exists
|
||||||
if grid is not None:
|
if grid is not None:
|
||||||
timeRange=iscUtil.toJavaTimeRange(tr)
|
self._inv[tr] = (grid, hist)
|
||||||
LogStream.logDebug("iscMosaic: Saving Parm:",self._we.getParmid(),"TR:",timeRange)
|
self._invCache = None
|
||||||
gridType = self._we.getGridType()
|
|
||||||
index = bisect.bisect_left(map(lambda x : x[0], self._inv), tr[0])
|
|
||||||
self._inv.insert(index, tr)
|
|
||||||
history = ArrayList()
|
|
||||||
|
|
||||||
for h in hist:
|
def flush(self):
|
||||||
dbName = self._we.getParmid().getDbId().toString()
|
"""Actually writes the contents of the WECache to HDF5/DB"""
|
||||||
if dbName.find('Fcst') != -1:
|
# get cache inventory in time range order
|
||||||
#strip out publish time to allow for publishing correctly
|
# we want to write to disk in contiguous time range blocks so we only
|
||||||
#when merging Fcst out of A1
|
# overwrite what we have full sets of grids for.
|
||||||
hh = GridDataHistory(h)
|
inv = list(self.keys())
|
||||||
hh.setPublishTime(None)
|
# Don't believe the grid slices need to be in time order when saving
|
||||||
history.add(hh)
|
# but leaving them that way just in case.
|
||||||
else:
|
gridsToSave = LinkedHashMap()
|
||||||
history.add(GridDataHistory(h))
|
while inv:
|
||||||
if gridType == 'SCALAR':
|
# retrieve the next BATCH of grids to persist
|
||||||
self._we.setItemScalar(timeRange, grid.astype(numpy.float32), history)
|
i = inv[:BATCH_WRITE_COUNT]
|
||||||
elif gridType == 'VECTOR':
|
# pre-compute the replacement TR for the save requests generated by
|
||||||
self._we.setItemVector(timeRange, grid[0].astype(numpy.float32), grid[1].astype(numpy.float32), history)
|
# IFPWE.put().
|
||||||
elif gridType == 'WEATHER':
|
# since the inventory is in order it's the start time of the
|
||||||
self._we.setItemWeather(timeRange, grid[0].astype(numpy.byte), str(grid[1]), history)
|
# first TR and the end time of the last TR.
|
||||||
elif gridType == 'DISCRETE':
|
gridSaveTR = iscUtil.toJavaTimeRange((i[0][0], i[-1][1]))
|
||||||
self._we.setItemDiscrete(timeRange, grid[0].astype(numpy.byte), str(grid[1]), history)
|
for tr in i:
|
||||||
LogStream.logDebug("iscMosaic: Successfully saved Parm:",self._we.getParmid(),"Time:",timeRange)
|
javaTR = iscUtil.toJavaTimeRange(tr)
|
||||||
|
pyGrid, pyHist = self._inv[tr]
|
||||||
|
javaHist = self.__buildJavaGridHistory(pyHist)
|
||||||
|
javaGrid = self.__buildJavaGridSlice(javaTR, pyGrid, javaHist)
|
||||||
|
gridsToSave.put(javaTR, javaGrid)
|
||||||
|
self._we.put(gridsToSave, gridSaveTR)
|
||||||
|
# delete the persisted items from the cache and our copy of the
|
||||||
|
# inventory
|
||||||
|
gridsToSave.clear()
|
||||||
|
for tr in i:
|
||||||
|
del self._inv[tr]
|
||||||
|
self._invCache = None
|
||||||
|
inv = inv[BATCH_WRITE_COUNT:]
|
||||||
|
time.sleep(BATCH_DELAY)
|
||||||
|
|
||||||
|
|
||||||
def overlaps(self, tr1, tr2):
|
def overlaps(self, tr1, tr2):
|
||||||
if (tr1[0] >= tr2[0] and tr1[0] < tr2[1]) or \
|
if (tr1[0] >= tr2[0] and tr1[0] < tr2[1]) or \
|
||||||
(tr2[0] >= tr1[0] and tr2[0] < tr1[1]):
|
(tr2[0] >= tr1[0] and tr2[0] < tr1[1]):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def __encodeGridSlice(self, grid):
|
||||||
|
gridType = self._we.getGridType()
|
||||||
|
if gridType == "SCALAR":
|
||||||
|
return grid.__numpy__[0]
|
||||||
|
elif gridType == "VECTOR":
|
||||||
|
vecGrids = grid.__numpy__
|
||||||
|
return (vecGrids[0], vecGrids[1])
|
||||||
|
elif gridType == "WEATHER":
|
||||||
|
keys = grid.getKeys()
|
||||||
|
keyList = []
|
||||||
|
for theKey in keys:
|
||||||
|
keyList.append(theKey.toString())
|
||||||
|
return (grid.__numpy__[0], keyList)
|
||||||
|
elif gridType =="DISCRETE":
|
||||||
|
keys = grid.getKey()
|
||||||
|
keyList = []
|
||||||
|
for theKey in keys:
|
||||||
|
keyList.append(theKey.toString())
|
||||||
|
return (grid.__numpy__[0], keyList)
|
||||||
|
|
||||||
|
def __encodeGridHistory(self, histories):
|
||||||
|
retVal = []
|
||||||
|
for i in xrange(histories.size()):
|
||||||
|
retVal.append(histories.get(i).getCodedString())
|
||||||
|
return tuple(retVal)
|
||||||
|
|
||||||
|
def __buildJavaGridSlice(self, tr, grid, history):
|
||||||
|
gridType = self._we.getGridType()
|
||||||
|
if gridType == "SCALAR":
|
||||||
|
return self._we.buildScalarSlice(tr, grid.astype(numpy.float32), history)
|
||||||
|
elif gridType == "VECTOR":
|
||||||
|
return self._we.buildVectorSlice(tr, grid[0].astype(numpy.float32), grid[1].astype(numpy.float32), history)
|
||||||
|
elif gridType == "WEATHER":
|
||||||
|
return self._we.buildWeatherSlice(tr, grid[0].astype(numpy.byte), str(grid[1]), history)
|
||||||
|
elif gridType == "DISCRETE":
|
||||||
|
return self._we.buildDiscreteSlice(tr, grid[0].astype(numpy.byte), str(grid[1]), history)
|
||||||
|
|
||||||
|
def __buildJavaGridHistory(self, histories):
|
||||||
|
retVal = ArrayList()
|
||||||
|
blankPubTime = "Fcst" in self._we.getParmid().getDbId().toString()
|
||||||
|
for histEntry in histories:
|
||||||
|
javaHist = GridDataHistory(histEntry)
|
||||||
|
# strip out publish time to allow for publishing correctly
|
||||||
|
# when merging Fcst out of A1
|
||||||
|
if blankPubTime:
|
||||||
|
javaHist.setPublishTime(None)
|
||||||
|
retVal.add(javaHist)
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
|
||||||
class IscMosaic:
|
class IscMosaic:
|
||||||
|
@ -549,7 +605,8 @@ class IscMosaic:
|
||||||
# Returns tuple of (parmName, TR, #grids, #fails)
|
# Returns tuple of (parmName, TR, #grids, #fails)
|
||||||
if len(inTimesProc):
|
if len(inTimesProc):
|
||||||
totalTimeRange = (inTimesProc[0][0], inTimesProc[ -1][ -1] - 3600)
|
totalTimeRange = (inTimesProc[0][0], inTimesProc[ -1][ -1] - 3600)
|
||||||
|
self._wec.flush()
|
||||||
|
|
||||||
retryAttempt = retries
|
retryAttempt = retries
|
||||||
except:
|
except:
|
||||||
retryAttempt = retryAttempt + 1
|
retryAttempt = retryAttempt + 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue