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 ...@@ -206,7 +206,9 @@ public abstract class AbstractFilter<M extends MetricValue<?>> implements
if (isOverallMetric) { if (isOverallMetric) {
M overall = getDerivedMetricValueFor(DerivedMetric.this, M overall = getDerivedMetricValueFor(DerivedMetric.this,
incoming, null); incoming, null);
setOverallMetric(overall); if (overall != null) {
setOverallMetric(overall);
}
} else { } else {
for (Host host : hosts) { for (Host host : hosts) {
M perHost = getDerivedMetricValueFor(DerivedMetric.this, M perHost = getDerivedMetricValueFor(DerivedMetric.this,
......
...@@ -83,14 +83,17 @@ public abstract class StatisticsFilter extends ...@@ -83,14 +83,17 @@ public abstract class StatisticsFilter extends
Metric<?> derivedMetric, List<Metric<?>> inputs, Host host) { Metric<?> derivedMetric, List<Metric<?>> inputs, Host host) {
assert inputs.size() == 1; assert inputs.size() == 1;
assert host == null; assert host == null;
Metric<?> input = inputs.get(0); Metric<? extends MetricValue<?>> input = inputs.get(0);
if (input.isOverallMetric()) { if (input.isOverallMetric()) {
throw new AssertionError( throw new AssertionError(
"Only available for per-host input metrics."); "Only available for per-host input metrics.");
} }
LinkedList<MetricValue> mvs = new LinkedList<MetricValue>( List<? extends MetricValue<?>> values = input.getAllPerHostMetrics();
input.getAllPerHostMetrics()); if (values == null || values.isEmpty()) {
return new StatisticsMetricValue(mvs); return null;
}
LinkedList<MetricValue> mvs = new LinkedList<MetricValue>(values);
return new StatisticsMetricValue(mvs);
} }
/** /**
......
...@@ -20,7 +20,14 @@ ...@@ -20,7 +20,14 @@
package de.tud.kom.p2psim.impl.analyzer.metric.output; 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.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.api.common.SimHost;
import de.tud.kom.p2psim.impl.util.db.dao.DAO; import de.tud.kom.p2psim.impl.util.db.dao.DAO;
...@@ -47,6 +54,8 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -47,6 +54,8 @@ public class MetricOutputDAO extends AbstractOutput {
protected long timeStopDao = Long.MAX_VALUE; protected long timeStopDao = Long.MAX_VALUE;
protected Set<String> metricsToAggregate = new LinkedHashSet<>();
/** /**
* *
* @param table * @param table
...@@ -72,6 +81,18 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -72,6 +81,18 @@ public class MetricOutputDAO extends AbstractOutput {
this.timeStopDao = timeStopDao; 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 @Override
public void onInitialize(List<Metric> metrics) { public void onInitialize(List<Metric> metrics) {
...@@ -111,12 +132,25 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -111,12 +132,25 @@ public class MetricOutputDAO extends AbstractOutput {
private final List<SimHost> hosts; private final List<SimHost> hosts;
private final boolean writeAggregates;
private final Map<String, List<SimHost>> hostsByGroup;
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.getUnit() metric.getName(), metric.getDescription(),
.toString()); metric.getUnit().toString());
this.hosts = GlobalOracle.getHosts(); 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 @Override
...@@ -139,18 +173,51 @@ public class MetricOutputDAO extends AbstractOutput { ...@@ -139,18 +173,51 @@ public class MetricOutputDAO extends AbstractOutput {
} }
} else { } else {
// per-host metric // per-host metric
for (SimHost host : hosts) { if (writeAggregates) {
MetricValue mv = metric.getPerHostMetric(host.getId()); /*
if (mv != null) { * Write aggregates instead of individual metric values.
Object val = mv.getValue(); * This can be improved w.r.t. performance, but currently we
if (mv.isValid()) { * do not really care.
if (val instanceof Number) { */
double vd = ((Number) val).doubleValue(); // Iterate over groups
if (Double.isNaN(vd)) { for (String group : hostsByGroup.keySet()) {
continue; 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 { ...@@ -271,27 +271,36 @@ public class DefaultConfigurator implements Configurator {
if (elem.getName().equalsIgnoreCase(FAKE_CONTAINER_ELEMENT)) { if (elem.getName().equalsIgnoreCase(FAKE_CONTAINER_ELEMENT)) {
configureFirstLevel(elem); configureFirstLevel(elem);
} else if (elem.getName().equals(Configurator.DEFAULT_TAG)) { } else if (elem.getName().equals(Configurator.DEFAULT_TAG)) {
for (Iterator iter = elem configureDefaults(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));
}
}
}
} else { } else {
configureComponent(elem); 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 * Create (if not existent yet) and configure a configurable component by
* parsing the XML subtree. * parsing the XML subtree.
...@@ -301,7 +310,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -301,7 +310,7 @@ public class DefaultConfigurator implements Configurator {
* @return configured component * @return configured component
*/ */
public Object configureComponent(Element elem) { public Object configureComponent(Element elem) {
String name = elem.getName(); String name = elem.getName();
if (Configurator.SPECIAL_IF_EQUAL_STR.equalsIgnoreCase(name)) { if (Configurator.SPECIAL_IF_EQUAL_STR.equalsIgnoreCase(name)) {
processIfEqualStr(elem, new ToConfigureCallback() { processIfEqualStr(elem, new ToConfigureCallback() {
...@@ -323,6 +332,18 @@ public class DefaultConfigurator implements Configurator { ...@@ -323,6 +332,18 @@ public class DefaultConfigurator implements Configurator {
return null; 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, Monitor.log(DefaultConfigurator.class, Level.DEBUG,
"Configure component " + name); "Configure component " + name);
...@@ -343,8 +364,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -343,8 +364,8 @@ public class DefaultConfigurator implements Configurator {
if (component != null) { if (component != null) {
Monitor.log(DefaultConfigurator.class, Level.INFO, Monitor.log(DefaultConfigurator.class, Level.INFO,
"Configure component " "Configure component "
+ component.getClass().getSimpleName() + " with element " + component.getClass().getSimpleName()
+ name); + " with element " + name);
configureAttributes(component, elem, consAttrs); configureAttributes(component, elem, consAttrs);
// configure subcomponents // configure subcomponents
if (component instanceof Builder) { if (component instanceof Builder) {
...@@ -362,8 +383,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -362,8 +383,8 @@ public class DefaultConfigurator implements Configurator {
} }
} else { } else {
// component cannot be created and has not been registered // component cannot be created and has not been registered
Monitor.log(DefaultConfigurator.class, Level.WARN, "Skip element " Monitor.log(DefaultConfigurator.class, Level.WARN,
+ name); "Skip element " + name);
} }
return component; return component;
} }
...@@ -375,8 +396,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -375,8 +396,7 @@ public class DefaultConfigurator implements Configurator {
Object component; Object component;
String className = getAttributeValue(elem.attribute(CLASS_TAG)); String className = getAttributeValue(elem.attribute(CLASS_TAG));
Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Create component " Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Create component "
+ className + " with element " + className + " with element " + elem.getName());
+ elem.getName());
component = createInstance(className, component = createInstance(className,
getAttributeValue(elem.attribute(STATIC_CREATION_METHOD_TAG)), getAttributeValue(elem.attribute(STATIC_CREATION_METHOD_TAG)),
consAttrs, elem); consAttrs, elem);
...@@ -442,29 +462,30 @@ public class DefaultConfigurator implements Configurator { ...@@ -442,29 +462,30 @@ public class DefaultConfigurator implements Configurator {
for (int i = 0; i < methods.length; i++) { for (int i = 0; i < methods.length; i++) {
if (methodName.equals(methods[i].getName())) { if (methodName.equals(methods[i].getName())) {
match = methods[i]; match = methods[i];
Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Match " Monitor.log(DefaultConfigurator.class, Level.DEBUG,
+ match); "Match " + match);
break; break;
} }
} }
if (match == null) { if (match == null) {
Monitor.log(DefaultConfigurator.class, Level.WARN, "Cannot set " Monitor.log(DefaultConfigurator.class, Level.WARN,
+ subcomponent + " as there is no method " "Cannot set " + subcomponent + " as there is no method "
+ methodName + " declared in " + component); + methodName + " declared in " + component);
throw new ConfigurationException("Cannot set " + subcomponent throw new ConfigurationException(
+ " as there is no method " + methodName + " declared in " "Cannot set " + subcomponent + " as there is no method "
+ component); + methodName + " declared in " + component);
} else { } else {
Class[] types = match.getParameterTypes(); Class[] types = match.getParameterTypes();
Monitor.log(DefaultConfigurator.class, Level.DEBUG, "Param types" Monitor.log(DefaultConfigurator.class, Level.DEBUG,
+ Arrays.asList(types)); "Param types" + Arrays.asList(types));
if (types.length == 1) { if (types.length == 1) {
try { try {
match.invoke(component, types[0].cast(subcomponent)); match.invoke(component, types[0].cast(subcomponent));
} catch (Exception e) { } catch (Exception e) {
throw new ConfigurationException("Failed to configure " throw new ConfigurationException(
+ methodName + " in " + component + " with " "Failed to configure " + methodName + " in "
+ subcomponent, e); + component + " with " + subcomponent,
e);
} }
} else { } else {
throw new ConfigurationException("Wrong number of params for " throw new ConfigurationException("Wrong number of params for "
...@@ -507,11 +528,10 @@ public class DefaultConfigurator implements Configurator { ...@@ -507,11 +528,10 @@ public class DefaultConfigurator implements Configurator {
} else { } else {
Monitor.log(DefaultConfigurator.class, Monitor.log(DefaultConfigurator.class,
Level.ERROR, Level.ERROR,
"Found two possible methods " "Found two possible methods " + method
+ method + " and " + methods[i]); + " and " + methods[i]);
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Cannot set property " "Cannot set property " + name
+ name
+ " as there are more than one matching methods in " + " as there are more than one matching methods in "
+ classToConfigure); + classToConfigure);
} }
...@@ -525,7 +545,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -525,7 +545,8 @@ public class DefaultConfigurator implements Configurator {
*/ */
for (int i = 0; i < methods.length; i++) { for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals("setProperty") if (methods[i].getName().equals("setProperty")
&& methods[i].getParameterTypes().length == 2) { && methods[i]
.getParameterTypes().length == 2) {
method = methods[i]; method = methods[i];
} }
} }
...@@ -541,8 +562,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -541,8 +562,7 @@ public class DefaultConfigurator implements Configurator {
* Still nothing? * Still nothing?
*/ */
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Cannot set property " "Cannot set property " + name
+ name
+ " as there are no matching methods in class " + " as there are no matching methods in class "
+ classToConfigure); + classToConfigure);
} }
...@@ -554,7 +574,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -554,7 +574,8 @@ public class DefaultConfigurator implements Configurator {
} catch (Exception e) { } catch (Exception e) {
throw new ConfigurationException( throw new ConfigurationException(
"Failed to set the property " + name + " in " "Failed to set the property " + name + " in "
+ component, e); + component,
e);
} }
} }
} }
...@@ -607,8 +628,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -607,8 +628,8 @@ public class DefaultConfigurator implements Configurator {
} }
param = lvals; param = lvals;
} else { } else {
throw new IllegalArgumentException("Parameter type " + typeClass throw new IllegalArgumentException(
+ " is not supported"); "Parameter type " + typeClass + " is not supported");
} }
return param; return param;
} }
...@@ -635,8 +656,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -635,8 +656,8 @@ public class DefaultConfigurator implements Configurator {
String value = attr.getValue(); String value = attr.getValue();
value = parseValue(value); value = parseValue(value);
if (value == null) if (value == null)
throw new IllegalStateException("Variable " + attr.getValue() throw new IllegalStateException(
+ " has not been set"); "Variable " + attr.getValue() + " has not been set");
return value; return value;
} }
...@@ -738,12 +759,11 @@ public class DefaultConfigurator implements Configurator { ...@@ -738,12 +759,11 @@ public class DefaultConfigurator implements Configurator {
break; break;
} }
consArgs[i] = configureComponent(elem); consArgs[i] = configureComponent(elem);
if (consArgs[i].getClass().isAssignableFrom( if (consArgs[i].getClass()
types[i])) .isAssignableFrom(types[i]))
throw new ConfigurationException( throw new ConfigurationException(
"The type of the component configured for the parameter '" "The type of the component configured for the parameter '"
+ cArgs[i] + cArgs[i] + "', type is "
+ "', type is "
+ consArgs[i].getClass() + consArgs[i].getClass()
.getSimpleName() .getSimpleName()
+ " and is not equal to the type " + " and is not equal to the type "
...@@ -771,15 +791,16 @@ public class DefaultConfigurator implements Configurator { ...@@ -771,15 +791,16 @@ public class DefaultConfigurator implements Configurator {
component = forName.newInstance(); component = forName.newInstance();
} else } else
component = forName.getDeclaredMethod(staticMethod, component = forName
new Class[0]).invoke(null, new Object[0]); .getDeclaredMethod(staticMethod, new Class[0])
.invoke(null, new Object[0]);
componentList.add(component); componentList.add(component);
return component; return component;
} catch (Exception e) { } catch (Exception e) {
throw new ConfigurationException("Failed to create configurable " throw new ConfigurationException(
+ className, e); "Failed to create configurable " + className, e);
} }
} }
...@@ -791,8 +812,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -791,8 +812,8 @@ public class DefaultConfigurator implements Configurator {
*/ */
public void setVariables(Map<String, String> variables) { public void setVariables(Map<String, String> variables) {
if (variables.size() != 0) { if (variables.size() != 0) {
Monitor.log(DefaultConfigurator.class, Level.WARN, "Set variables " Monitor.log(DefaultConfigurator.class, Level.WARN,
+ variables); "Set variables " + variables);
} }
this.variables.putAll(variables); this.variables.putAll(variables);
} }
...@@ -835,8 +856,8 @@ public class DefaultConfigurator implements Configurator { ...@@ -835,8 +856,8 @@ public class DefaultConfigurator implements Configurator {
factor *= Time.SECOND; factor *= Time.SECOND;
break; break;
default: default:
throw new IllegalStateException("time unit " + unit throw new IllegalStateException(
+ " is not allowed"); "time unit " + unit + " is not allowed");
} }
} }
} }
...@@ -870,7 +891,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -870,7 +891,7 @@ public class DefaultConfigurator implements Configurator {
throw new IllegalStateException("Invalid memory unit."); throw new IllegalStateException("Invalid memory unit.");
} }
} }
// Convert type // Convert type
double dNum = Double.valueOf(number); double dNum = Double.valueOf(number);
if (targetClass.equals(Integer.class)) { if (targetClass.equals(Integer.class)) {
...@@ -907,9 +928,11 @@ public class DefaultConfigurator implements Configurator { ...@@ -907,9 +928,11 @@ public class DefaultConfigurator implements Configurator {
String arg1p = parseValue(arg1); String arg1p = parseValue(arg1);
if (arg0p == null) if (arg0p == null)
throw new RuntimeException("Variable " + arg0 + " not set or null."); throw new RuntimeException(
"Variable " + arg0 + " not set or null.");
if (arg1p == 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)) { if (arg0p.equals(arg1p)) {
...@@ -917,7 +940,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -917,7 +940,7 @@ public class DefaultConfigurator implements Configurator {
if (!iter.hasNext()) if (!iter.hasNext())
Monitor.log(DefaultConfigurator.class, Level.WARN, Monitor.log(DefaultConfigurator.class, Level.WARN,
"No component to configure in the ifEqualStr-clause (arg0=" "No component to configure in the ifEqualStr-clause (arg0="
+ arg0 + ", arg1=" + arg1 + ")."); + arg0 + ", arg1=" + arg1 + ").");
else { else {
while (iter.hasNext()) { while (iter.hasNext()) {
Element child = (Element) iter.next(); Element child = (Element) iter.next();
...@@ -947,9 +970,11 @@ public class DefaultConfigurator implements Configurator { ...@@ -947,9 +970,11 @@ public class DefaultConfigurator implements Configurator {
String arg1p = parseValue(arg1); String arg1p = parseValue(arg1);
if (arg0p == null) if (arg0p == null)
throw new RuntimeException("Variable " + arg0 + " not set or null."); throw new RuntimeException(
"Variable " + arg0 + " not set or null.");
if (arg1p == 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)) { if (!arg0p.equals(arg1p)) {
...@@ -957,7 +982,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -957,7 +982,7 @@ public class DefaultConfigurator implements Configurator {
if (!iter.hasNext()) if (!iter.hasNext())
Monitor.log(DefaultConfigurator.class, Level.WARN, Monitor.log(DefaultConfigurator.class, Level.WARN,
"No component to configure in the ifNotEqualStr-clause (arg0=" "No component to configure in the ifNotEqualStr-clause (arg0="
+ arg0 + ", arg1=" + arg1 + ")."); + arg0 + ", arg1=" + arg1 + ").");
else { else {
while (iter.hasNext()) { while (iter.hasNext()) {
Element child = (Element) iter.next(); Element child = (Element) iter.next();
...@@ -967,8 +992,6 @@ public class DefaultConfigurator implements Configurator { ...@@ -967,8 +992,6 @@ public class DefaultConfigurator implements Configurator {
} }
} }
/** /**
* Gets the parsed XML-Configuration File. So are the included tags * Gets the parsed XML-Configuration File. So are the included tags
* resolved. * resolved.
...@@ -1006,16 +1029,16 @@ public class DefaultConfigurator implements Configurator { ...@@ -1006,16 +1029,16 @@ public class DefaultConfigurator implements Configurator {
return "Cannot parse/read the configuration"; return "Cannot parse/read the configuration";
} }
@Override @Override
public List<Object> getConfigurable(Class type) { public List<Object> getConfigurable(Class type) {
List<Object> components = Lists.newArrayList(); List<Object> components = Lists.newArrayList();
for (Object obj : configurables.values()) { for (Object obj : configurables.values()) {
if (type.isAssignableFrom(obj.getClass())) { if (type.isAssignableFrom(obj.getClass())) {
components.add(obj); components.add(obj);
} }
} }
return components; return components;
} }
protected interface ToConfigureCallback { protected interface ToConfigureCallback {
public void run(Element elemToConfigure); public void run(Element elemToConfigure);
......
...@@ -36,11 +36,9 @@ public class LinearMovement extends AbstractLocalMovementStrategy { ...@@ -36,11 +36,9 @@ public class LinearMovement extends AbstractLocalMovementStrategy {
public Either<PositionVector, Boolean> nextPosition(SimLocationActuator comp, public Either<PositionVector, Boolean> nextPosition(SimLocationActuator comp,
PositionVector destination) { PositionVector destination) {
PositionVector newPosition; PositionVector newPosition = null;
if (destination if (destination
.distanceTo(comp.getRealPosition()) < getMovementSpeed(comp)) { .distanceTo(comp.getRealPosition()) > getMovementSpeed(comp)) {
newPosition = destination.clone();
} else {
newPosition = comp.getRealPosition().moveStep(destination, getMovementSpeed(comp)); newPosition = comp.getRealPosition().moveStep(destination, getMovementSpeed(comp));
} }
return new Left<PositionVector, Boolean>(newPosition); return new Left<PositionVector, Boolean>(newPosition);
......
...@@ -81,7 +81,7 @@ public class RealWorldStreetsMovement extends AbstractLocalMovementStrategy { ...@@ -81,7 +81,7 @@ public class RealWorldStreetsMovement extends AbstractLocalMovementStrategy {
hopper = new GraphHopper().forServer(); hopper = new GraphHopper().forServer();
hopper.setOSMFile(osmFileLocation); hopper.setOSMFile(osmFileLocation);
// where to store graphhopper files? // where to store graphhopper files?
hopper.setGraphHopperLocation(graphFolderFiles+"/"+osmFileLocation.hashCode()); hopper.setGraphHopperLocation(graphFolderFiles+"/"+osmFileLocation.hashCode()+movementType);
hopper.setEncodingManager(new EncodingManager(movementType)); hopper.setEncodingManager(new EncodingManager(movementType));
hopper.importOrLoad(); hopper.importOrLoad();
init = true; init = true;
......
...@@ -39,6 +39,20 @@ public class GPSCalculation { ...@@ -39,6 +39,20 @@ public class GPSCalculation {
private static double scaleFactor; 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() { public GPSCalculation() {
} }
...@@ -49,7 +63,6 @@ public class GPSCalculation { ...@@ -49,7 +63,6 @@ public class GPSCalculation {
* case, 1px == 1m) - this way, the world-size specified in the configs * case, 1px == 1m) - this way, the world-size specified in the configs
* is valid on all zoom levels. * is valid on all zoom levels.
*/ */
this.scaleFactor = 0.125;
// 17: 2, 16: 1, 15: 0.5, 14: 0.25 // 17: 2, 16: 1, 15: 0.5, 14: 0.25
VisualizationInjector.setScale(Math.pow(2.0d, (zoom - 16))); VisualizationInjector.setScale(Math.pow(2.0d, (zoom - 16)));
} }
...@@ -67,31 +80,45 @@ public class GPSCalculation { ...@@ -67,31 +80,45 @@ public class GPSCalculation {
} }
public static double getLatUpper() { public static double getLatUpper() {
return latCenter + scaleFactor * 0.027613 * Binder return latCenter + (Binder.getComponentOrNull(Topology.class)
.getComponentOrNull(Topology.class).getWorldDimensions().getY() .getWorldDimensions().getY() / 111111d) * scaleFactor;
/ 1000;
// return latCenter + scaleFactor * 0.027613 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getY()
// / 1000;
} }
public static double getLatLower() { public static double getLatLower() {
return latCenter - scaleFactor * 0.027613 * Binder return latCenter - (Binder.getComponentOrNull(Topology.class)
.getComponentOrNull(Topology.class).getWorldDimensions().getY() .getWorldDimensions().getY() / 111111d) * scaleFactor;
/ 1000;
// return latCenter - scaleFactor * 0.027613 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getY()
// / 1000;
} }
public static double getLonLeft() { public static double getLonLeft() {
return lonCenter - scaleFactor * 0.0419232 * Binder return lonCenter - (Binder.getComponentOrNull(Topology.class)
.getComponentOrNull(Topology.class).getWorldDimensions().getX() .getWorldDimensions().getX() / 111111d / scaleLon) * scaleFactor;
/ 1000;
// return lonCenter - scaleFactor * 0.043 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getX()
// / 1000;
} }
public static double getLonRight() { public static double getLonRight() {
return lonCenter + scaleFactor * 0.0419232 * Binder return lonCenter + (Binder.getComponentOrNull(Topology.class)
.getComponentOrNull(Topology.class).getWorldDimensions().getX() .getWorldDimensions().getX() / 111111d / scaleLon) * scaleFactor;
/ 1000;
// return lonCenter + scaleFactor * 0.043 * Binder
// .getComponentOrNull(Topology.class).getWorldDimensions().getX()
// / 1000;
} }
public void setLatCenter(double latCenter) { public void setLatCenter(double latCenter) {
this.latCenter = latCenter; this.latCenter = latCenter;
this.scaleLon = Math.cos(Math.toRadians(latCenter));
this.scaleFactor = 0.38d;
} }
public void setLonCenter(double lonCenter) { public void setLonCenter(double lonCenter) {
......
...@@ -43,6 +43,7 @@ import de.tud.kom.p2psim.impl.topology.TopologyFactory; ...@@ -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.attraction.IAttractionGenerator;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.mapvisualization.IMapVisualization; 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;
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.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent; import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import de.tud.kom.p2psim.impl.util.Either; import de.tud.kom.p2psim.impl.util.Either;
...@@ -50,6 +51,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder; ...@@ -50,6 +51,7 @@ import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Randoms; 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.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationActuator; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationActuator;
...@@ -94,7 +96,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationAc ...@@ -94,7 +96,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationAc
* @author Martin Hellwig, Christoph Muenker * @author Martin Hellwig, Christoph Muenker
* @version 1.0, 07.07.2015 * @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; private final int EVENT_MOVE = 1;
...@@ -114,7 +116,7 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -114,7 +116,7 @@ public class ModularMovementModel implements MovementModel, EventHandler {
private Set<SimLocationActuator> moveableHosts = new LinkedHashSet<SimLocationActuator>(); 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; private boolean initialized = false;
...@@ -154,9 +156,16 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -154,9 +156,16 @@ public class ModularMovementModel implements MovementModel, EventHandler {
localMovementStrategy.setWaypointModel(Binder localMovementStrategy.setWaypointModel(Binder
.getComponentOrNull(Topology.class).getWaypointModel()); .getComponentOrNull(Topology.class).getWaypointModel());
/*
* Scale depending on calculation interval, if interval != 1 Second.
*/
localMovementStrategy
.setScaleFactor(timeBetweenMoveOperation / (double) Time.SECOND);
List<AttractionPoint> attractionPoints = attractionGenerator List<AttractionPoint> attractionPoints = attractionGenerator
.getAttractionPoints(); .getAttractionPoints();
transition.setAttractionPoints(attractionPoints); transition.setAttractionPoints(attractionPoints);
transition.addAttractionAssignmentListener(this);
// This adds the mobile hosts (smartphones/users) to the transition // This adds the mobile hosts (smartphones/users) to the transition
// strategy // strategy
...@@ -189,7 +198,7 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -189,7 +198,7 @@ public class ModularMovementModel implements MovementModel, EventHandler {
@Override @Override
public AttractionPoint getTargetLocation(SimLocationActuator actuator) { public AttractionPoint getTargetLocation(SimLocationActuator actuator) {
return transition.getAssignments().get(actuator); return transition.getAssignment(actuator);
} }
@Override @Override
...@@ -216,7 +225,6 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -216,7 +225,6 @@ public class ModularMovementModel implements MovementModel, EventHandler {
@Override @Override
public void addComponent(SimLocationActuator comp) { public void addComponent(SimLocationActuator comp) {
moveableHosts.add(comp); moveableHosts.add(comp);
offsetPosition.put(comp, randomOffsetVector());
} }
public Set<SimLocationActuator> getAllLocationActuators() { public Set<SimLocationActuator> getAllLocationActuators() {
...@@ -233,27 +241,48 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -233,27 +241,48 @@ public class ModularMovementModel implements MovementModel, EventHandler {
} }
} }
private PositionVector randomOffsetVector() { @Override
double x = rand.nextGaussian() * 6; public void updatedAttractionAssignment(SimLocationActuator component,
double y = rand.nextGaussian() * 6; 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() { protected void move() {
Map<SimLocationActuator, AttractionPoint> assigns = transition for (SimLocationActuator component : moveableHosts) {
.getAssignments(); assert currentTarget.containsKey(component);
for (Entry<SimLocationActuator, AttractionPoint> entry : assigns doLocalMovement(component, currentTarget.get(component));
.entrySet()) {
SimLocationActuator ms = entry.getKey();
PositionVector attractionCenter = (PositionVector) entry.getValue();
PositionVector destination = new PositionVector(attractionCenter);
destination.add(offsetPosition.get(ms));
doLocalMovement(ms, destination);
} }
Event.scheduleWithDelay(timeBetweenMoveOperation, this, null, Event.scheduleWithDelay(timeBetweenMoveOperation, this, null,
EVENT_MOVE); EVENT_MOVE);
} }
...@@ -331,6 +360,4 @@ public class ModularMovementModel implements MovementModel, EventHandler { ...@@ -331,6 +360,4 @@ public class ModularMovementModel implements MovementModel, EventHandler {
public List<AttractionPoint> getAttractionPoints() { public List<AttractionPoint> getAttractionPoints() {
return new Vector<AttractionPoint>(transition.getAllAttractionPoints()); return new Vector<AttractionPoint>(transition.getAllAttractionPoints());
} }
} }
...@@ -62,7 +62,7 @@ public class ModularMovementModelViz extends JComponent ...@@ -62,7 +62,7 @@ public class ModularMovementModelViz extends JComponent
private final static int NODE_PAD = 2; 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"); private static Color COLOR_ATTR_POINT = Color.decode("#4A7B9D");
...@@ -159,11 +159,17 @@ public class ModularMovementModelViz extends JComponent ...@@ -159,11 +159,17 @@ public class ModularMovementModelViz extends JComponent
VisualizationInjector.scaleValue(point.x) - ATTR_PAD, VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
VisualizationInjector.scaleValue(point.y) - ATTR_PAD); VisualizationInjector.scaleValue(point.y) - ATTR_PAD);
g2.setColor(COLOR_ATTR_POINT); 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( g2.fillOval(
VisualizationInjector.scaleValue(point.x) - ATTR_PAD, VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
VisualizationInjector.scaleValue(point.y) - ATTR_PAD, VisualizationInjector.scaleValue(point.y) - ATTR_PAD,
ATTR_PAD * 2 + 1, ATTR_PAD * 2 + 1); 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 ...@@ -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" + 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 + 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 ## Configuration via SocialTest.xml
......
...@@ -110,8 +110,15 @@ public class JSONAttractionGenerator implements IAttractionGenerator { ...@@ -110,8 +110,15 @@ public class JSONAttractionGenerator implements IAttractionGenerator {
String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name"); String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name");
double lat = allPOI.getJSONObject(i).getDouble("lat"); double lat = allPOI.getJSONObject(i).getDouble("lat");
double lon = allPOI.getJSONObject(i).getDouble("lon"); double lon = allPOI.getJSONObject(i).getDouble("lon");
AttractionPointImpl ap;
if(lat > latLeft && lat < latRight && 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) { catch (JSONException e) {
//This bar had no name defined, so there was an error. Not so bad //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; ...@@ -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.common.SimHostComponent;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; 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.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.transition.ITransitionStrategy.AttractionAssignmentListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint;
/** /**
...@@ -58,9 +59,11 @@ public class FixedAssignmentStrategy implements ITransitionStrategy { ...@@ -58,9 +59,11 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
private Map<AttractionPoint, String> mappingAPGroupId = new LinkedHashMap<AttractionPoint, String>(); private Map<AttractionPoint, String> mappingAPGroupId = new LinkedHashMap<AttractionPoint, String>();
private List<AttractionAssignmentListener> listeners = new LinkedList<>();
@Override @Override
public Map<SimLocationActuator, AttractionPoint> getAssignments() { public AttractionPoint getAssignment(SimLocationActuator comp) {
return new HashMap<SimLocationActuator, AttractionPoint>(assignments); return assignments.get(comp);
} }
@Override @Override
...@@ -73,6 +76,18 @@ public class FixedAssignmentStrategy implements ITransitionStrategy { ...@@ -73,6 +76,18 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
return aPoints; return aPoints;
} }
@Override
public void addAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.add(listener);
}
@Override
public void removeAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.remove(listener);
}
@Override @Override
public void addComponent(SimLocationActuator ms) { public void addComponent(SimLocationActuator ms) {
comps.add(ms); comps.add(ms);
...@@ -105,7 +120,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy { ...@@ -105,7 +120,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
throw new Error("Should not happen."); throw new Error("Should not happen.");
} }
listeners.forEach(listener -> listener.updatedAttractionAssignment(ms, assignments.get(ms)));
} }
...@@ -118,6 +133,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy { ...@@ -118,6 +133,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
public void updateTargetAttractionPoint(SimLocationActuator comp, public void updateTargetAttractionPoint(SimLocationActuator comp,
AttractionPoint attractionPoint) { AttractionPoint attractionPoint) {
assignments.put(comp, attractionPoint); assignments.put(comp, attractionPoint);
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
} }
private void mappingHost(SimLocationActuator ms) { private void mappingHost(SimLocationActuator ms) {
......
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition; package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
...@@ -35,23 +33,30 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Attraction ...@@ -35,23 +33,30 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Attraction
* @version 1.0, 03.07.2015 * @version 1.0, 03.07.2015
*/ */
public interface ITransitionStrategy { public interface ITransitionStrategy {
/** /**
* Returns the assignments of the MovementSupported Objects to the * Currently assigned attraction point.
* AttractionPoints
* *
* @param comp
* @return * @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! * Should be called first, to add the Attraction Points for the assignment!
* *
* @param attractionPoints * @param attractionPoints
*/ */
public void setAttractionPoints(Collection<AttractionPoint> attractionPoints); public void setAttractionPoints(
Collection<AttractionPoint> attractionPoints);
/** /**
* Return a set of all attraction points * Return a set of all attraction points
*
* @return * @return
*/ */
public Set<AttractionPoint> getAllAttractionPoints(); public Set<AttractionPoint> getAllAttractionPoints();
...@@ -79,4 +84,18 @@ public interface ITransitionStrategy { ...@@ -79,4 +84,18 @@ public interface ITransitionStrategy {
public void updateTargetAttractionPoint(SimLocationActuator comp, public void updateTargetAttractionPoint(SimLocationActuator comp,
AttractionPoint attractionPoint); 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; ...@@ -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.api.topology.social.SocialView;
import de.tud.kom.p2psim.impl.simengine.Simulator; import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector; 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.Binder;
import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.EventHandler;
...@@ -98,6 +99,8 @@ public class SocialTransitionStrategy ...@@ -98,6 +99,8 @@ public class SocialTransitionStrategy
private Map<SimLocationActuator, SimHost> mapMsHost = new HashMap<SimLocationActuator, SimHost>(); private Map<SimLocationActuator, SimHost> mapMsHost = new HashMap<SimLocationActuator, SimHost>();
private Map<SimHost, SimLocationActuator> mapHostMs = new HashMap<SimHost, SimLocationActuator>(); private Map<SimHost, SimLocationActuator> mapHostMs = new HashMap<SimHost, SimLocationActuator>();
private List<AttractionAssignmentListener> listeners = new LinkedList<>();
private double minPauseTime = Simulator.MINUTE_UNIT * 0.5; private double minPauseTime = Simulator.MINUTE_UNIT * 0.5;
...@@ -148,11 +151,22 @@ public class SocialTransitionStrategy ...@@ -148,11 +151,22 @@ public class SocialTransitionStrategy
} }
@Override @Override
public Map<SimLocationActuator, AttractionPoint> getAssignments() { public AttractionPoint getAssignment(SimLocationActuator comp) {
// FIXME why new? return new HashMap<MovementSupported, return assignments.get(comp);
// AttractionPoint>(assignments);
return assignments;
} }
@Override
public void addAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.add(listener);
}
@Override
public void removeAttractionAssignmentListener(
AttractionAssignmentListener listener) {
listeners.remove(listener);
}
@Override @Override
public void setAttractionPoints(Collection<AttractionPoint> attractionPoints) { public void setAttractionPoints(Collection<AttractionPoint> attractionPoints) {
...@@ -192,6 +206,7 @@ public class SocialTransitionStrategy ...@@ -192,6 +206,7 @@ public class SocialTransitionStrategy
AttractionPoint attractionPoint) { AttractionPoint attractionPoint) {
arrivedAtAttractionPoint.remove(comp); arrivedAtAttractionPoint.remove(comp);
assignments.put(comp, attractionPoint); assignments.put(comp, attractionPoint);
listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
} }
@Override @Override
...@@ -221,6 +236,9 @@ public class SocialTransitionStrategy ...@@ -221,6 +236,9 @@ public class SocialTransitionStrategy
} }
assignments.put(ms, ap); assignments.put(ms, ap);
arrivedAtAttractionPoint.remove(ms); arrivedAtAttractionPoint.remove(ms);
for (AttractionAssignmentListener listener : listeners) {
listener.updatedAttractionAssignment(ms, ap);
}
} }
private AttractionPoint findHighestScore(SimLocationActuator ms, 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> { ...@@ -118,6 +118,8 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
private Set<String> groupIDsAccessPointUsage = new LinkedHashSet<>(); private Set<String> groupIDsAccessPointUsage = new LinkedHashSet<>();
private List<HandoverSensor5G> handoverSensors = new LinkedList<>(); private List<HandoverSensor5G> handoverSensors = new LinkedList<>();
private List<CellLink> links = new LinkedList<>();
/** /**
* *
...@@ -245,9 +247,13 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> { ...@@ -245,9 +247,13 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
@Override @Override
public void onLocationChanged(Host host, Location location) { public void onLocationChanged(Host host, Location location) {
super.onLocationChanged(host, location); super.onLocationChanged(host, location);
if (lastMovementTimestamp != Time.getCurrentTime()) { if (lastMovementTimestamp != Time.getCurrentTime()) {
lastMovementTimestamp = Time.getCurrentTime(); lastMovementTimestamp = Time.getCurrentTime();
// Force re-assignment to cells.
for (CellLink cellLink : links) {
cellLink.setOutdated(true);
}
checkAPAssociations(); checkAPAssociations();
} }
} }
...@@ -291,6 +297,7 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> { ...@@ -291,6 +297,7 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
getPhyType().getDefaultMTU(), mobileClient, getPhyType().getDefaultMTU(), mobileClient,
cloudlets.contains(sourceIsClient ? destination : source), cloudlets.contains(sourceIsClient ? destination : source),
mobileClientsUsingAccessPoints.contains(mobileClient)); mobileClientsUsingAccessPoints.contains(mobileClient));
links.add(link);
updateOutdatedLink(link); updateOutdatedLink(link);
return link; return link;
} }
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
package de.tud.kom.p2psim.impl.topology.views.visualization.world; 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.Color;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
...@@ -165,15 +167,56 @@ public class NodeInfoComponentVis extends JComponent ...@@ -165,15 +167,56 @@ public class NodeInfoComponentVis extends JComponent
private final Color activeGreen = new Color(0, 200, 0); private final Color activeGreen = new Color(0, 200, 0);
private final Color[] colors = { Color.ORANGE, Color.BLUE, Color.RED, private final Color[] baseColors = { Color.ORANGE, Color.BLUE, Color.RED,
Color.MAGENTA, Color.GRAY, Color.GREEN, Color.CYAN, Color.PINK, Color.GRAY, Color.GREEN, Color.CYAN,
Color.PINK }; 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) { public NodeVis(Host host, NodeInformation nodeInfo) {
this.nodeInfo = nodeInfo; this.nodeInfo = nodeInfo;
this.host = (SimHost) host; this.host = (SimHost) host;
this.loc = this.host.getTopologyComponent().getRealPosition(); this.loc = this.host.getTopologyComponent().getRealPosition();
this.visNodeInfo = VisualizationInjector.getNodeInformation(host.getId()); 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 ...@@ -184,24 +227,28 @@ public class NodeInfoComponentVis extends JComponent
*/ */
public void drawLegend(Graphics2D g2) { public void drawLegend(Graphics2D g2) {
String[] dimensions = nodeInfo.getNodeColorDimensionDescriptions(); String[] dimensions = nodeInfo.getNodeColorDimensionDescriptions();
int radius = 4;
for (int dim = 0; dim < dimensions.length; dim++) { int segments = dimensions.length;
radius += 2; int segmentDegrees = (int) (360 / (double) segments);
if (!activeLayers[dim]) { int arcSize = 8;
g2.setStroke(new BasicStroke(3));
for (int color = 0; color < segments; color++) {
if (!activeLayers[color]) {
continue; continue;
} }
g2.setColor(Color.DARK_GRAY); g2.setColor(Color.DARK_GRAY);
g2.drawOval(10, 20 * (dim + 1) - 10, radius * 2, radius * 2); g2.drawArc(10, 20 * (color + 1)+10, 2*arcSize, 2*arcSize, color*segmentDegrees, segmentDegrees);
g2.drawString(dimensions[dim], 30, 20 * (dim + 1)); String[] colorDescs = nodeInfo.getNodeColorDescriptions(color);
String[] colorDescs = nodeInfo.getNodeColorDescriptions(dim);
for (int i = 0; i < colorDescs.length; i++) { for (int i = 0; i < colorDescs.length; i++) {
g2.setColor(colors[i]); g2.setColor(colors[color][i]);
g2.fillRect(30 + (i + 1) * 90, 20 * (dim + 1) - 10, 8, 8); g2.fillRect(40 + i * 90, 20 * (color + 1)+10, 8, 8);
g2.setColor(Color.DARK_GRAY); g2.setColor(Color.DARK_GRAY);
g2.drawString(colorDescs[i], 40 + (i + 1) * 90, g2.drawString(colorDescs[i], 50 + i * 90,
20 * (dim + 1)); 20 * (color + 2));
} }
} }
g2.setStroke(new BasicStroke(1));
} }
public void draw(Graphics2D g2) { public void draw(Graphics2D g2) {
...@@ -222,24 +269,26 @@ public class NodeInfoComponentVis extends JComponent ...@@ -222,24 +269,26 @@ public class NodeInfoComponentVis extends JComponent
if (!nodeInfo.isActive()) { if (!nodeInfo.isActive()) {
return; return;
} }
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
1.0f));
/*
* TODO add offline/online info here as well (removes the need for a int segments = nodeInfo.getNodeColorDimensions();
* custom object that visualizes the underlay!) int segmentDegrees = (int) (360 / (double) segments);
*/ int arcSize = 8;
int numColors = nodeInfo.getNodeColorDimensions(); g2.setStroke(new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
radius = 4; for (int dim = 0; dim < segments; dim++) {
for (int color = 0; color < numColors; color++) { int value = nodeInfo.getNodeColor(dim);
int value = nodeInfo.getNodeColor(color); if (value < 0 || !activeLayers[dim]) {
radius += 2;
if (value < 0 || !activeLayers[color]) {
continue; continue;
} }
g2.setColor(colors[value]); g2.setColor(colors[dim][value]);
g2.drawOval(center.x - radius, center.y - radius, radius * 2, g2.drawArc(center.x-arcSize, center.y-arcSize, 2*arcSize, 2*arcSize, dim*segmentDegrees, segmentDegrees);
radius * 2);
} }
g2.setStroke(new BasicStroke(1));
String nodeDesc = nodeInfo.getNodeDescription(); String nodeDesc = nodeInfo.getNodeDescription();
g2.drawString(nodeDesc, center.x + 4, center.y + 4); g2.drawString(nodeDesc, center.x + 4, center.y + 4);
} }
......
...@@ -28,6 +28,8 @@ import javax.persistence.EntityManager; ...@@ -28,6 +28,8 @@ import javax.persistence.EntityManager;
import org.hibernate.Session; import org.hibernate.Session;
import de.tud.kom.p2psim.impl.util.db.metric.CustomMeasurement; 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.HostMetric;
import de.tud.kom.p2psim.impl.util.db.metric.HostMetricBound; import de.tud.kom.p2psim.impl.util.db.metric.HostMetricBound;
import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor;
...@@ -98,6 +100,15 @@ public class CommitThread implements Runnable { ...@@ -98,6 +100,15 @@ public class CommitThread implements Runnable {
((HostMetricBound) persist).setHostMetric(foundMetric); ((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); // log.info("Persisting " + persist);
s.persist(persist); s.persist(persist);
......
...@@ -40,12 +40,15 @@ import org.omg.CORBA.CustomMarshal; ...@@ -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.CustomMeasurement;
import de.tud.kom.p2psim.impl.util.db.metric.Experiment; 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.HostMetric;
import de.tud.kom.p2psim.impl.util.db.metric.HostMetricBound; 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.Measurement;
import de.tud.kom.p2psim.impl.util.db.metric.MeasurementPair; 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.MeasurementPairList;
import de.tud.kom.p2psim.impl.util.db.metric.MeasurementSingle; 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.Metric;
import de.tud.kom.p2psim.impl.util.db.metric.MetricDescription; import de.tud.kom.p2psim.impl.util.db.metric.MetricDescription;
import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor;
...@@ -146,10 +149,13 @@ public class DAO { ...@@ -146,10 +149,13 @@ public class DAO {
cfg.addAnnotatedClass(Experiment.class); cfg.addAnnotatedClass(Experiment.class);
cfg.addAnnotatedClass(HostMetric.class); cfg.addAnnotatedClass(HostMetric.class);
cfg.addAnnotatedClass(HostMetricBound.class); cfg.addAnnotatedClass(HostMetricBound.class);
cfg.addAnnotatedClass(GroupMetric.class);
cfg.addAnnotatedClass(GroupMetricBound.class);
cfg.addAnnotatedClass(Measurement.class); cfg.addAnnotatedClass(Measurement.class);
cfg.addAnnotatedClass(MeasurementPair.class); cfg.addAnnotatedClass(MeasurementPair.class);
cfg.addAnnotatedClass(MeasurementPairList.class); cfg.addAnnotatedClass(MeasurementPairList.class);
cfg.addAnnotatedClass(MeasurementSingle.class); cfg.addAnnotatedClass(MeasurementSingle.class);
cfg.addAnnotatedClass(MeasurementStatistic.class);
cfg.addAnnotatedClass(Metric.class); cfg.addAnnotatedClass(Metric.class);
cfg.addAnnotatedClass(MetricDescription.class); cfg.addAnnotatedClass(MetricDescription.class);
...@@ -350,17 +356,33 @@ public class DAO { ...@@ -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() { 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()) { while (!threads.isEmpty()) {
Thread thread = threads.peek(); Thread thread = threads.peek();
try { try {
Monitor.log(DAO.class, Level.INFO, "Waiting for thread " Monitor.log(DAO.class, Level.INFO, "Waiting for thread "
+ thread.getName() + " to finish"); + thread.getName() + " to finish");
thread.join(); thread.join();
Monitor.log(DAO.class, Level.INFO, "Thread " + thread.getName() Monitor.log(DAO.class, Level.INFO,
+ " finished"); "Thread " + thread.getName() + " finished");
} catch (InterruptedException e) { } catch (InterruptedException e) {
Monitor.log(DAO.class, Level.WARN, Monitor.log(DAO.class, Level.WARN,
"got interrupted while waiting for commit threads"); "got interrupted while waiting for commit threads");
...@@ -368,14 +390,6 @@ public class DAO { ...@@ -368,14 +390,6 @@ public class DAO {
} }
threads.poll(); 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 @@ ...@@ -21,6 +21,10 @@
package de.tud.kom.p2psim.impl.util.db.dao.metric; package de.tud.kom.p2psim.impl.util.db.dao.metric;
import java.util.Date; 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.simengine.Simulator;
import de.tud.kom.p2psim.impl.util.db.dao.DAO; import de.tud.kom.p2psim.impl.util.db.dao.DAO;
...@@ -61,13 +65,20 @@ public class ExperimentDAO extends DAO { ...@@ -61,13 +65,20 @@ public class ExperimentDAO extends DAO {
long seed = Simulator.getSeed(); long seed = Simulator.getSeed();
String system = Simulator.getInstance().getConfigurator() String system = Simulator.getInstance().getConfigurator()
.getResolvedConfiguration(); .getResolvedConfiguration();
// FIXME: The following has to be uncommented again. Map<String, String> vars = new LinkedHashMap<>(Simulator.getInstance().getConfigurator()
// String workload = Simulator.getInstance().getConfigurator() .getVariables());
// .getVariables().toString(); // 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() String experimentDescription = Simulator.getMonitor()
.getExperimentDescription(); .getExperimentDescription();
experiment = new Experiment(seed, actTime, experimentDescription, experiment = new Experiment(seed, actTime, experimentDescription,
system, ""); system, workload);
persistImmediately(experiment); 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