package org.jactr.eclipse.runtime.probe2; /* * default logging */ import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.tools.grapher.core.message.ProbeContainerUpdate; import org.jactr.tools.grapher.core.message.StringTableMessage; import org.jactr.tools.tracer.transformer.ITransformedEvent; /** * top level model based container. * * @author harrison */ public class ModelProbeData { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(ModelProbeData.class); private final String _modelName; private final StringTable _stringTable; private final double _timeWindow; private volatile double _minimumValue = 0; private volatile double _maximumValue = 0; private int _maxCapacity = 0; private int _normalCapacity = 0; private final Map<String, double[]> _probeData; private double[] _samplingTimes; private volatile int _lastSampleIndex = -1; public ModelProbeData(String modelName, double timeWindow, StringTable sessionStringTable) { _modelName = modelName; _stringTable = sessionStringTable; _timeWindow = timeWindow; _probeData = new ConcurrentHashMap<String, double[]>(); } public void clear() { _probeData.clear(); } public double getTimeWindow() { return _timeWindow; } void process(ITransformedEvent event) { if (event instanceof StringTableMessage) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Got string table update : %s", ((StringTableMessage) event).getStringTable())); _stringTable.update((StringTableMessage) event); } else updateProbeData((ProbeContainerUpdate) event); } private int computeSampleIndex(ProbeContainerUpdate event) { double sampleTime = event.getSimulationTime(); int sampleIndex = 0; /* * first time through, we need to figure out what the ideal capacity is for * the moment. */ if (_samplingTimes == null) { double samplingTime = event.getWindowSize(); _normalCapacity = (int) (_timeWindow / samplingTime); _maxCapacity = (int) (1.5 * _normalCapacity); if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Capacity: %d / %d", _normalCapacity, _maxCapacity)); /* * labels */ _samplingTimes = new double[_maxCapacity]; for (int i = 0; i < _maxCapacity; i++) _samplingTimes[i] = sampleTime + samplingTime * i; sampleIndex = 0; } else { /* * compute sampleIndex */ sampleIndex = (int) ((sampleTime - _samplingTimes[0]) / event .getWindowSize()); if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("%.2f [%d] [%.2f, %.2f]", sampleTime, sampleIndex, _samplingTimes[0], _samplingTimes[1])); } /* * do we need to resize? */ if (sampleIndex >= _maxCapacity) { /* * shift ourselves and trigger a shift for the probe data */ if (LOGGER.isDebugEnabled()) LOGGER.debug("Maximum capacity reached. Shifting"); double windowSize = event.getWindowSize(); int blockSize = _maxCapacity - _normalCapacity; System.arraycopy(_samplingTimes, blockSize, _samplingTimes, 0, _normalCapacity); for (int i = _normalCapacity; i < _maxCapacity; i++) _samplingTimes[i] = _samplingTimes[i - 1] + windowSize; for (double[] probeData : _probeData.values()) { System.arraycopy(probeData, blockSize, probeData, 0, _normalCapacity); Arrays.fill(probeData, _normalCapacity, _maxCapacity, Double.NaN); } sampleIndex = _normalCapacity; } return sampleIndex; } void updateProbeData(ProbeContainerUpdate event) { int sampleIndex = computeSampleIndex(event); for (Map.Entry<Long, Number> entry : event.getData().entrySet()) { String probeName = _stringTable.lookUp(entry.getKey()); if (probeName == null) { if (LOGGER.isWarnEnabled()) LOGGER.warn(String.format("Missing data from stringTable [%d]", entry.getKey())); continue; } double value = entry.getValue().doubleValue(); _minimumValue = Math.min(value, _minimumValue); _maximumValue = Math.max(value, _maximumValue); double[] probeData = _probeData.get(probeName); if (probeData == null) { probeData = new double[_maxCapacity]; Arrays.fill(probeData, Double.NaN); _probeData.put(probeName, probeData); } probeData[sampleIndex] = value; } _samplingTimes[sampleIndex] = event.getSimulationTime(); _lastSampleIndex = sampleIndex; } public Set<String> getProbeNames(Set<String> container) { if (container == null) container = new TreeSet<String>(); container.addAll(_probeData.keySet()); return container; } public double getMaximumValue() { return _maximumValue; } public double getMinimumValue() { return _minimumValue; } public double getStartTime() { if (_samplingTimes == null) return 0; return _samplingTimes[0]; } public double getEndTime() { if (_samplingTimes == null || _lastSampleIndex == -1) return _timeWindow; return _samplingTimes[_lastSampleIndex]; } public double[] getSampleTimes(double[] container) { if (_samplingTimes == null) return new double[] { 0, 1 }; return _samplingTimes; } public double[] getProbeData(String probeName, double[] container) { double[] pd = _probeData.get(probeName); return pd; } }