Commit fdbd3c23 authored by Clemens Krug's avatar Clemens Krug
Browse files

Merge remote-tracking branch 'remotes/origin/master' into nr/resAlloc-clemens

# Conflicts:
#	src/de/tud/kom/p2psim/impl/topology/movement/modularosm/ModularMovementModel.java
#	src/de/tud/kom/p2psim/impl/topology/movement/modularosm/ModularMovementModelViz.java
parents c5beb3fb 4dabbcdd
......@@ -206,7 +206,9 @@ public abstract class AbstractFilter<M extends MetricValue<?>> implements
if (isOverallMetric) {
M overall = getDerivedMetricValueFor(DerivedMetric.this,
incoming, null);
setOverallMetric(overall);
if (overall != null) {
setOverallMetric(overall);
}
} else {
for (Host host : hosts) {
M perHost = getDerivedMetricValueFor(DerivedMetric.this,
......
......@@ -83,14 +83,17 @@ public abstract class StatisticsFilter extends
Metric<?> derivedMetric, List<Metric<?>> inputs, Host host) {
assert inputs.size() == 1;
assert host == null;
Metric<?> input = inputs.get(0);
Metric<? extends MetricValue<?>> input = inputs.get(0);
if (input.isOverallMetric()) {
throw new AssertionError(
"Only available for per-host input metrics.");
}
LinkedList<MetricValue> mvs = new LinkedList<MetricValue>(
input.getAllPerHostMetrics());
return new StatisticsMetricValue(mvs);
List<? extends MetricValue<?>> values = input.getAllPerHostMetrics();
if (values == null || values.isEmpty()) {
return null;
}
LinkedList<MetricValue> mvs = new LinkedList<MetricValue>(values);
return new StatisticsMetricValue(mvs);
}
/**
......
......@@ -20,7 +20,14 @@
package de.tud.kom.p2psim.impl.analyzer.metric.output;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.impl.util.db.dao.DAO;
......@@ -47,6 +54,8 @@ public class MetricOutputDAO extends AbstractOutput {
protected long timeStopDao = Long.MAX_VALUE;
protected Set<String> metricsToAggregate = new LinkedHashSet<>();
/**
*
* @param table
......@@ -72,6 +81,18 @@ public class MetricOutputDAO extends AbstractOutput {
this.timeStopDao = timeStopDao;
}
/**
* 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
* is defined by the hostGroup from the XML-config.
*
* @param metricsToAggregate
*/
public void setToAggregate(String[] metricsToAggregate) {
for (String metric : metricsToAggregate) {
this.metricsToAggregate.add(metric);
}
}
@Override
public void onInitialize(List<Metric> metrics) {
......@@ -111,12 +132,25 @@ public class MetricOutputDAO extends AbstractOutput {
private final List<SimHost> hosts;
private final boolean writeAggregates;
private final Map<String, List<SimHost>> hostsByGroup;
public MetricDaoAdapter(ActiveMetric metric) {
this.metric = metric;
this.md = new MetricDescription(MetricOutputDAO.class.getName(),
metric.getName(), metric.getDescription(), metric.getUnit()
.toString());
metric.getName(), metric.getDescription(),
metric.getUnit().toString());
this.hosts = GlobalOracle.getHosts();
writeAggregates = metricsToAggregate.contains(metric.getName());
this.hostsByGroup = new LinkedHashMap<>();
for (SimHost simHost : hosts) {
String groupId = simHost.getProperties().getGroupID();
if (!this.hostsByGroup.containsKey(groupId)) {
this.hostsByGroup.put(groupId, new LinkedList<>());
}
this.hostsByGroup.get(groupId).add(simHost);
}
}
@Override
......@@ -139,18 +173,51 @@ public class MetricOutputDAO extends AbstractOutput {
}
} else {
// per-host metric
for (SimHost host : hosts) {
MetricValue mv = metric.getPerHostMetric(host.getId());
if (mv != null) {
Object val = mv.getValue();
if (mv.isValid()) {
if (val instanceof Number) {
double vd = ((Number) val).doubleValue();
if (Double.isNaN(vd)) {
continue;
if (writeAggregates) {
/*
* Write aggregates instead of individual metric values.
* This can be improved w.r.t. performance, but currently we
* do not really care.
*/
// Iterate over groups
for (String group : hostsByGroup.keySet()) {
DescriptiveStatistics stats = new DescriptiveStatistics();
for (SimHost host : hostsByGroup.get(group)) {
MetricValue mv = metric
.getPerHostMetric(host.getId());
if (mv != null) {
Object val = mv.getValue();
if (mv.isValid()) {
if (val instanceof Number) {
double vd = ((Number) val)
.doubleValue();
if (Double.isNaN(vd)) {
continue;
}
// Add value
stats.addValue(vd);
}
}
}
}
// Write Group stats
MeasurementDAO.storeGroupStatisticsMeasurement(md,
group, time, stats);
}
} else {
for (SimHost host : hosts) {
MetricValue mv = metric.getPerHostMetric(host.getId());
if (mv != null) {
Object val = mv.getValue();
if (mv.isValid()) {
if (val instanceof Number) {
double vd = ((Number) val).doubleValue();
if (Double.isNaN(vd)) {
continue;
}
dao.storeSingleMeasurement(md,
host.getHostId(), time, vd);
}
dao.storeSingleMeasurement(md,
host.getHostId(), time, vd);
}
}
}
......
......@@ -271,27 +271,36 @@ public class DefaultConfigurator implements Configurator {
if (elem.getName().equalsIgnoreCase(FAKE_CONTAINER_ELEMENT)) {
configureFirstLevel(elem);
} else if (elem.getName().equals(Configurator.DEFAULT_TAG)) {
for (Iterator iter = elem
.elementIterator(); iter
.hasNext();) {
Element variable = (Element) iter.next();
if (variable != null) {
String name = variable
.attributeValue(Configurator.VARIABLE_NAME_TAG);
String value = variable
.attributeValue(Configurator.VARIABLE_VALUE_TAG);
if (!variables.containsKey(name)) {
// set to default only if not set yet
variables.put(name, parseValue(value));
}
}
}
configureDefaults(elem);
} else {
configureComponent(elem);
}
}
}
/**
* Processes a <code><Default></code> Tag by setting the respective
* variables.
*
* @param defaultElement
*/
private void configureDefaults(Element elem) {
assert elem.getName().equals(Configurator.DEFAULT_TAG);
for (Iterator iter = elem.elementIterator(); iter.hasNext();) {
Element variable = (Element) iter.next();
if (variable != null) {
String name = variable
.attributeValue(Configurator.VARIABLE_NAME_TAG);
String value = variable
.attributeValue(Configurator.VARIABLE_VALUE_TAG);
if (!variables.containsKey(name)) {
// set to default only if not set yet
variables.put(name, parseValue(value));
}
}
}
}
/**
* Create (if not existent yet) and configure a configurable component by
* parsing the XML subtree.
......@@ -301,7 +310,7 @@ public class DefaultConfigurator implements Configurator {
* @return configured component
*/
public Object configureComponent(Element elem) {
String name = elem.getName();
if (Configurator.SPECIAL_IF_EQUAL_STR.equalsIgnoreCase(name)) {
processIfEqualStr(elem, new ToConfigureCallback() {
......@@ -323,6 +332,18 @@ public class DefaultConfigurator implements Configurator {
return null;
}
/*
* FIXED (BR) Workaround to support DEFAULT-tags within IF-blocks (i.e.,
* as non-first-level elements). The additional check for the CLASS-tag
* prevents setDefault setters with custom classes from stopping to
* work.
*/
if (Configurator.DEFAULT_TAG.equalsIgnoreCase(name)
&& elem.attribute(CLASS_TAG) == null) {
configureDefaults(elem);
return null;
}
Monitor.log(DefaultConfigurator.class, Level.DEBUG,
"Configure component " + name);
......@@ -343,8 +364,8 @@ public class DefaultConfigurator implements Configurator {
if (component != null) {
Monitor.log(DefaultConfigurator.class, Level.INFO,
"Configure component "
+ component.getClass().getSimpleName() + " with element "
+ name);
+ component.getClass().getSimpleName()
+ " with element " + name);
configureAttributes(component, elem, consAttrs);
// configure subcomponents
if (component instanceof Builder) {
......@@ -362,8 +383,8 @@ public class DefaultConfigurator implements Configurator {
}
} else {
// component cannot be created and has not been registered
Monitor.log(DefaultConfigurator.class, Level.WARN, "Skip element "
+ name);
Monitor.log(DefaultConfigurator.class, Level.WARN,
"Skip element " + name);
}
return component;
}
......@@ -375,8 +396,7 @@ public class DefaultConfigurator implements Configurator {
Object component;
String className = getAttributeValue(elem.attribute(CLASS_TAG));
Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Create component "
+ className + " with element "
+ elem.getName());
+ className + " with element " + elem.getName());
component = createInstance(className,
getAttributeValue(elem.attribute(STATIC_CREATION_METHOD_TAG)),
consAttrs, elem);
......@@ -442,29 +462,30 @@ public class DefaultConfigurator implements Configurator {
for (int i = 0; i < methods.length; i++) {
if (methodName.equals(methods[i].getName())) {
match = methods[i];
Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Match "
+ match);
Monitor.log(DefaultConfigurator.class, Level.DEBUG,
"Match " + match);
break;
}
}
if (match == null) {
Monitor.log(DefaultConfigurator.class, Level.WARN, "Cannot set "
+ subcomponent + " as there is no method "
+ methodName + " declared in " + component);
throw new ConfigurationException("Cannot set " + subcomponent
+ " as there is no method " + methodName + " declared in "
+ component);
Monitor.log(DefaultConfigurator.class, Level.WARN,
"Cannot set " + subcomponent + " as there is no method "
+ methodName + " declared in " + component);
throw new ConfigurationException(
"Cannot set " + subcomponent + " as there is no method "
+ methodName + " declared in " + component);
} else {
Class[] types = match.getParameterTypes();
Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Param types"
+ Arrays.asList(types));
Monitor.log(DefaultConfigurator.class, Level.DEBUG,
"Param types" + Arrays.asList(types));
if (types.length == 1) {
try {
match.invoke(component, types[0].cast(subcomponent));
} catch (Exception e) {
throw new ConfigurationException("Failed to configure "
+ methodName + " in " + component + " with "
+ subcomponent, e);
throw new ConfigurationException(
"Failed to configure " + methodName + " in "
+ component + " with " + subcomponent,
e);
}
} else {
throw new ConfigurationException("Wrong number of params for "
......@@ -507,11 +528,10 @@ public class DefaultConfigurator implements Configurator {
} else {
Monitor.log(DefaultConfigurator.class,
Level.ERROR,
"Found two possible methods "
+ method + " and " + methods[i]);
"Found two possible methods " + method
+ " and " + methods[i]);
throw new IllegalArgumentException(
"Cannot set property "
+ name
"Cannot set property " + name
+ " as there are more than one matching methods in "
+ classToConfigure);
}
......@@ -525,7 +545,8 @@ public class DefaultConfigurator implements Configurator {
*/
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals("setProperty")
&& methods[i].getParameterTypes().length == 2) {
&& methods[i]
.getParameterTypes().length == 2) {
method = methods[i];
}
}
......@@ -541,8 +562,7 @@ public class DefaultConfigurator implements Configurator {
* Still nothing?
*/
throw new IllegalArgumentException(
"Cannot set property "
+ name
"Cannot set property " + name
+ " as there are no matching methods in class "
+ classToConfigure);
}
......@@ -554,7 +574,8 @@ public class DefaultConfigurator implements Configurator {
} catch (Exception e) {
throw new ConfigurationException(
"Failed to set the property " + name + " in "
+ component, e);
+ component,
e);
}
}
}
......@@ -607,8 +628,8 @@ public class DefaultConfigurator implements Configurator {
}
param = lvals;
} else {
throw new IllegalArgumentException("Parameter type " + typeClass
+ " is not supported");
throw new IllegalArgumentException(
"Parameter type " + typeClass + " is not supported");
}
return param;
}
......@@ -635,8 +656,8 @@ public class DefaultConfigurator implements Configurator {
String value = attr.getValue();
value = parseValue(value);
if (value == null)
throw new IllegalStateException("Variable " + attr.getValue()
+ " has not been set");
throw new IllegalStateException(
"Variable " + attr.getValue() + " has not been set");
return value;
}
......@@ -738,12 +759,11 @@ public class DefaultConfigurator implements Configurator {
break;
}
consArgs[i] = configureComponent(elem);
if (consArgs[i].getClass().isAssignableFrom(
types[i]))
if (consArgs[i].getClass()
.isAssignableFrom(types[i]))
throw new ConfigurationException(
"The type of the component configured for the parameter '"
+ cArgs[i]
+ "', type is "
+ cArgs[i] + "', type is "
+ consArgs[i].getClass()
.getSimpleName()
+ " and is not equal to the type "
......@@ -771,15 +791,16 @@ public class DefaultConfigurator implements Configurator {
component = forName.newInstance();
} else
component = forName.getDeclaredMethod(staticMethod,
new Class[0]).invoke(null, new Object[0]);
component = forName
.getDeclaredMethod(staticMethod, new Class[0])
.invoke(null, new Object[0]);
componentList.add(component);
return component;
} catch (Exception e) {
throw new ConfigurationException("Failed to create configurable "
+ className, e);
throw new ConfigurationException(
"Failed to create configurable " + className, e);
}
}
......@@ -791,8 +812,8 @@ public class DefaultConfigurator implements Configurator {
*/
public void setVariables(Map<String, String> variables) {
if (variables.size() != 0) {
Monitor.log(DefaultConfigurator.class, Level.WARN, "Set variables "
+ variables);
Monitor.log(DefaultConfigurator.class, Level.WARN,
"Set variables " + variables);
}
this.variables.putAll(variables);
}
......@@ -835,8 +856,8 @@ public class DefaultConfigurator implements Configurator {
factor *= Time.SECOND;
break;
default:
throw new IllegalStateException("time unit " + unit
+ " is not allowed");
throw new IllegalStateException(
"time unit " + unit + " is not allowed");
}
}
}
......@@ -870,7 +891,7 @@ public class DefaultConfigurator implements Configurator {
throw new IllegalStateException("Invalid memory unit.");
}
}
// Convert type
double dNum = Double.valueOf(number);
if (targetClass.equals(Integer.class)) {
......@@ -907,9 +928,11 @@ public class DefaultConfigurator implements Configurator {
String arg1p = parseValue(arg1);
if (arg0p == null)
throw new RuntimeException("Variable " + arg0 + " not set or null.");
throw new RuntimeException(
"Variable " + arg0 + " not set or null.");
if (arg1p == null)
throw new RuntimeException("Variable " + arg1 + " not set or null.");
throw new RuntimeException(
"Variable " + arg1 + " not set or null.");
if (arg0p.equals(arg1p)) {
......@@ -917,7 +940,7 @@ public class DefaultConfigurator implements Configurator {
if (!iter.hasNext())
Monitor.log(DefaultConfigurator.class, Level.WARN,
"No component to configure in the ifEqualStr-clause (arg0="
+ arg0 + ", arg1=" + arg1 + ").");
+ arg0 + ", arg1=" + arg1 + ").");
else {
while (iter.hasNext()) {
Element child = (Element) iter.next();
......@@ -947,9 +970,11 @@ public class DefaultConfigurator implements Configurator {
String arg1p = parseValue(arg1);
if (arg0p == null)
throw new RuntimeException("Variable " + arg0 + " not set or null.");
throw new RuntimeException(
"Variable " + arg0 + " not set or null.");
if (arg1p == null)
throw new RuntimeException("Variable " + arg1 + " not set or null.");
throw new RuntimeException(
"Variable " + arg1 + " not set or null.");
if (!arg0p.equals(arg1p)) {
......@@ -957,7 +982,7 @@ public class DefaultConfigurator implements Configurator {
if (!iter.hasNext())
Monitor.log(DefaultConfigurator.class, Level.WARN,
"No component to configure in the ifNotEqualStr-clause (arg0="
+ arg0 + ", arg1=" + arg1 + ").");
+ arg0 + ", arg1=" + arg1 + ").");
else {
while (iter.hasNext()) {
Element child = (Element) iter.next();
......@@ -967,8 +992,6 @@ public class DefaultConfigurator implements Configurator {
}
}
/**
* Gets the parsed XML-Configuration File. So are the included tags
* resolved.
......@@ -1006,16 +1029,16 @@ public class DefaultConfigurator implements Configurator {
return "Cannot parse/read the configuration";
}
@Override
public List<Object> getConfigurable(Class type) {
List<Object> components = Lists.newArrayList();
for (Object obj : configurables.values()) {
if (type.isAssignableFrom(obj.getClass())) {
components.add(obj);
}
}
return components;
}
@Override
public List<Object> getConfigurable(Class type) {
List<Object> components = Lists.newArrayList();
for (Object obj : configurables.values()) {
if (type.isAssignableFrom(obj.getClass())) {
components.add(obj);
}
}
return components;
}
protected interface ToConfigureCallback {
public void run(Element elemToConfigure);
......
......@@ -36,11 +36,9 @@ public class LinearMovement extends AbstractLocalMovementStrategy {
public Either<PositionVector, Boolean> nextPosition(SimLocationActuator comp,
PositionVector destination) {
PositionVector newPosition;
PositionVector newPosition = null;
if (destination
.distanceTo(comp.getRealPosition()) < getMovementSpeed(comp)) {
newPosition = destination.clone();
} else {
.distanceTo(comp.getRealPosition()) > getMovementSpeed(comp)) {
newPosition = comp.getRealPosition().moveStep(destination, getMovementSpeed(comp));
}
return new Left<PositionVector, Boolean>(newPosition);
......
......@@ -81,7 +81,7 @@ public class RealWorldStreetsMovement extends AbstractLocalMovementStrategy {
hopper = new GraphHopper().forServer();
hopper.setOSMFile(osmFileLocation);
// where to store graphhopper files?
hopper.setGraphHopperLocation(graphFolderFiles+"/"+osmFileLocation.hashCode());
hopper.setGraphHopperLocation(graphFolderFiles+"/"+osmFileLocation.hashCode()+movementType);
hopper.setEncodingManager(new EncodingManager(movementType));
hopper.importOrLoad();
init = true;
......
......@@ -39,6 +39,20 @@ public class GPSCalculation {
private static double scaleFactor;
/*
* http://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-
* latitude-longitude-by-some-amount-of-meters
*
* If your displacements aren't too great (less than a few kilometers) and
* you're not right at the poles, use the quick and dirty estimate that
* 111,111 meters (111.111 km) in the y direction is 1 degree (of latitude)
* and 111,111 * cos(latitude) meters in the x direction is 1 degree (of
* longitude).
*
* -> Latitude: 1m = 1 deg / 111111
*/
private static double scaleLon;
public GPSCalculation() {
}
......@@ -49,7 +63,6 @@ public class GPSCalculation {
* case, 1px == 1m) - this way, the world-size specified in the configs
* is valid on all zoom levels.
*/
this.scaleFactor = 0.125;
// 17: 2, 16: 1, 15: 0.5, 14: 0.25
VisualizationInjector.setScale(Math.pow(2.0d, (zoom - 16)));
}
......@@ -67,31 +80,45 @@ public class GPSCalculation {
}
public static double getLatUpper() {
return latCenter + scaleFactor * 0.027613 * Binder
.getComponentOrNull(Topology.class).getWorldDimensions().getY()
/ 1000;
return latCenter + (Binder.getComponentOrNull(Topology.class)
.getWorldDimensions().getY() / 111111d) * scaleFactor;
// return latCenter + scaleFactor * 0.027613 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getY()
// / 1000;
}
public static double getLatLower() {
return latCenter - scaleFactor * 0.027613 * Binder
.getComponentOrNull(Topology.class).getWorldDimensions().getY()
/ 1000;
return latCenter - (Binder.getComponentOrNull(Topology.class)
.getWorldDimensions().getY() / 111111d) * scaleFactor;
// return latCenter - scaleFactor * 0.027613 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getY()
// / 1000;
}
public static double getLonLeft() {
return lonCenter - scaleFactor * 0.0419232 * Binder
.getComponentOrNull(Topology.class).getWorldDimensions().getX()
/ 1000;
return lonCenter - (Binder.getComponentOrNull(Topology.class)
.getWorldDimensions().getX() / 111111d / scaleLon) * scaleFactor;
// return lonCenter - scaleFactor * 0.043 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getX()
// / 1000;
}
public static double getLonRight() {
return lonCenter + scaleFactor * 0.0419232 * Binder
.getComponentOrNull(Topology.class).getWorldDimensions().getX()
/ 1000;
return lonCenter + (Binder.getComponentOrNull(Topology.class)
.getWorldDimensions().getX() / 111111d / scaleLon) * scaleFactor;
// return lonCenter + scaleFactor * 0.043 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getX()
// / 1000;
}
public void setLatCenter(double latCenter) {
this.latCenter = latCenter;
this.scaleLon = Math.cos(Math.toRadians(latCenter));
this.scaleFactor = 0.38d;
}
public void setLonCenter(double lonCenter) {
......
......@@ -43,6 +43,7 @@ import de.tud.kom.p2psim.impl.topology.TopologyFactory;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.mapvisualization.IMapVisualization;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy.AttractionAssignmentListener;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import de.tud.kom.p2psim.impl.util.Either;
......@@ -50,6 +51,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationActuator;
......@@ -94,7 +96,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationAc
* @author Martin Hellwig, Christoph Muenker
* @version 1.0, 07.07.2015
*/
public class ModularMovementModel implements MovementModel, EventHandler {
public class ModularMovementModel implements MovementModel, EventHandler, AttractionAssignmentListener {
private final int EVENT_MOVE = 1;
......@@ -114,7 +116,7 @@ public class ModularMovementModel implements MovementModel, EventHandler {
private Set<SimLocationActuator> moveableHosts = new LinkedHashSet<SimLocationActuator>();
private Map<SimLocationActuator, PositionVector> offsetPosition = new LinkedHashMap<SimLocationActuator, PositionVector>();
private Map<SimLocationActuator, PositionVector> currentTarget = new LinkedHashMap<>();
private boolean initialized = false;
......@@ -154,9 +156,16 @@ public class ModularMovementModel implements MovementModel, EventHandler {
localMovementStrategy.setWaypointModel(Binder
.getComponentOrNull(Topology.class).getWaypointModel());
/*
* Scale depending on calculation interval, if interval != 1 Second.
*/
localMovementStrategy
.setScaleFactor(timeBetweenMoveOperation / (double) Time.SECOND);
List<AttractionPoint> attractionPoints = attractionGenerator
.getAttractionPoints();
transition.setAttractionPoints(attractionPoints);
transition.addAttractionAssignmentListener(this);
// This adds the mobile hosts (smartphones/users) to the transition
// strategy
......@@ -189,7 +198,7 @@ public class ModularMovementModel implements MovementModel, EventHandler {
@Override
public AttractionPoint getTargetLocation(SimLocationActuator actuator) {
return transition.getAssignments().get(actuator);
return transition.getAssignment(actuator);
}
@Override
......@@ -216,7 +225,6 @@ public class ModularMovementModel implements MovementModel, EventHandler {
@Override
public void addComponent(SimLocationActuator comp) {
moveableHosts.add(comp);
offsetPosition.put(comp, randomOffsetVector());
}
public Set<SimLocationActuator> getAllLocationActuators() {
......@@ -233,27 +241,48 @@ public class ModularMovementModel implements MovementModel, EventHandler {
}
}
private PositionVector randomOffsetVector() {
double x = rand.nextGaussian() * 6;
double y = rand.nextGaussian() * 6;
@Override
public void updatedAttractionAssignment(SimLocationActuator component,
AttractionPoint newAssignment) {
/*
* Use this method to calculate the offset and target location for a
* host.
*/
PositionVector attractionCenter = (PositionVector) newAssignment;
PositionVector destination = null;
int tries = 0;
do {
destination = new PositionVector(attractionCenter);
// Gaussian with std = 1 --> >99% of nodes
PositionVector offset = new PositionVector(
rand.nextGaussian() * newAssignment.getRadius() / 3,
rand.nextGaussian() * newAssignment.getRadius() / 3);
destination.add(offset);
// Check constraints
if (destination.getX() < 0.0
|| destination.getX() > Binder
.getComponentOrNull(Topology.class)
.getWorldDimensions().getX() || destination.getY() < 0.0
|| destination.getY() > Binder
.getComponentOrNull(Topology.class)
.getWorldDimensions().getY()) {
destination = null;
if (tries > 100) {
throw new AssertionError("Unable to find a valid target destination within <100 tries.");
}
}
tries++;
} while (destination == null);
return new PositionVector(x, y);
currentTarget.put(component, destination);
}
protected void move() {
Map<SimLocationActuator, AttractionPoint> assigns = transition
.getAssignments();
for (Entry<SimLocationActuator, AttractionPoint> entry : assigns
.entrySet()) {
SimLocationActuator ms = entry.getKey();
PositionVector attractionCenter = (PositionVector) entry.getValue();
PositionVector destination = new PositionVector(attractionCenter);
destination.add(offsetPosition.get(ms));
doLocalMovement(ms, destination);
for (SimLocationActuator component : moveableHosts) {
assert currentTarget.containsKey(component);
doLocalMovement(component, currentTarget.get(component));
}
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null,
EVENT_MOVE);
}
......@@ -331,6 +360,4 @@ public class ModularMovementModel implements MovementModel, EventHandler {
public List<AttractionPoint> getAttractionPoints() {
return new Vector<AttractionPoint>(transition.getAllAttractionPoints());
}
}
......@@ -62,7 +62,7 @@ public class ModularMovementModelViz extends JComponent
private final static int NODE_PAD = 2;
private final static int ATTR_PAD = 10;
private final static int ATTR_PAD = 5;
private static Color COLOR_ATTR_POINT = Color.decode("#4A7B9D");
......@@ -159,11 +159,17 @@ public class ModularMovementModelViz extends JComponent
VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
VisualizationInjector.scaleValue(point.y) - ATTR_PAD);
g2.setColor(COLOR_ATTR_POINT);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
float alpha = 0.25f + (float) (aPoint.getWeight() / 2);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
g2.fillOval(
VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
VisualizationInjector.scaleValue(point.y) - ATTR_PAD,
ATTR_PAD * 2 + 1, ATTR_PAD * 2 + 1);
g2.setColor(COLOR_ATTR_POINT);
int radius = (int) aPoint.getRadius() + ATTR_PAD;
g2.drawOval(VisualizationInjector.scaleValue(point.x) - radius,
VisualizationInjector.scaleValue(point.y) - radius,
radius * 2 + 1, radius * 2 + 1);
}
}
......
......@@ -7,6 +7,9 @@ This movement model can load map-data from different sources (OpenStreetMap-data
+ Change parameters of the simulation. E.g. which map-provider provides the map-data or which type of POIs (Points of Interest) should be loaded. The whole configuration part is made in the file "config/social/SocialTest.xml"
+ In the folder "osm" are some files. Some files can be loaded from the project, some are temporary files and some are cached values, which can be reused at the next start
OSM-PBF-files for Darmstadt: http://download.bbbike.org/osm/bbbike/Darmstadt/
General: http://download.bbbike.org/osm/bbbike/
## Configuration via SocialTest.xml
......
......@@ -110,8 +110,15 @@ public class JSONAttractionGenerator implements IAttractionGenerator {
String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name");
double lat = allPOI.getJSONObject(i).getDouble("lat");
double lon = allPOI.getJSONObject(i).getDouble("lon");
AttractionPointImpl ap;
if(lat > latLeft && lat < latRight &&
lon > lonLeft && lon < lonRight) attractionPoints.add(new AttractionPointImpl(barname, transformGPSWindowToOwnWorld(lat, lon)));
lon > lonLeft && lon < lonRight) {
ap = new AttractionPointImpl(barname, transformGPSWindowToOwnWorld(lat, lon));
attractionPoints.add(ap);
// the following is allowed to fail.
ap.setWeight(allPOI.getJSONObject(i).getJSONObject("tags").getDouble("weight"));
ap.setRadius(allPOI.getJSONObject(i).getJSONObject("tags").getDouble("radius"));
}
}
catch (JSONException e) {
//This bar had no name defined, so there was an error. Not so bad
......
......@@ -33,6 +33,7 @@ import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.common.SimHostComponent;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy.AttractionAssignmentListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/**
......@@ -58,9 +59,11 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
private Map<AttractionPoint, String> mappingAPGroupId = new LinkedHashMap<AttractionPoint, String>();
private List<AttractionAssignmentListener> listeners = new LinkedList<>();
@Override
public Map<SimLocationActuator, AttractionPoint> getAssignments() {
return new HashMap<SimLocationActuator, AttractionPoint>(assignments);
public AttractionPoint getAssignment(SimLocationActuator comp) {
return assignments.get(comp);
}
@Override
......@@ -73,6 +76,18 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
return aPoints;
}
@Override
public void addAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.add(listener);
}
@Override
public void removeAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.remove(listener);
}
@Override
public void addComponent(SimLocationActuator ms) {
comps.add(ms);
......@@ -105,7 +120,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
throw new Error("Should not happen.");
}
listeners.forEach(listener -> listener.updatedAttractionAssignment(ms, assignments.get(ms)));
}
......@@ -118,6 +133,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
public void updateTargetAttractionPoint(SimLocationActuator comp,
AttractionPoint attractionPoint) {
assignments.put(comp, attractionPoint);
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
}
private void mappingHost(SimLocationActuator ms) {
......
......@@ -21,8 +21,6 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
......@@ -35,23 +33,30 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Attraction
* @version 1.0, 03.07.2015
*/
public interface ITransitionStrategy {
/**
* Returns the assignments of the MovementSupported Objects to the
* AttractionPoints
* Currently assigned attraction point.
*
* @param comp
* @return
*/
public Map<SimLocationActuator, AttractionPoint> getAssignments();
public AttractionPoint getAssignment(SimLocationActuator comp);
public void addAttractionAssignmentListener(AttractionAssignmentListener listener);
public void removeAttractionAssignmentListener(AttractionAssignmentListener listener);
/**
* Should be called first, to add the Attraction Points for the assignment!
*
* @param attractionPoints
*/
public void setAttractionPoints(Collection<AttractionPoint> attractionPoints);
public void setAttractionPoints(
Collection<AttractionPoint> attractionPoints);
/**
* Return a set of all attraction points
*
* @return
*/
public Set<AttractionPoint> getAllAttractionPoints();
......@@ -79,4 +84,18 @@ public interface ITransitionStrategy {
public void updateTargetAttractionPoint(SimLocationActuator comp,
AttractionPoint attractionPoint);
public interface AttractionAssignmentListener {
/**
* Invoked after the assignment of AttractionPoints for the given
* component changed.
*
* @param component
* @param newAssignment
*/
public void updatedAttractionAssignment(SimLocationActuator component,
AttractionPoint newAssignment);
}
}
......@@ -42,6 +42,7 @@ import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tud.kom.p2psim.api.topology.social.SocialView;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy.AttractionAssignmentListener;
import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
......@@ -98,6 +99,8 @@ public class SocialTransitionStrategy
private Map<SimLocationActuator, SimHost> mapMsHost = new HashMap<SimLocationActuator, SimHost>();
private Map<SimHost, SimLocationActuator> mapHostMs = new HashMap<SimHost, SimLocationActuator>();
private List<AttractionAssignmentListener> listeners = new LinkedList<>();
private double minPauseTime = Simulator.MINUTE_UNIT * 0.5;
......@@ -148,11 +151,22 @@ public class SocialTransitionStrategy
}
@Override
public Map<SimLocationActuator, AttractionPoint> getAssignments() {
// FIXME why new? return new HashMap<MovementSupported,
// AttractionPoint>(assignments);
return assignments;
public AttractionPoint getAssignment(SimLocationActuator comp) {
return assignments.get(comp);
}
@Override
public void addAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.add(listener);
}
@Override
public void removeAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.remove(listener);
}
@Override
public void setAttractionPoints(Collection<AttractionPoint> attractionPoints) {
......@@ -192,6 +206,7 @@ public class SocialTransitionStrategy
AttractionPoint attractionPoint) {
arrivedAtAttractionPoint.remove(comp);
assignments.put(comp, attractionPoint);
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
}
@Override
......@@ -221,6 +236,9 @@ public class SocialTransitionStrategy
}
assignments.put(ms, ap);
arrivedAtAttractionPoint.remove(ms);
for (AttractionAssignmentListener listener : listeners) {
listener.updatedAttractionAssignment(ms, ap);
}
}
private AttractionPoint findHighestScore(SimLocationActuator ms,
......
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/**
* A simplified transition strategy taking only the weights of an AP into account.
*
* @author Bjoern Richerzhagen
* @version 1.0, Jan 16, 2017
*/
public class WeightedTransitionStrategy implements ITransitionStrategy, EventHandler {
private Set<AttractionPoint> aps = new LinkedHashSet<>();
private Map<SimLocationActuator, AttractionPoint> assignments = new LinkedHashMap<>();
private Map<SimLocationActuator, AttractionPoint> lastAssignments = new LinkedHashMap<>();
private List<AttractionAssignmentListener> listeners = new LinkedList<>();
private long pauseTimeMin = 0;
private long pauseTimeMax = 0;
private Random rnd = Randoms.getRandom(WeightedTransitionStrategy.class);
private final static int EVENT_PAUSE_ENDED = 1;
@Override
public AttractionPoint getAssignment(SimLocationActuator comp) {
return assignments.get(comp);
}
@Override
public void addAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.add(listener);
}
@Override
public void removeAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.remove(listener);
}
@Override
public void setAttractionPoints(
Collection<AttractionPoint> attractionPoints) {
this.aps.addAll(attractionPoints);
}
@Override
public Set<AttractionPoint> getAllAttractionPoints() {
return Collections.unmodifiableSet(aps);
}
@Override
public void addComponent(SimLocationActuator ms) {
this.assignments.put(ms, getNewAssignment(ms));
}
private AttractionPoint getNewAssignment(SimLocationActuator component) {
double score = rnd.nextDouble();
List<AttractionPoint> candidates = new LinkedList<>();
for (AttractionPoint ap : aps) {
if (ap.getWeight() >= score) {
candidates.add(ap);
}
}
if (candidates.isEmpty()) {
candidates.addAll(aps);
}
AttractionPoint assignment = candidates.get(rnd.nextInt(candidates.size()));
listeners.forEach(listener -> listener.updatedAttractionAssignment(component, assignment));
return assignment;
}
private long getPauseTime(SimLocationActuator component) {
return (long) (rnd.nextDouble() * (pauseTimeMax-pauseTimeMin)) + pauseTimeMin;
}
@Override
public void eventOccurred(Object content, int type) {
assert type == EVENT_PAUSE_ENDED;
SimLocationActuator comp = (SimLocationActuator) content;
if (!this.assignments.containsKey(comp)) {
// maybe someone assigned a new AP in the meantime. ignore.
this.assignments.put(comp, getNewAssignment(comp));
}
}
@Override
public void reachedAttractionPoint(SimLocationActuator ms) {
this.lastAssignments.put(ms, this.assignments.remove(ms));
Event.scheduleWithDelay(getPauseTime(ms), this, ms, EVENT_PAUSE_ENDED);
}
@Override
public void updateTargetAttractionPoint(SimLocationActuator comp,
AttractionPoint attractionPoint) {
this.lastAssignments.put(comp, this.assignments.remove(comp));
this.assignments.put(comp, attractionPoint);
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
}
public void setMinPauseTime(long minPauseTime) {
if (minPauseTime < 0) {
throw new ConfigurationException(
"MinPauseTime should be >= 0!");
}
this.pauseTimeMin = minPauseTime;
}
public void setMaxPauseTime(long maxPauseTime) {
if (maxPauseTime < 0) {
throw new ConfigurationException(
"MaxPauseTime should be >= 0!");
}
this.pauseTimeMax = maxPauseTime;
}
}
......@@ -118,6 +118,8 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
private Set<String> groupIDsAccessPointUsage = new LinkedHashSet<>();
private List<HandoverSensor5G> handoverSensors = new LinkedList<>();
private List<CellLink> links = new LinkedList<>();
/**
*
......@@ -245,9 +247,13 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
@Override
public void onLocationChanged(Host host, Location location) {
super.onLocationChanged(host, location);
super.onLocationChanged(host, location);
if (lastMovementTimestamp != Time.getCurrentTime()) {
lastMovementTimestamp = Time.getCurrentTime();
// Force re-assignment to cells.
for (CellLink cellLink : links) {
cellLink.setOutdated(true);
}
checkAPAssociations();
}
}
......@@ -291,6 +297,7 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
getPhyType().getDefaultMTU(), mobileClient,
cloudlets.contains(sourceIsClient ? destination : source),
mobileClientsUsingAccessPoints.contains(mobileClient));
links.add(link);
updateOutdatedLink(link);
return link;
}
......
......@@ -20,6 +20,8 @@
package de.tud.kom.p2psim.impl.topology.views.visualization.world;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
......@@ -165,15 +167,56 @@ public class NodeInfoComponentVis extends JComponent
private final Color activeGreen = new Color(0, 200, 0);
private final Color[] colors = { Color.ORANGE, Color.BLUE, Color.RED,
Color.MAGENTA, Color.GRAY, Color.GREEN, Color.CYAN,
Color.PINK };
private final Color[] baseColors = { Color.ORANGE, Color.BLUE, Color.RED,
Color.PINK, Color.GRAY, Color.GREEN, Color.CYAN,
Color.WHITE };
private final Color[] tuColors = {
new Color(93, 133, 195), // 1a
new Color(80, 182, 149), // 3a
// new Color(221,223,72), // 5a
new Color(248,186,60), // 7a
new Color(233,80,62), // 9a
new Color(128, 69, 151), // 11a
new Color(0, 78, 138), // 1c
new Color(0, 136, 119), // 3c
// new Color(177, 189, 0), // 5c
new Color(210, 135, 0), // 7c
new Color(185, 15, 34), // 9c
new Color(97, 28, 115), // 11c
};
private Color[][] colors = null;
public NodeVis(Host host, NodeInformation nodeInfo) {
this.nodeInfo = nodeInfo;
this.host = (SimHost) host;
this.loc = this.host.getTopologyComponent().getRealPosition();
this.visNodeInfo = VisualizationInjector.getNodeInformation(host.getId());
/*
* Create per-info-option colors by deriving the color from the base color
*/
colors = new Color[nodeInfo.getNodeColorDimensions()][];
for (int dim = 0; dim < colors.length; dim++) {
Color baseColor = baseColors[dim];
int dimensionSize = nodeInfo
.getNodeColorDescriptions(dim).length;
colors[dim] = new Color[dimensionSize];
/*
* http://stackoverflow.com/questions/2355157/dynamically-
* creating-colors-with-different-brightness
*/
// float hsbVals[] = Color.RGBtoHSB(baseColor.getRed(),
// baseColor.getGreen(), baseColor.getBlue(), null);
for (int i = 0; i < dimensionSize; i++) {
float hue = i / (float) dimensionSize;
// colors[dim][i] = Color.getHSBColor(hue, hsbVals[1],
// hsbVals[2]);
colors[dim][i] = tuColors[i];
}
}
}
/**
......@@ -184,24 +227,28 @@ public class NodeInfoComponentVis extends JComponent
*/
public void drawLegend(Graphics2D g2) {
String[] dimensions = nodeInfo.getNodeColorDimensionDescriptions();
int radius = 4;
for (int dim = 0; dim < dimensions.length; dim++) {
radius += 2;
if (!activeLayers[dim]) {
int segments = dimensions.length;
int segmentDegrees = (int) (360 / (double) segments);
int arcSize = 8;
g2.setStroke(new BasicStroke(3));
for (int color = 0; color < segments; color++) {
if (!activeLayers[color]) {
continue;
}
g2.setColor(Color.DARK_GRAY);
g2.drawOval(10, 20 * (dim + 1) - 10, radius * 2, radius * 2);
g2.drawString(dimensions[dim], 30, 20 * (dim + 1));
String[] colorDescs = nodeInfo.getNodeColorDescriptions(dim);
g2.drawArc(10, 20 * (color + 1)+10, 2*arcSize, 2*arcSize, color*segmentDegrees, segmentDegrees);
String[] colorDescs = nodeInfo.getNodeColorDescriptions(color);
for (int i = 0; i < colorDescs.length; i++) {
g2.setColor(colors[i]);
g2.fillRect(30 + (i + 1) * 90, 20 * (dim + 1) - 10, 8, 8);
g2.setColor(colors[color][i]);
g2.fillRect(40 + i * 90, 20 * (color + 1)+10, 8, 8);
g2.setColor(Color.DARK_GRAY);
g2.drawString(colorDescs[i], 40 + (i + 1) * 90,
20 * (dim + 1));
g2.drawString(colorDescs[i], 50 + i * 90,
20 * (color + 2));
}
}
g2.setStroke(new BasicStroke(1));
}
public void draw(Graphics2D g2) {
......@@ -222,24 +269,26 @@ public class NodeInfoComponentVis extends JComponent
if (!nodeInfo.isActive()) {
return;
}
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
1.0f));
/*
* TODO add offline/online info here as well (removes the need for a
* custom object that visualizes the underlay!)
*/
int numColors = nodeInfo.getNodeColorDimensions();
radius = 4;
for (int color = 0; color < numColors; color++) {
int value = nodeInfo.getNodeColor(color);
radius += 2;
if (value < 0 || !activeLayers[color]) {
int segments = nodeInfo.getNodeColorDimensions();
int segmentDegrees = (int) (360 / (double) segments);
int arcSize = 8;
g2.setStroke(new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
for (int dim = 0; dim < segments; dim++) {
int value = nodeInfo.getNodeColor(dim);
if (value < 0 || !activeLayers[dim]) {
continue;
}
g2.setColor(colors[value]);
g2.drawOval(center.x - radius, center.y - radius, radius * 2,
radius * 2);
g2.setColor(colors[dim][value]);
g2.drawArc(center.x-arcSize, center.y-arcSize, 2*arcSize, 2*arcSize, dim*segmentDegrees, segmentDegrees);
}
g2.setStroke(new BasicStroke(1));
String nodeDesc = nodeInfo.getNodeDescription();
g2.drawString(nodeDesc, center.x + 4, center.y + 4);
}
......
......@@ -28,6 +28,8 @@ import javax.persistence.EntityManager;
import org.hibernate.Session;
import de.tud.kom.p2psim.impl.util.db.metric.CustomMeasurement;
import de.tud.kom.p2psim.impl.util.db.metric.GroupMetric;
import de.tud.kom.p2psim.impl.util.db.metric.GroupMetricBound;
import de.tud.kom.p2psim.impl.util.db.metric.HostMetric;
import de.tud.kom.p2psim.impl.util.db.metric.HostMetricBound;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
......@@ -98,6 +100,15 @@ public class CommitThread implements Runnable {
((HostMetricBound) persist).setHostMetric(foundMetric);
}
}
}
if (persist instanceof GroupMetricBound) {
GroupMetric metric = ((GroupMetricBound) persist).getGroupMetric();
if (metric != null) {
GroupMetric foundMetric = (GroupMetric) s.get(GroupMetric.class, metric.getId());
if (foundMetric != null) {
((GroupMetricBound) persist).setGroupMetric(foundMetric);
}
}
}
// log.info("Persisting " + persist);
s.persist(persist);
......
......@@ -40,12 +40,15 @@ import org.omg.CORBA.CustomMarshal;
import de.tud.kom.p2psim.impl.util.db.metric.CustomMeasurement;
import de.tud.kom.p2psim.impl.util.db.metric.Experiment;
import de.tud.kom.p2psim.impl.util.db.metric.GroupMetric;
import de.tud.kom.p2psim.impl.util.db.metric.GroupMetricBound;
import de.tud.kom.p2psim.impl.util.db.metric.HostMetric;
import de.tud.kom.p2psim.impl.util.db.metric.HostMetricBound;
import de.tud.kom.p2psim.impl.util.db.metric.Measurement;
import de.tud.kom.p2psim.impl.util.db.metric.MeasurementPair;
import de.tud.kom.p2psim.impl.util.db.metric.MeasurementPairList;
import de.tud.kom.p2psim.impl.util.db.metric.MeasurementSingle;
import de.tud.kom.p2psim.impl.util.db.metric.MeasurementStatistic;
import de.tud.kom.p2psim.impl.util.db.metric.Metric;
import de.tud.kom.p2psim.impl.util.db.metric.MetricDescription;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
......@@ -146,10 +149,13 @@ public class DAO {
cfg.addAnnotatedClass(Experiment.class);
cfg.addAnnotatedClass(HostMetric.class);
cfg.addAnnotatedClass(HostMetricBound.class);
cfg.addAnnotatedClass(GroupMetric.class);
cfg.addAnnotatedClass(GroupMetricBound.class);
cfg.addAnnotatedClass(Measurement.class);
cfg.addAnnotatedClass(MeasurementPair.class);
cfg.addAnnotatedClass(MeasurementPairList.class);
cfg.addAnnotatedClass(MeasurementSingle.class);
cfg.addAnnotatedClass(MeasurementStatistic.class);
cfg.addAnnotatedClass(Metric.class);
cfg.addAnnotatedClass(MetricDescription.class);
......@@ -350,17 +356,33 @@ public class DAO {
}
/**
* Wait for all queue committing threads to finish.
* Wait for all queue committing threads to finish AND close the session
* factory.
*/
public static void finishCommits() {
waitForCommitsToFinish();
if (sessionFactory != null) {
sessionFactory.close();
}
StandardServiceRegistryBuilder.destroy(serviceRegistry);
Monitor.log(DAO.class, Level.INFO, "commit threads finished. \n stored "
+ objectCount + " objects in " + commitCount
+ " threaded transactions taking " + commitTime + " ms");
}
/**
* Basically the same as finishCommits(), but without closing the session
* factory.
*/
public static void waitForCommitsToFinish() {
while (!threads.isEmpty()) {
Thread thread = threads.peek();
try {
Monitor.log(DAO.class, Level.INFO, "Waiting for thread "
+ thread.getName() + " to finish");
thread.join();
Monitor.log(DAO.class, Level.INFO, "Thread " + thread.getName()
+ " finished");
Monitor.log(DAO.class, Level.INFO,
"Thread " + thread.getName() + " finished");
} catch (InterruptedException e) {
Monitor.log(DAO.class, Level.WARN,
"got interrupted while waiting for commit threads");
......@@ -368,14 +390,6 @@ public class DAO {
}
threads.poll();
}
if (sessionFactory != null) {
sessionFactory.close();
}
StandardServiceRegistryBuilder.destroy(serviceRegistry);
Monitor.log(DAO.class, Level.INFO,
"commit threads finished. \n stored " + objectCount
+ " objects in " + commitCount
+ " threaded transactions taking " + commitTime + " ms");
}
/**
......
......@@ -21,6 +21,10 @@
package de.tud.kom.p2psim.impl.util.db.dao.metric;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.util.db.dao.DAO;
......@@ -61,13 +65,20 @@ public class ExperimentDAO extends DAO {
long seed = Simulator.getSeed();
String system = Simulator.getInstance().getConfigurator()
.getResolvedConfiguration();
// FIXME: The following has to be uncommented again.
// String workload = Simulator.getInstance().getConfigurator()
// .getVariables().toString();
Map<String, String> vars = new LinkedHashMap<>(Simulator.getInstance().getConfigurator()
.getVariables());
// Remove seed for database copy
List<String> keys = new LinkedList<>(vars.keySet());
for (String key : keys) {
if (key.equalsIgnoreCase("seed")) {
vars.remove(key);
}
}
String workload = vars.toString();
String experimentDescription = Simulator.getMonitor()
.getExperimentDescription();
experiment = new Experiment(seed, actTime, experimentDescription,
system, "");
system, workload);
persistImmediately(experiment);
}
......
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