Commit 51027aa4 authored by Tobias Meuser's avatar Tobias Meuser
Browse files

Added spatial metric

parent b3c75941
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.impl.analyzer.metric.output; package de.tud.kom.p2psim.impl.analyzer.metric.output;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -54,113 +55,113 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; ...@@ -54,113 +55,113 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
*/ */
public class MetricOutputDAO extends AbstractOutput { public class MetricOutputDAO extends AbstractOutput {
protected long timeEnableDao = 0; protected long timeEnableDao = 0;
protected long timeStopDao = Long.MAX_VALUE; protected long timeStopDao = Long.MAX_VALUE;
protected Set<String> metricsToAggregate = new LinkedHashSet<>(); protected Set<String> metricsToAggregate = new LinkedHashSet<>();
protected List<DaoAdapter> daoAdapters = new LinkedList<>(); protected List<DaoAdapter> daoAdapters = new LinkedList<>();
/** /**
* *
* @param table * @param table
*/ */
@XMLConfigurableConstructor({ "table" }) @XMLConfigurableConstructor({ "table" })
public MetricOutputDAO(String table) { public MetricOutputDAO(String table) {
DAO.database = table; DAO.database = table;
} }
public void setUser(String user) { public void setUser(String user) {
DAO.username = user; DAO.username = user;
} }
public void setPassword(String password) { public void setPassword(String password) {
DAO.password = password; DAO.password = password;
} }
public void setTimeEnableDao(long timeEnableDao) { public void setTimeEnableDao(long timeEnableDao) {
this.timeEnableDao = timeEnableDao; this.timeEnableDao = timeEnableDao;
} }
public void setTimeStopDao(long timeStopDao) { public void setTimeStopDao(long timeStopDao) {
this.timeStopDao = timeStopDao; this.timeStopDao = timeStopDao;
} }
/** /**
* A list of PER-HOST metrics that are NOT written individually but instead * A list of PER-HOST metrics that are NOT written individually but instead
* statistical figures for a group of hosts is written. The group of hosts * statistical figures for a group of hosts is written. The group of hosts is
* is defined by the hostGroup from the XML-config. * defined by the hostGroup from the XML-config.
* *
* @param metricsToAggregate * @param metricsToAggregate
*/ */
public void setToAggregate(String[] metricsToAggregate) { public void setToAggregate(String[] metricsToAggregate) {
for (String metric : metricsToAggregate) { for (String metric : metricsToAggregate) {
this.metricsToAggregate.add(metric); this.metricsToAggregate.add(metric);
} }
} }
public boolean isToAggregate(Metric metric) { public boolean isToAggregate(Metric metric) {
for (String string : metricsToAggregate) { for (String string : metricsToAggregate) {
if (metric.getName().equals(string)) { if (metric.getName().equals(string)) {
return true; return true;
} }
if (string.endsWith("*")) { if (string.endsWith("*")) {
// prefix matching // prefix matching
String mName = metric.getName(); String mName = metric.getName();
if (mName.startsWith(string.substring(0, string.length()-1))) { if (mName.startsWith(string.substring(0, string.length() - 1))) {
return true; return true;
} }
} }
if (string.startsWith("*")) { if (string.startsWith("*")) {
// postfix matching // postfix matching
String mName = metric.getName(); String mName = metric.getName();
if (mName.endsWith(string.substring(1, string.length()))) { if (mName.endsWith(string.substring(1, string.length()))) {
return true; return true;
} }
} }
} }
return false; return false;
} }
@Override @Override
public void onInitialize(List<Metric> metrics) { public void onInitialize(List<Metric> metrics) {
for (Metric metric : metrics) { for (Metric metric : metrics) {
/* /*
* Only active metrics are allowed. We register as a listener and * Only active metrics are allowed. We register as a listener and wait for our
* wait for our call. * call.
*/ */
if (metric instanceof ActiveMetric) { if (metric instanceof ActiveMetric) {
ActiveMetric am = (ActiveMetric) metric; ActiveMetric am = (ActiveMetric) metric;
MetricDaoAdapter adapter = new MetricDaoAdapter(am); MetricDaoAdapter adapter = new MetricDaoAdapter(am);
am.addActiveMetricListener(adapter); am.addActiveMetricListener(adapter);
daoAdapters.add(adapter); daoAdapters.add(adapter);
} }
if (metric instanceof ActiveSpatialMetric) { if (metric instanceof ActiveSpatialMetric) {
ActiveSpatialMetric asm = (ActiveSpatialMetric) metric; ActiveSpatialMetric asm = (ActiveSpatialMetric) metric;
SpatialMetricDaoAdapter adapter = new SpatialMetricDaoAdapter(asm); SpatialMetricDaoAdapter adapter = new SpatialMetricDaoAdapter(asm);
asm.addActiveSpatialMetricListener(adapter); asm.addActiveSpatialMetricListener(adapter);
daoAdapters.add(adapter); daoAdapters.add(adapter);
} }
} }
} }
@Override @Override
public void onStop() { public void onStop() {
for (DaoAdapter adapter : daoAdapters) { for (DaoAdapter adapter : daoAdapters) {
adapter.onStop(); adapter.onStop();
} }
/* /*
* Commit missing values * Commit missing values
*/ */
DAO.commitQueue(); DAO.commitQueue();
} }
private interface DaoAdapter { private interface DaoAdapter {
void onStop(); void onStop();
} }
/** /**
* This class helps in persisting a metric using the {@link MeasurementDAO} * This class helps in persisting a metric using the {@link MeasurementDAO}
* *
* @author Bjoern Richerzhagen * @author Bjoern Richerzhagen
...@@ -186,8 +187,7 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -186,8 +187,7 @@ public class MetricOutputDAO extends AbstractOutput {
public MetricDaoAdapter(ActiveMetric metric) { public MetricDaoAdapter(ActiveMetric metric) {
this.metric = metric; this.metric = metric;
this.md = new MetricDescription(MetricOutputDAO.class.getName(), this.md = new MetricDescription(MetricOutputDAO.class.getName(), metric.getName(), metric.getDescription(),
metric.getName(), metric.getDescription(),
metric.getUnit().toString()); metric.getUnit().toString());
this.hosts = GlobalOracle.getHosts(); this.hosts = GlobalOracle.getHosts();
this.writeAggregates = isToAggregate(metric); this.writeAggregates = isToAggregate(metric);
...@@ -197,8 +197,7 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -197,8 +197,7 @@ public class MetricOutputDAO extends AbstractOutput {
String groupId = simHost.getProperties().getGroupID(); String groupId = simHost.getProperties().getGroupID();
if (!this.hostsByGroup.containsKey(groupId)) { if (!this.hostsByGroup.containsKey(groupId)) {
this.hostsByGroup.put(groupId, new LinkedList<>()); this.hostsByGroup.put(groupId, new LinkedList<>());
this.globalStatsByGroup.put(groupId, this.globalStatsByGroup.put(groupId, new DescriptiveStatistics());
new DescriptiveStatistics());
} }
this.hostsByGroup.get(groupId).add(simHost); this.hostsByGroup.get(groupId).add(simHost);
} }
...@@ -206,12 +205,9 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -206,12 +205,9 @@ public class MetricOutputDAO extends AbstractOutput {
public void onStop() { public void onStop() {
if (writeAggregates) { if (writeAggregates) {
for (Entry<String, DescriptiveStatistics> groupData : globalStatsByGroup for (Entry<String, DescriptiveStatistics> groupData : globalStatsByGroup.entrySet()) {
.entrySet()) { MeasurementDAO.storeGroupStatisticsMeasurement(md, groupData.getKey(), Time.getCurrentTime(),
MeasurementDAO.storeGroupStatisticsMeasurement(md, groupData.getValue(), Time.getCurrentTime() - timeEnableDao, true);
groupData.getKey(), Time.getCurrentTime(),
groupData.getValue(),
Time.getCurrentTime() - timeEnableDao, true);
} }
globalStatsByGroup.clear(); globalStatsByGroup.clear();
} }
...@@ -239,24 +235,20 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -239,24 +235,20 @@ public class MetricOutputDAO extends AbstractOutput {
// per-host metric // per-host metric
if (writeAggregates) { if (writeAggregates) {
/* /*
* Write aggregates instead of individual metric values. * Write aggregates instead of individual metric values. This can be improved
* This can be improved w.r.t. performance, but currently we * w.r.t. performance, but currently we do not really care.
* do not really care.
*/ */
// Iterate over groups // Iterate over groups
for (String group : hostsByGroup.keySet()) { for (String group : hostsByGroup.keySet()) {
DescriptiveStatistics stats = new DescriptiveStatistics(); DescriptiveStatistics stats = new DescriptiveStatistics();
DescriptiveStatistics globalStats = globalStatsByGroup DescriptiveStatistics globalStats = globalStatsByGroup.get(group);
.get(group);
for (SimHost host : hostsByGroup.get(group)) { for (SimHost host : hostsByGroup.get(group)) {
MetricValue mv = metric MetricValue mv = metric.getPerHostMetric(host.getId());
.getPerHostMetric(host.getId());
if (mv != null) { if (mv != null) {
Object val = mv.getValue(); Object val = mv.getValue();
if (mv.isValid()) { if (mv.isValid()) {
if (val instanceof Number) { if (val instanceof Number) {
double vd = ((Number) val) double vd = ((Number) val).doubleValue();
.doubleValue();
if (Double.isNaN(vd)) { if (Double.isNaN(vd)) {
continue; continue;
} }
...@@ -268,14 +260,12 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -268,14 +260,12 @@ public class MetricOutputDAO extends AbstractOutput {
} }
} }
// Write Group stats // Write Group stats
long observationDuration = Time.getCurrentTime() long observationDuration = Time.getCurrentTime() - timestampLastEvent;
- timestampLastEvent;
if (timestampLastEvent == -1) { if (timestampLastEvent == -1) {
observationDuration = Time.getCurrentTime() observationDuration = Time.getCurrentTime() - timeEnableDao;
- timeEnableDao;
} }
MeasurementDAO.storeGroupStatisticsMeasurement(md, MeasurementDAO.storeGroupStatisticsMeasurement(md, group, time, stats, observationDuration,
group, time, stats, observationDuration, false); false);
} }
timestampLastEvent = Time.getCurrentTime(); timestampLastEvent = Time.getCurrentTime();
} else { } else {
...@@ -289,8 +279,7 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -289,8 +279,7 @@ public class MetricOutputDAO extends AbstractOutput {
if (Double.isNaN(vd)) { if (Double.isNaN(vd)) {
continue; continue;
} }
dao.storeSingleMeasurement(md, dao.storeSingleMeasurement(md, host.getHostId(), time, vd);
host.getHostId(), time, vd);
} }
} }
} }
...@@ -302,7 +291,8 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -302,7 +291,8 @@ public class MetricOutputDAO extends AbstractOutput {
} }
/** /**
* This class helps in persisting a spatial metric using the {@link MeasurementDAO} * This class helps in persisting a spatial metric using the
* {@link MeasurementDAO}
* *
* @author Tobias Meuser * @author Tobias Meuser
* @version 1.0, 10.10.2018 * @version 1.0, 10.10.2018
...@@ -319,11 +309,16 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -319,11 +309,16 @@ public class MetricOutputDAO extends AbstractOutput {
private final Map<String, DescriptiveStatistics> globalStatsByGroup; private final Map<String, DescriptiveStatistics> globalStatsByGroup;
private double spatialResolution = 20; private Map<GridKey, Double> values = new HashMap<>();
private long lastUpdate = -1;
private final double spatialResolution;
private ActiveSpatialMetric<?> metric;
public SpatialMetricDaoAdapter(ActiveSpatialMetric metric) { public SpatialMetricDaoAdapter(ActiveSpatialMetric metric) {
this.md = new MetricDescription(MetricOutputDAO.class.getName(), this.metric = metric;
metric.getName(), metric.getDescription(), this.md = new MetricDescription(MetricOutputDAO.class.getName(), metric.getName(), metric.getDescription(),
metric.getUnit().toString()); metric.getUnit().toString());
this.hosts = GlobalOracle.getHosts(); this.hosts = GlobalOracle.getHosts();
this.hostsByGroup = new LinkedHashMap<>(); this.hostsByGroup = new LinkedHashMap<>();
...@@ -332,16 +327,26 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -332,16 +327,26 @@ public class MetricOutputDAO extends AbstractOutput {
String groupId = simHost.getProperties().getGroupID(); String groupId = simHost.getProperties().getGroupID();
if (!this.hostsByGroup.containsKey(groupId)) { if (!this.hostsByGroup.containsKey(groupId)) {
this.hostsByGroup.put(groupId, new LinkedList<>()); this.hostsByGroup.put(groupId, new LinkedList<>());
this.globalStatsByGroup.put(groupId, this.globalStatsByGroup.put(groupId, new DescriptiveStatistics());
new DescriptiveStatistics());
} }
this.hostsByGroup.get(groupId).add(simHost); this.hostsByGroup.get(groupId).add(simHost);
} }
spatialResolution = metric.getResolution();
} }
@Override @Override
public void onStop() { public void onStop() {
// Noting to do here store();
}
private void store() {
for (Entry<GridKey, Double> entry : values.entrySet()) {
dao.storeGlobalSpatialMeasurement(md, lastUpdate, entry.getValue(), entry.getKey().getX(),
entry.getKey().getY());
}
values.clear();
lastUpdate = Time.getCurrentTime();
} }
@Override @Override
...@@ -352,7 +357,12 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -352,7 +357,12 @@ public class MetricOutputDAO extends AbstractOutput {
return; return;
} }
if (metric.isOverallMetric()) { if (metric.isOverallMetric()) {
if (!metric.isAggregated() || Time.getCurrentTime() != lastUpdate) {
store();
}
// global // global
SpatialMetricValue mv = metric.getOverallMetric(); SpatialMetricValue mv = metric.getOverallMetric();
Object val = mv.getValue(); Object val = mv.getValue();
...@@ -360,9 +370,16 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -360,9 +370,16 @@ public class MetricOutputDAO extends AbstractOutput {
if (val instanceof Number) { if (val instanceof Number) {
double vd = ((Number) val).doubleValue(); double vd = ((Number) val).doubleValue();
dao.storeGlobalSpatialMeasurement(md, time, vd, GridKey key = new GridKey((int) (mv.getLocation().getLongitude() / spatialResolution),
(int) (mv.getLocation().getLongitude() / spatialResolution),
(int) (mv.getLocation().getLatitude() / spatialResolution)); (int) (mv.getLocation().getLatitude() / spatialResolution));
if (!values.containsKey(key)) {
values.put(key, vd);
} else {
double storedValue = values.get(key);
if (storedValue < vd) {
values.put(key, vd);
}
}
} }
} }
} else { } else {
...@@ -385,7 +402,37 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -385,7 +402,37 @@ public class MetricOutputDAO extends AbstractOutput {
} }
} }
} }
}
private class GridKey {
private final int x;
private final int y;
public GridKey(int pX, int pY) {
x = pX;
y = pY;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public int hashCode() {
return Integer.hashCode(x) << 16 + Integer.hashCode(y);
}
@Override
public boolean equals(Object pObj) {
if (pObj instanceof GridKey) {
return x == ((GridKey) pObj).x && y == ((GridKey) pObj).y;
}
return false;
}
} }
} }
...@@ -29,6 +29,8 @@ import de.tudarmstadt.maki.simonstrator.api.common.metric.Metric; ...@@ -29,6 +29,8 @@ import de.tudarmstadt.maki.simonstrator.api.common.metric.Metric;
public abstract class AbstractSpatialMetric<T extends AbstractSpatialMetricValue<?>> extends AbstractMetric<T> implements Metric<T>, ActiveSpatialMetric<T> { public abstract class AbstractSpatialMetric<T extends AbstractSpatialMetricValue<?>> extends AbstractMetric<T> implements Metric<T>, ActiveSpatialMetric<T> {
protected boolean aggregate = false;
public AbstractSpatialMetric(String pDescription, MetricUnit pUnit) { public AbstractSpatialMetric(String pDescription, MetricUnit pUnit) {
super(pDescription, pUnit); super(pDescription, pUnit);
} }
...@@ -42,6 +44,11 @@ public abstract class AbstractSpatialMetric<T extends AbstractSpatialMetricValue ...@@ -42,6 +44,11 @@ public abstract class AbstractSpatialMetric<T extends AbstractSpatialMetricValue
super.setOverallMetric(aggregate); super.setOverallMetric(aggregate);
} }
@Override
public boolean isAggregated() {
return aggregate;
}
private List<ActiveSpatialMetricListener> _listeners = new ArrayList<>(); private List<ActiveSpatialMetricListener> _listeners = new ArrayList<>();
@Override @Override
......
...@@ -75,9 +75,6 @@ public class VehicleMovementModel implements MovementModel, EventHandler { ...@@ -75,9 +75,6 @@ public class VehicleMovementModel implements MovementModel, EventHandler {
private final int width; private final int width;
private final int height; private final int height;
private double scenarioWidth = 0;
private double scenarioHeight = 0;
private final String sumoExe; private final String sumoExe;
private final String sumoConfigFile; private final String sumoConfigFile;
private final String sumoTrace; private final String sumoTrace;
...@@ -269,9 +266,6 @@ public class VehicleMovementModel implements MovementModel, EventHandler { ...@@ -269,9 +266,6 @@ public class VehicleMovementModel implements MovementModel, EventHandler {
_extractor = simulationController; _extractor = simulationController;
} }
scenarioWidth = _extractor.getScenarioWidth();
scenarioHeight = _extractor.getScenarioHeight();
System.out.println("Initialization: done."); System.out.println("Initialization: done.");
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment